シナプス技術者ブログ

シナプスの技術者公式ブログ。インターネットで、鹿児島の毎日を笑顔にします。

Webアプリの本番環境と開発環境を同一のDocker Composeで管理する

技術部システム開発課の蔵坪と申します。

弊社では、今まで、Nuxt等のWebアプリを開発する場合、本番環境と開発環境は、それぞれ別の環境を用意しておりましたが、今回、Docker Composeを使って本番と開発環境を一つの環境で管理できるようにしてみました。

その構築の作業の中でつまずいた、Docker Composeの環境毎の切り替えとNGINXの設定について、紹介したいと思います。

Docker Composeの環境毎の切り替え

以下の公式ドキュメントから、Docker Composeでは、何も構成ファイルのオプションを付けずに起動した場合、docker-compose.ymlとdocker-compose.override.ymlの2つのファイルが読み込まれ、-fオプションを付けた場合は、-fオプションで指定された構成ファイルだけが読み込まれることがわかります。

docs.docker.com

このルールから以下のファイル構成にしました。

ファイル名 用途
docker-compose.yml 本番、開発環境の共通設定を記載
docker-compose.production.yml 本番環境用の構成記載
docker-compose.override.yml 開発環境用の構成を記載

上記の構成にした場合、各環境での起動方法は、以下になります。

環境 コマンド 読み込まれる構成ファイル
開発環境 docker compose up -d docker-compose.yml
docker-compose.override.yml
本番環境 docker compose /
-f docker-compose.yml /
-f docker-compose.production.yml up -d
docker-compose.yml
docker-compose.production.yml

起動コマンドを手打ちする機会が多い開発環境では、オプションもup -dと打つだけなので、簡単です。本番環境の起動方法が少々面倒ですが、本番環境は、systemdで管理するようにしたため、通常の運用の中で、docker composeの起動コマンドを手打ちする機会はありません。

docker-compose.override.ymlでは、開発環境のみで必要な構成を記載します。Nuxtアプリでしたので、Nuxtのホットリロード用のポート設定等を記載しました。

version: "3.7"
services:
  nuxt:
    ports:
      - "24678:24678"

docker-compose.produection.ymlでは、本番環境のみで必要な構成を記載します。nginxやmysqlのログのvolume設定等を記載しました。

version: "3.7"
services:
  nginx:
    volumes:
      - ./nginx/log:/var/log/nginx
  mysql:
    volumes:
      - ./mysql/log:/var/log/mysql

設定が正しくできているかの確認は、docker compose configコマンドで確認できます。

docker compose config
docker compose -f docker-compose.yml -f docker-compose.production.yml config

NGINXの設定

本番環境と、開発環境を両対応するにあたって、ブラウザでアクセスするURLが環境毎に異なるため、NGINX側の設定を変更する必要がありました。

環境 URL
本番環境 https://www.xxxxxxx.xx/
開発環境 https://localhost/

docker-composeの.envファイルに、サーバ名を記載して、nginxの設定ファイルを環境変数で記載すればいいと考えておりましたが、nginxのサーバ名の指定箇所で環境変数が利用できませんでした。

server {
    listen *:443 ssl;

    server_name $SERVER_NAME;

nginxの設定ファイルに、上記のように記載しても、環境変数から、設定を読み込んでくれませんでした。

nginxのDOCKER OFFICIAL IMAGEでは、/etc/nginx/templatesに、設定ファイルを保存しておくと、nginx起動時にnginxのconf.dフォルダに展開される機能が組み込まれています。

hub.docker.com

この時に、templatesフォルダに保存されているファイルが、envsubstを使って、conf.dフォルダに展開されるため、templatesフォルダでは、環境変数が利用できます。

フォルダ 説明
/etc/nginx/templates 環境変数が利用できる
/etc/nginx/conf.d 環境変数は利用できない
環境変数が置換されてtemplatesフォルダのファイルが展開される

この仕組みを利用して、.envに記載されている環境変数で、本番と開発環境を切り替えることができます。

今回は、サーバ名やSSLの設定ファイルのパスを環境変数で置き換えるようにしました。

さいごに

本番環境と開発環境を同一のDocker Composeで管理するにあたって、色々分からないことがあって調査等に時間がかかりましたが、次回以降は、同様のサービス開始時等に環境を用意する手間を削減できそうです。