Docker マルチステージビルドでNode.jsでコンパイルしたjsファイルをnginxで配信する
Dockerのマルチステージビルドという機能を使い、nodeのコンテナでコンパイルしたJavascriptのファイルをnginxのコンテナで配信する方法を紹介します。
フォルダ構成は以下のようになっています。
- web
- Dockerfile
- frontend
- src(フロントエンドのソース)
- package.json
- docker-compose.yml
docker-compose.ymlは以下のようになっています。
Dockerfileでは最終的にnginxのコンテナを起動します。
Dockerfileでfrontendフォルダなどの親ディレクトリを参照する必要があるため、Docker ComposeでDockerfileをビルドする際に親ディレクトリのファイルをコピーするで紹介した方法で、contextを指定しています。
docker-compose.ymlversion: '3'
services:
web:
build:
context: .
dockerfile: ./web/DockerfileDockerfileを以下のようにします。
DockerfileFROM node as build-stage
# frontendのソースをビルド
ADD ./frontend/package*.json ./
RUN npm install
COPY ./frontend .
RUN npm run build
FROM nginx as production-stage
RUN mkdir /var/www
RUN mkdir /var/www/front
COPY --from=build-stage /code/build /var/www/frontFROMが2つあるのがポイントです。
最初のFROMではnodeのコンテナを使用して、frontendフォルダのソースをコンパイル(トランスパイル)してJavascriptファイルを作成します。
この工程をbuild-stageという名前でFROMの部分で定義しています。
次に、最終的に実行するnginxのコンテナを使用します。
production-stageという名前でFROMの部分で定義しています。
14行目のコピーコマンドの、--from=build-stageで先程のbuild-stageのコンテナを参照できます。
build-stageで作成したJavascriptのあるフォルダのファイルを現在(production-stage)のコンテナにコピーします。
本番環境でもコンパイル用のコンテナ(node)を作成して、コンパイルしたJavascriptファイルをvolumeでnginxコンテナと共有するような構成でしたが、マルチステージビルドを使用することにより、本番環境でコンパイル用のコンテナ(node)を用意する必要がなくなりました。