如何使用Docker构建Next.js的生产环境和开发环境

动机

我在开发环境和生产环境中尝试使用Docker时遇到了一些困难,所以我将记录下使用Docker构建Next.js环境的方法作为备忘录。

开发环境

根据公式模板进行制作。

FROM node:18-alpine

WORKDIR /app

COPY package.json yarn.lock* ./
RUN if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
    else echo "Warning: Lockfile not found. It is recommended to commit lockfiles to version control." && yarn install; \
    fi

COPY src ./src
COPY public ./public
COPY next.config.js .
COPY tsconfig.json .

CMD ["yarn", "dev"]

1行目:我們在v18的節點上進行建立。
3行目:指定工作目錄。
5行目:將package.json和yarn.lock複製到容器內。如果使用npm,將yarn.lock改為package-lock.json或其他。
6行目:安裝所需的套件。如果使用npm,將npm ci替換為npm ci。也可以在官方模板中使用條件判斷。
10至13行目:將啟動所需的代碼複製到容器內。
15行目:使用yarn dev啟動伺服器。如果使用npm,將npm run dev替換為npm run dev。

接下来我们来创建docker-compose。
请将以下内容写入docker-compose.dev.yml。

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.dev
    image: next-app
    container_name: next-app
    ports:
      - '3001:3001'
    env_file:
      - .env
    volumes:
      - ./src:/app/src
      - ./public:/app/public
      - node_modules:/app/node_modules
    restart: always
    tty: true
    stdin_open: true

volumes:
  node_modules:

通过以下命令可以启动容器。

docker compose -f docker-compose.dev.yml build
docker compose -f docker-compose.dev.yml up -d

正式环境

由于使用了Next公式的模板无法正常工作,我们将根据由docker init创建的Dockerfile和docker-compose进行构建。由于下面的文件是针对yarn的,所以如果要使用npm,请相应地将yarn run build或yarn start的部分改写为适用于npm的形式。

# syntax=docker/dockerfile:1

# Comments are provided throughout this file to help you get started.
# If you need more help, visit the Dockerfile reference guide at
# https://docs.docker.com/engine/reference/builder/

ARG NODE_VERSION=18.16.0

################################################################################
# Use node image for base image for all stages.
FROM node:${NODE_VERSION}-alpine as base

# Set working directory for all build stages.
WORKDIR /usr/src/app


################################################################################
# Create a stage for installing production dependecies.
FROM base as deps

# Download dependencies as a separate step to take advantage of Docker's caching.
# Leverage a cache mount to /root/.yarn to speed up subsequent builds.
# Leverage bind mounts to package.json and yarn.lock to avoid having to copy them
# into this layer.
RUN --mount=type=bind,source=package.json,target=package.json \
    --mount=type=bind,source=yarn.lock,target=yarn.lock \
    --mount=type=cache,target=/root/.yarn \
    yarn install --production --frozen-lockfile

################################################################################
# Create a stage for building the application.
FROM deps as build

# Copy the rest of the source files into the image.
COPY . .
# Run the build script.
RUN yarn run build

################################################################################
# Create a new stage to run the application with minimal runtime dependencies
# where the necessary files are copied from the build stage.
FROM base as final

# Use production node environment by default.
ENV NODE_ENV production

# Run the application as a non-root user.
USER node

# Copy package.json so that package manager commands can be used.
COPY package.json .

# Copy the production dependencies from the deps stage and also
# the built application from the build stage into the image.
COPY --from=deps /usr/src/app/node_modules ./node_modules
COPY --from=build /usr/src/app/.next ./.next
COPY ./public ./public

# Run the application.
CMD yarn start
version: '3'

services:
  next-app:
    container_name: next-app-prod
    image: next-app-prod
    build:
      context: .
      dockerfile: Dockerfile.prod
      args:
        ENV_VARIABLE: ${ENV_VARIABLE}
        NEXT_PUBLIC_ENV_VARIABLE: ${NEXT_PUBLIC_ENV_VARIABLE}
    restart: always
    ports:
      - 4400:4400

在中国,您可以使用以下命令启动容器。当您更新应用程序时,也可以使用类似的命令进行更新。
参考链接:https://matsuand.github.io/docs.docker.jp.onthefly/compose/production/

docker compose -f docker-compose.prod.yml build
docker compose -f docker-compose.prod.yml up -d

结束

本次记录了使用Docker构建生产环境和开发环境的方法。下一次我们将使后端也能够在Docker中创建,并实现后端与客户端之间的通信。

以下是可供參考的資料。

Next.js官方代码库
https://github.com/vercel/next.js/tree/canary/examples/with-docker-compose/next-app

Docker 手册
https://matsuand.github.io/docs.docker.jp.onthefly/compose/production/

追加记录

2023年9月27日,修复了在正式环境中无法传送public目录内文件的问题。

广告
将在 10 秒后关闭
bannerAds