動機
リモート環境をAmazon ECSにし、ローカル環境もDockerで構築していましたが、このときDockerfileの運用に悩みました。ローカル環境とリモート環境では、コンテナ化したいものが違ったからです。
- ローカル環境
- 主にランタイムをコンテナ化したい
- 手元のIDEでコーディングしたいので、コードはミュータブルで良い
- リモート環境
- アプリケーションも含めてコンテナ化したい
- コードは書き換えられなくて良い
上記のような欲求のため、Dockerfileを分けていましたが、管理が複雑になってきたため一つにまとめたいと思いました。
TL;DR
- マルチステージビルドでリモート環境とローカル環境を分ける
- FROM句を複数書くやり方
- 共通な部分とローカル環境・リモート環境で分けるものを別々で記載すると良い
マルチステージビルドを使う
概要
上記の課題を解決するため、Dockerのマルチステージビルドを使いました。
マルチステージビルドは、1つのDockerfileにFROM句を複数記載するやり方です。
これを使って、PHPのDockerfileを記載してみます。
# ローカル環境とリモート環境で共通なもの
FROM php:8.0-fpm AS base
RUN apt-get update && apt-get install -y zlib1g-dev git zip && \
docker-php-ext-install opcache && \
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \
php composer-setup.php && \
php -r "unlink('composer-setup.php');" && \
mv composer.phar /usr/local/bin/composer
# ローカル環境用。xdebugとかもここ。
FROM base AS local
RUN pecl install xdebug && \
docker-php-ext-enable xdebug
# リモート環境用。コードもコピーしちゃう。
FROM base AS remote
WORKDIR /var/www/html/
COPY . .
RUN composer install -n --prefer-dist
各FROM句の説明
base
baseはローカル環境とリモート環境で変わらない処理を記載します。
MySQLやRedisのライブラリ、Composer等がここになります。
local
localはローカル環境用でbaseの処理以外でローカル環境で必要なものを記載します。
Xdebugはローカル環境で使いたいだけなので、ここに記載します。
remote
remoteはリモート環境用で、アプリケーションのコピーや依存関係の解決などを行います。
他にリモート環境で必要なものがあれば、ここに記載します。
周辺ツールとの連携
マルチステージビルドを使うことで、Dockerfileを1つにまとめることができましたが、周辺ツールでlocalとremoteを使い分ける必要があります。
ここでは自分が利用しているDocker-ComposeとAWS Copilotの例を記載します。
Docker-Compose
yamlファイルのbuildの欄にtargetを追加します。
ローカル環境で使いたいだけなので、ここではlocalを設定します。
これで、base + localのビルドを行ってくれます。
services:
app:
build:
context: .
dockerfile: Dockerfile
target: local
AWS Copilot
AWS Copilotのmanifestも、同様にtargetを指定することができます。
ECSはリモート環境で、アプリケーションもコンテナ化したいので、remoteを指定します。
これで、base + remoteのビルドを行ってくれます。
build:
dockerfile: Dockerfile
context: .
target: remote
まとめ
マルチステージビルドを使うことで、ローカル環境とリモート環境のDockerfileを共通化することができ、悩みを解決することができました。
以上、最後まで読んでいただきありがとうございました。