動機
開発環境・本番環境でdockerを使ってみよう!と思って試したところ何点か詰まったので備忘録としてNext.jsをdockerで環境構築する方法を記しておきます。
開発環境
公式のテンプレートをもとに作っていきます。
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のnode上で作っていきます
3行目: 作業ディレクトリを指定します。
5行目: package.json, yarn.lockをコンテナ内にコピーします。npmを使う場合はyarn.lockの部分をpackage-lock.jsonとかに変えてください。
6行目: 必要なパッケージをインストール。npmを使う場合はnpm ci
とかに書き換えてください。公式のテンプレートのままif文で条件分岐してもOK
10 ~ 13行目: 起動に必要なコードをコンテナ内にコピー
15行目: yarn dev
でサーバーを起動。npmを使われる場合は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ディレクトリ内のファイルが配信されない問題を修正