Skip to content

Next.js 应用部署

Vercel 部署

Vercel 是 Next.js 的开发商,也是 Next.js 应用的推荐部署平台。Vercel 提供了一定额度的免费部署服务。

平台独立的争议性

Vercel 声称 Next.js 是平台独立的,可部署在各种云平台和独立服务器。但似乎只有 Vercel 对 Next.js 有完美的支持,其他云平台就没那么好了,例如 Netlify、AWS 等目前只有实验性支持。关于这方面的批评可参考 Remix 开发者 Kent C. Dodds 对 Next.js 的评价文章 Why I Won't Use Next.js 这篇文章。

Vercel 部署。

TIP

推荐阅读 Vercel 平台的官方文档 Next.js on Vercel 来了解更多。同时,Vercel 官方还提供了一些 社区模板,用于快速部署应用。

Docker 部署

对于大多数不使用云服务平台的公司来说,Docker 部署是最常见的方式,这可以和公司内部的 Kubernetes 集群、DevOps 等系统结合使用。

构建产物

和 Nuxt 构建器不同的是,Next.js 应用的构建产物中不包含 node_modules/,因此需要在构建操作后复制相关的依赖,然后再运行应用。我们不希望将开发依赖也一起复制过来,我们可使用下面的 pnpm 命令来安装运行时依赖:

bash
pnpm i --prod --ignore-scripts

使用 Docker 多阶段构建可以显著减小镜像大小,提高构建速度。这里使用两个阶段来构建 Next.js 应用的 Docker 镜像。

在第一阶段我们使用 Node.js 完整的 Bookworm 镜像来打包 Next.js 应用,此处可根据项目进行调整。在第二阶段我们将第一阶段的产物复制过来,然后确保 next 命令行工具在路径,并在启动时运行 Next.js 应用。

NOTE

node:bookwormnode:bookworm-slim 镜像的大小差异很大,前者包含了各种常见的构建工具,我们在打包应用时常常需要构建原生依赖库(用 C/C++/Rust 等编写的库),而后者则只包含了 Node.js 运行时。和纯 SPA 的前端应用不同,Next.js 的构建结果不是跨平台的,而且其中的原生依赖通常不是跨 Linux 二进制兼容的,因此我们选择同一个 Linux 发行版本的镜像来构建和运行应用。

dockerfile
ARG NODE_VERSION=22.2.0
ARG NPM_REGISTRY=https://registry.npmjs.org

# Builder image
FROM node:${NODE_VERSION}-bookworm as builder
ARG NPM_REGISTRY
WORKDIR /app

COPY . ./

ENV NODE_OPTIONS=--max-old-space-size=4096
RUN npm -v && \
    npm config set registry ${NPM_REGISTRY} && \
    npm i -g pnpm && \
    pnpm -v && \
    pnpm config set registry ${NPM_REGISTRY} && \
    mv .env.production .env && \
    pnpm i
RUN pnpm build
RUN mkdir -p dist/ && \
    rm -rf .next/cache && \
    mv .next/ dist/ && \
    mv package.json dist/ && \
    mv pnpm-lock.yaml dist/ && \
    mv .env dist/ && \
    mv tsconfig.json dist/ && \
    cd dist/ && \
    pnpm i --prod --ignore-scripts && \
    rm -rf pnpm-lock.yaml

# Production image
FROM node:${NODE_VERSION}-bookworm-slim
WORKDIR /app

COPY --from=builder /app/dist /app

ENV PATH=/app/node_modules/.bin:$PATH
EXPOSE 3000
CMD ["next", "start"]

将上述 Dockerfile 文件放在 Next.js 项目根目录,然后执行构建命令:

bash
docker build -t hello-nextjs .

构建成功后将生成名为 hello-nextjs 的镜像,我们可以使用下面的命令来运行:

bash
docker run -p 3000:3000 hello-nextjs

添加依赖

prisma
generator client {
  provider      = "prisma-client-js"
  binaryTargets = ["native", "debian-openssl-1.1.x"]
}

Node.js 部署

静态部署