Next.jsアプリケーションをECSで動かしたいと思い、Dockerfileを作ってみたのでメモ。
設定の用意
Dockerfileと.dockerignoreを用意し、ビルドコマンド用にMakefileも用意した。
# syntax = docker/dockerfile:experimental FROM node:12-stretch-slim AS nextjs-on-ecs-server-builder USER node WORKDIR /app COPY --chown=node:node package.json yarn.lock ./ RUN mkdir -p /home/node/.cache RUN --mount=type=cache,target=/home/node/.cache,id=yarn-cache,sharing=private,uid=1000 yarn install --pure-lockfile COPY --chown=node:node . ./ RUN npm run build FROM node:12-stretch-slim AS nextjs-on-ecs-server WORKDIR /app COPY --from=nextjs-on-ecs-server-builder /app/package.json /app/yarn.lock ./ RUN --mount=type=cache,target=/home/node/.cache,id=yarn-cache,sharing=private,uid=1000 yarn install --pure-lockfile --production COPY --from=nextjs-on-ecs-server-builder /app/.next ./.next CMD ["npm", "run", "start"]
- 本番用に無駄なデータが入らないように、next buildを実行するビルド用イメージ(nextjs-on-ecs-server-builder)と、実際にに実行するためのイメージ(nextjs-on-ecs-server)を、マルチステージビルドで分離した
# syntax = docker/dockerfile:experimental
を書いておき、yarn installでは高速化のため--mount=type=cache
付きで実行して、イメージ更新時にキャッシュが使われるようにする- https://nextjs.org/docs/deployment を参考にし、nextjs-on-ecs-serverには
- package.json、yarn.lock、.nextだけ入れる
- yarn.lockは実行するだけならいらないかも?
- yarn installは--production付きでdependenciesだけを入れる
- package.json、yarn.lock、.nextだけ入れる
.git node_modules .next
export DOCKER_BUILDKIT=1 .PHONY: build build: docker build --file Dockerfile.server --target nextjs-on-ecs-server --tag nextjs-on-ecs-server:latest --progress plain .
ビルドして実行する
ビルドする
$ make build
これでnextjs-on-ecs-serverというイメージが出来たので、実行する。
$ docker run --rm -ti -p 3000:3000 nextjs-on-ecs-server > with-typescript@1.0.0 start /app > next start > Ready on http://localhost:3000
http://localhost:3000/ にアクセスすると、以下のように表示される。
まとめ
これでNext.jsアプリケーションをコンテナで動かすことができた。あとはECSなり何でも良いのでデプロイしたら良い。