LoginSignup
9
6

More than 3 years have passed since last update.

【Next.js】Next プロジェクトを Dockernize する

Posted at

k8s 環境に Next.js プロジェクトをデプロイすることになったので、いろいろ書いてみた。
今回は npm ではなく、yarn を使用している。

環境

  • ubuntu 20.04.1
  • Docker 19.03.13
  • Next.js 9.5.4

また、npm スクリプトはこんな感じ。

{
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  }
}

Docker 上で開発を行う

Docker 内の Node で開発を行う場合。ローカルの Node のバージョンを気にせず開発は行えるが、ローカルのエディタでは型定義などを読み込めず面倒ではある。

  • Dockerfile
    開発用なので、ベースイメージは通常のものにした。
FROM node:12.18.4

WORKDIR /app
# npmパッケージのインストールに必要なファイルをコピー
COPY package.json yarn.lock ./
# npmを使用している場合は、以下のようにする
# COPY package*.json ./
RUN yarn install
EXPOSE 3000
CMD ["yarn", "dev"]
  • Docker build
docker build --rm -t next_dev:latest -f path/to/Dockerfile
  • Docker run
    プロジェクトのフォルダで実行する。(-v の引数にプロジェクトフォルダを絶対パスで指定すれば OK)
docker run -p 3000:3000 -v $PWD:/app -it next_dev:latest

Production 向けにビルドする

ここからは、本番向けにイメージを作成する。

とりあえず作ってみる

いつも通り作ってみる。本番向けなので alpine イメージを使う。
ビルドコンテキスト(Docker build 時に Docker デーモンへ送信されるファイルの場所)はプロジェクトフォルダ。

FROM node:12.18.4-alpine

WORKDIR /app
# ローカルのソースを全てコピー
COPY . /app
# npmパッケージのインストール、production向けにビルド
RUN yarn install && NODE_ENV=production yarn build
EXPOSE 3000

CMD ["yarn", "start"]
  • ビルド&実行

ビルドにはプロジェクトフォルダで以下のコマンドを実行。

$ docker build --rm -t next_prod:latest -f path/to/Dockerfile

デーモンとして動かすには以下のコマンドを実行。

$ docker run -d -p 3000:3000 next_prod:latest

これでサーバー自体は動くが、このままでは Docker イメージのサイズが 900MB あるので、もう少しスリムにしたいところ。
(もちろん、イメージのサイズは Next.js プロジェクトの中身による)

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
next_prod         latest              d211c6246173        6 minutes ago       899MB

multi stage build する

multi stage build により、Docker イメージの容量を削減する。

  • Dockerfile
FROM node:12.18.4-alpine AS base

# パッケージのインストールを行う
WORKDIR /base
COPY . .
RUN yarn install

# Production向けビルドを行う
FROM base AS build
WORKDIR /build
COPY --from=base /base ./
RUN NODE_ENV=production yarn build

# ビルド成果物をコピーし、サーバーを起動
FROM node:12.18.4-alpine AS production
ENV NODE_ENV=production
WORKDIR /app
# ビルド成果物のみをコピーしてやる
COPY --from=build /build/package.json /build/yarn.lock ./
COPY --from=build /build/.next ./.next
COPY --from=build /build/public ./public
# node_modules以下がこのイメージにないので、next.jsのサーバーを動かすために必要
RUN yarn add next

EXPOSE 3000
CMD ["yarn", "start"]
  • ビルド&実行
$ docker build --rm -t next_prod:msb -f path/to/Dockerfile
$ docker run -d -p 3000:3000 next_prod:mdb

これにより、イメージはかなりスリムになった。各イメージの容量はこんな感じ。

$ docker images
REPOSITORY          TAG           SIZE
next_prod           msb           574MB    # production multi stage build
next_prod           latest        899MB    # production build
next_dev            latest        1.44GB   # dev

おわりに

DockernizeなのかDockerizeなのかよくわからない。

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6