zukucode
主にWEB関連の情報を技術メモとして発信しています。

Docker マルチステージビルドでNode.jsでコンパイルしたjsファイルをnginxで配信する

Dockerのマルチステージビルドという機能を使い、nodeのコンテナでコンパイルしたJavascriptのファイルをnginxのコンテナで配信する方法を紹介します。

フォルダ構成は以下のようになっています。

  • web
    • Dockerfile
  • frontend
    • src(フロントエンドのソース)
    • package.json
  • docker-compose.yml

docker-compose.ymlは以下のようになっています。

Dockerfileでは最終的にnginxのコンテナを起動します。

Dockerfilefrontendフォルダなどの親ディレクトリを参照する必要があるため、Docker ComposeでDockerfileをビルドする際に親ディレクトリのファイルをコピーするで紹介した方法で、contextを指定しています。

docker-compose.yml
version: '3'
services:
  web:
    build:
      context: .
      dockerfile: ./web/Dockerfile

Dockerfileを以下のようにします。

Dockerfile
FROM 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/front

FROMが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ファイルをvolumenginxコンテナと共有するような構成でしたが、マルチステージビルドを使用することにより、本番環境でコンパイル用のコンテナ(node)を用意する必要がなくなりました。


関連記事