はじめに
今回は、多くの開発者が直面するDockerファイル管理の課題に焦点を当て、一つのDockerfileで開発用と本番用の両環境に対応するスマートな方法を解説します。Docker Composeと環境変数を活用することで、Dockerfileを共通化し、開発から本番までのプロセスをスムーズにします。
目次
はじめに
開発用と本番用でDockerfileを分けることの課題
一つのDockerfileで両環境に対応するメリット
本記事で解説するDocker Composeと環境変数の活用
Dockerfileの共通化
マルチステージビルドの再確認と応用
開発用と本番用で異なる依存関係を管理する
アプリケーションのビルドと実行レイヤーを分離する
環境変数による挙動の切り替え
ARGとENVの使い方
開発用パッケージのインストールを制御する
各種設定ファイル(Nginx, PHP-FPMなど)の動的な切り替え
Docker Composeの活用
docker-compose.ymlとdocker-compose.override.ymlの役割
開発環境専用のサービス・ボリューム・ポート定義
docker-compose.prod.ymlを使った本番環境のオーバーライド
実践的なDockerfileとDocker Composeの例
フロントエンドのホットリロードと本番ビルドの共存
まとめと運用方法
チームでの運用ルールと注意点
安心安全のホワイト高還元SESに転職を考えている方へ
開発用と本番用でDockerfileを分けることの課題
多くのプロジェクトでは、開発環境と本番環境の要件が異なるため、それぞれ専用のDockerfileを用意しがちです。
- 開発用Dockerfile: デバッグツール(Xdebugなど)、開発用パッケージ(phpunitなど)、ホットリロードのための設定を含みます。
- 本番用Dockerfile: 軽量化のために不要なツールやパッケージを徹底的に排除し、セキュリティを考慮します。
このアプローチは、以下の課題を引き起こします。
- 管理の複雑化: 2つのDockerfileを常に同期させる必要があり、メンテナンスの負担が増加します。
- 一貫性の欠如: 開発環境と本番環境で微妙に設定が異なり、「開発環境では動いたのに本番では動かない」という問題が発生するリスクが高まります。
- CI/CDの複雑化: ビルドプロセスが複雑になり、CI/CDパイプラインの構築や保守が難しくなります。
一つのDockerfileで両環境に対応するメリット
逆に、一つのDockerfileで開発用・本番用を管理することでこれらの課題を解決し、以下のようなメリットが得られます。
一貫性: 開発環境と本番環境が同じビルドプロセスから生成されるため、環境差異に起因するバグを減らせます。
管理の容易さ: 修正やアップデートは一つのファイルに集中でき、メンテナンスコストを削減できます。
CI/CDの簡素化: ビルドプロセスが統一されるため、CI/CDパイプラインの構築がシンプルになります。
本記事で解説するDocker Composeと環境変数の活用
本記事では、一つのDockerfileをベースに、Docker Composeのオーバーライド機能と環境変数を使って、それぞれの環境に合わせた設定を適用する実践的な手法を解説します。
Dockerfileの共通化
マルチステージビルドの再確認と応用
マルチステージビルドは、一つのDockerfile内で複数のFROM命令を使い、中間的なイメージ(ステージ)を作成する手法です。最終的なイメージは、最後のステージから作成され、前のステージで生成された成果物だけをコピーします。この仕組みは、開発用と本番用を共通化する上で不可欠です。
開発用と本番用で異なる依存関係を管理する
composer installやnpm installコマンドには、開発用パッケージを含めるか否かを制御するオプションがあります。
- 開発用: composer install、npm install
- 本番用: composer install --no-dev、npm install --production
一つのDockerfileでこれらを使い分けるために、ARG命令を使ってビルド時に環境を指定します。
Dockerfile
# Dockerfile
ARG BUILD_ENV=production
# --- Stage 1: ビルドステージ ---
FROM composer:2.5 as build_stage
ARG BUILD_ENV
WORKDIR /app
COPY composer.json composer.lock ./
RUN if [ "${BUILD_ENV}" = "development" ]; then \
composer install; \
else \
composer install --no-dev --optimize-autoloader; \
fi
# --- Stage 2: 実行ステージ ---
FROM php:8.2-fpm-alpine
# ...
Dockerfile
# Dockerfile
ARG BUILD_ENV=production
# --- Stage 1: ビルドステージ ---
FROM composer:2.5 as build_stage
ARG BUILD_ENV
WORKDIR /app
COPY composer.json composer.lock ./
RUN if [ "${BUILD_ENV}" = "development" ]; then \
composer install; \
else \
composer install --no-dev --optimize-autoloader; \
fi
# --- Stage 2: 実行ステージ ---
FROM php:8.2-fpm-alpine
# ...
アプリケーションのビルドと実行レイヤーを分離する
マルチステージビルドの応用として、buildステージで開発用・本番用を問わず依存関係を解決し、実行ステージには必要なファイルだけをコピーすることで、最終的なイメージを常にクリーンで軽量に保つことができます。
環境変数による挙動の切り替え
ARGとENVの使い方
ARG: DockerfileのFROMやRUN命令で使えるビルド時の変数です。docker buildコマンドで値を渡します。ビルド完了後、この変数はイメージに残りません。
ENV: コンテナ実行時に使用できる実行時の変数です。Dockerfile内で設定するか、docker runやdocker-compose.ymlで値を渡します。
ARGをビルド時の条件分岐に使い、ENVを実行時の設定ファイル切り替えに使うのが効果的です。
開発用パッケージのインストールを制御する
前述したように、ARGを使って開発用パッケージのインストールを制御します。
Dockerfile
# Dockerfile
ARG BUILD_ENV=production
# ...
RUN if [ "${BUILD_ENV}" = "development" ]; then \
composer install; \
else \
composer install --no-dev --optimize-autoloader; \
fi
Dockerfile
# Dockerfile
ARG BUILD_ENV=production
# ...
RUN if [ "${BUILD_ENV}" = "development" ]; then \
composer install; \
else \
composer install --no-dev --optimize-autoloader; \
fi
各種設定ファイル(Nginx, PHP-FPMなど)の動的な切り替え
COPY命令は、ARGやENVを使った動的なファイル名指定をサポートしていません。しかし、シェルスクリプトやシンボリックリンクを組み合わせることで、実行時に設定ファイルを切り替えることができます。
Dockerfile
# Dockerfile
# ...
COPY ./docker/php-fpm.d/ /usr/local/etc/php-fpm.d/
# 開発用か本番用かを判断し、php.iniを切り替える
RUN if [ "$APP_ENV" = "development" ]; then \
cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini; \
else \
cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini; \
fi
Dockerfile
# Dockerfile
# ...
COPY ./docker/php-fpm.d/ /usr/local/etc/php-fpm.d/
# 開発用か本番用かを判断し、php.iniを切り替える
RUN if [ "$APP_ENV" = "development" ]; then \
cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini; \
else \
cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini; \
fi
この例では、docker-compose.ymlで渡されるAPP_ENVという環境変数を使って、実行時に適切なphp.iniを適用しています。
Docker Composeの活用
docker-compose.ymlとdocker-compose.override.ymlの役割
- docker-compose.yml: 開発と本番で共通する、基本的なサービス定義を記述します。
- docker-compose.override.yml: 開発環境専用の設定(ボリュームマウント、ポート、コマンドなど)を記述します。docker-compose upを実行すると、docker-compose.ymlとこのファイルが自動的にマージされます。
YAML
# docker-compose.yml (共通設定)
services:
app:
build: .
environment:
- APP_ENV=production # デフォルトを本番に
# ...
YAML
# docker-compose.override.yml (開発用設定)
services:
app:
environment:
- APP_ENV=development # 開発用に上書き
volumes:
- .:/var/www/html
ports:
- "8000:8000"
command: php artisan serve --host=0.0.0.0 --port=8000
YAML
# docker-compose.yml (共通設定)
services:
app:
build: .
environment:
- APP_ENV=production # デフォルトを本番に
# ...
YAML
# docker-compose.override.yml (開発用設定)
services:
app:
environment:
- APP_ENV=development # 開発用に上書き
volumes:
- .:/var/www/html
ports:
- "8000:8000"
command: php artisan serve --host=0.0.0.0 --port=8000
開発環境専用のサービス・ボリューム・ポート定義
docker-compose.override.ymlを使うことで、以下のような開発専用の設定を分離できます。
- ボリューム: ホストのソースコードをコンテナにマウントし、リアルタイムに変更を反映させます。
- ポート: ローカルマシンからサービスにアクセスするためにポートを公開します。
- コマンド: ホットリロードのための開発サーバー起動コマンドなどを定義します。
docker-compose.prod.ymlを使った本番環境のオーバーライド
本番環境にデプロイする際には、docker-compose.override.ymlを含まず、本番専用のdocker-compose.prod.ymlを使います。
YAML
# docker-compose.prod.yml (本番用設定)
services:
app:
environment:
- APP_ENV=production
volumes:
- app-data:/var/www/html
# ...
YAML
# docker-compose.prod.yml (本番用設定)
services:
app:
environment:
- APP_ENV=production
volumes:
- app-data:/var/www/html
# ...
ビルドと起動は以下のコマンドで行います。docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build
実践的なDockerfileとDocker Composeの例
開発用と本番用で異なるphp.iniを適用する方法
docker-compose.override.ymlでvolumesを使って、開発用php.iniをコンテナにマウントすることで、手軽に設定を切り替えられます。
YAML
# docker-compose.override.yml (開発用)
services:
app:
volumes:
- ./docker/php-fpm/dev.ini:/usr/local/etc/php/conf.d/php.ini
YAML
# docker-compose.override.yml (開発用)
services:
app:
volumes:
- ./docker/php-fpm/dev.ini:/usr/local/etc/php/conf.d/php.ini
フロントエンドのホットリロードと本番ビルドの共存
一つのDockerfileでnpm run devとnpm run buildを切り替えるには、docker-compose.override.ymlで開発用のcommandを定義し、本番用では何もしないようにします。
YAML
# docker-compose.override.yml (開発用)
services:
frontend:
command: npm run dev
YAML
# docker-compose.override.yml (開発用)
services:
frontend:
command: npm run dev
開発用デバッグツール(Xdebugなど)の本番環境での無効化
Xdebugを開発環境でのみ有効にするには、docker-compose.override.ymlで環境変数を設定し、Dockerfile内で条件分岐させます。
YAML
# docker-compose.override.yml (開発用)
services:
app:
environment:
- XDEBUG_MODE=develop,debug
Dockerfile
# Dockerfile
# ...
RUN if [ "$XDEBUG_MODE" ]; then \
# Xdebugをインストールする処理... \
fi
YAML
# docker-compose.override.yml (開発用)
services:
app:
environment:
- XDEBUG_MODE=develop,debug
Dockerfile
# Dockerfile
# ...
RUN if [ "$XDEBUG_MODE" ]; then \
# Xdebugをインストールする処理... \
fi
このように、docker-compose.ymlで共通の基盤を定義し、オーバーライドファイルでそれぞれの環境に特化した設定を上書きすることで、管理が非常にシンプルになります。
まとめと運用方法
一つのDockerfileで得られる一貫性と管理の容易さ
一つのDockerfileを使い、docker-composeのオーバーライド機能で環境を切り替えるこの方法は、以下のようなメリットをもたらします。
- 単一の真実: ビルドロジックは常に一つの場所にあり、バージョン管理が容易です。
- 環境差異の削減: 開発環境と本番環境で同じイメージが生成されるため、意図しないバグの発生を防げます。
- チームの効率化: 新しいメンバーがプロジェクトに参加する際も、たった一つのDockerfileを理解すればよく、学習コストが下がります。
チームでの運用ルールと注意点
.gitignoreへの追加: docker-compose.override.ymlは開発者ごとのローカル設定を含む可能性があるため、gitignoreに追加することを検討してください。
- ドキュメント化: README.mdに、開発環境と本番環境の起動方法を明記し、チームメンバー全員が同じ手順で作業できるようにします。
CI/CDパイプラインへの組み込み方
この管理術は、CI/CDと非常に相性が良いです。
YAML
# .github/workflows/ci-cd.yml
# ...
jobs:
build_and_push_image:
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Build production image
run: docker-compose -f docker-compose.yml -f docker-compose.prod.yml build
YAML
# .github/workflows/ci-cd.yml
# ...
jobs:
build_and_push_image:
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Build production image
run: docker-compose -f docker-compose.yml -f docker-compose.prod.yml build
このように、CIではdocker-compose.prod.ymlを使って本番用イメージをビルドし、コンテナレジストリにプッシュします。これにより、CI/CDパイプラインが非常にクリーンでメンテナンスしやすくなります。
今回の記事では、一つのDockerfileを軸に、docker-composeと環境変数を使って開発・本番環境を効率的に管理する方法を解説しました。この手法を取り入れることで、チーム開発の生産性を大きく向上させることができるかと思います。
最後までお読みいただきありがとうございました。
安心安全のホワイト高還元SESに転職を考えている方へ
新しい挑戦に踏み出すことは、人生において重要な一歩です。 転職活動は自分自身を知り、成長する貴重な機会でもあり、夢や成長を追求するためには必要な要素の一つ になるかと思います。 どんな選択をされるにせよ、その決断があなたに取って素晴らしい未来を切り開くことを願っています! グラディートと一緒に誇れるエンジニアを目指しましょう!
■『株式会社グラディート』では受託開発・SES・ブランディングデザイン・事業コンサルティングなどを事業として行う都内のIT企業です。現在、不遇な待遇で困っているエンジニアさんは、ぜひ一度グラディートに相談してみてね!(年収査定・SESへの転職相談も承っております!)
株式会社グラディート採用情報はこちら▼
https://en-gage.net/gradito/
株式会社グラディート公式サイトはこちら▼
https://www.gradito.co.jp/