この記事は「ウィルゲート Advent Calendar 2023」の 1 日目の記事です。
こんにちは、ウィルゲート開発室の岡田/おかしょい(@okashoi)です。
ウィルゲートでは開発環境の構築に Docker と Docker Compose を使っています。 ホストマシンの影響を(あまり)受けることなく共通の開発環境を提供することができるのが便利ですね。
本記事では、そんな Docker と Docker Compose を使った開発環境を構築してチームに提供する際に気をつけているちょっとしたポイントを挙げていきます。
- docker-compose.yaml ではなく compose.yaml
- .env を使って公開ポート番号等をカスタマイズできるようにする
- プロジェクト名を指定する
- depends_on, healthcheck を使ってサービスの起動タイミングを制御する
- 目的に応じて設定ファイルを分割する
- .dockerignore を指定して余計なファイルを Docker イメージに含めない
- おわりに
docker-compose.yaml
ではなく compose.yaml
少し前までは設定ファイル名のデフォルトは docker-compose.yaml
でしたが、2023 年 12 月現在では compose.yaml
を使うことが「好ましい(preferred)」とされています。
後方互換を保つために docker-compose.yaml
でもまだ動きますが、見かけたら compose.yaml
にリネームしてあげるとよいでしょう。
The default path for a Compose file is
compose.yaml
(preferred) orcompose.yml
that is placed in the working directory.
.env
を使って公開ポート番号等をカスタマイズできるようにする
例えば compose.yaml
の ports
要素によって公開ポートを指定できますが、これをハードコーディングしてしまうと人(環境)によってはポート番号が衝突してしまう可能性があります。
compose.yaml
では変数を展開することができ、同階層に .env
ファイルを設置することで変数の値を指定できます。
この仕組みを使えば、Git 管理された同一の compose.yaml
ファイルを使いつつ、起動する人自身の手によって環境をカスタマイズできます。
.env
HTTP_PORT=8080
compose.yaml
services: web-server: image: nginx:1.25.3 ports: - 127.0.0.1:${HTTP_PORT}:80
このあたりは The Twelve-Factor App の「設定を環境変数に格納する」の考え方にも通じますね。
プロジェクト名を指定する
1 つの compose.yaml
ファイルは「プロジェクト」という概念に結びつきます。
プロジェクト名は Docker コンテナ、Docker イメージ等のデフォルト名の一部に付けられます(コンテナ名なら<プロジェクト名>_<サービス名>_<連番>
)。
そして、デフォルトでは compose.yaml
ファイルが置かれているディレクトリ名が設定されます。
その結果、ディレクトリ構成によっては docker
とか develop
みたいな情報の少ない名前になってしまうなんてケースが発生しかねません。
プロジェクト名は compose.yaml
内の name
要素や COMPOSE_PROJECT_NAME
変数によって指定できるので、プロダクト名などのわかりやすい名前をつけてあげましょう。
depends_on
, healthcheck
を使ってサービスの起動タイミングを制御する
「Web アプリケーションのコンテナを起動する前に、データベースのコンテナが起動している」のように、コンテナの起動順を指定したケースもあるでしょう。
depends_on
要素を指定すると「そのサービス(ここではコンテナ、と読み替えて OK)より先に depends_on
に指定したサービスを立ち上げる」という形で起動順序(依存関係)を定義できます。
services: webapp: image: php:8.2.12-apache depends_on: - database database: image: mysql/mysql-server:8.2.0
ただし、単にサービス名を指定しただけでは「コンテナが起動しているか」しか見られていないため、「目的のサービスが利用可能な状態か」までは判断してくれません。
それを解決するには healthcheck
要素の指定と、depends_on
の condition
指定を組み合わせて使います。
services: webapp: image: php:8.2.12-apache depends_on: database: condition: service_healthy database: image: mysql/mysql-server:8.2.0 healthcheck: test: mysqladmin ping -h 127.0.0.1 -u${MYSQL_USER} -p${MYSQL_PASSWORD} interval: 1s timeout: 4s retries: 20 start_period: 10s
目的に応じて設定ファイルを分割する
先述のとおりデフォルトでは設定ファイルとして compose.yaml
を読み取りますが、-f
オプションを指定してファイル名を明示できます。
複数指定もできます。
docker compose -f <設定ファイル名1> -f <設定ファイル名2> ...
「開発用の環境」「自動テストの実行環境」といったように目的ごとに環境の設定や、必要なサービスが異なることもあるでしょう。
そんなときには「compose-common.yaml
に共通の設定を書き、開発環境用の設定を compose-dev.yaml
に、テスト用実行の設定を compose-test.yaml
に書きわける」というように運用できます。
.dockerignore
を指定して余計なファイルを Docker イメージに含めない
Docker イメージビルドの際、Dockerfile
の COPY
命令によってホストマシン上のファイルを Docker イメージに含めることがあります。
この際 .dockerignore
というファイルによって、イメージビルドに「含めない」ファイルやディレクトリを指定できます。
ファイル形式はおなじみ .gitignore
と同じです。
例えば node_modules
のような依存パッケージが格納されるディレクトリについて、「ホストマシン上のものを渡すのではなく、イメージビルドの過程でインストールさせる」といったことを実現できます。
おわりに
いずれも細かい部分ではありますが、知っていると開発環境をちょっと便利にできる Tips をご紹介しました。
設定内容やオプションはまだまだたくさんあるので、改めて公式ドキュメントを眺めてみるのもいいかもしれませんね!
そして「ウィルゲート Advent Calendar 2023」、明日は佐々木さんによる「PHP Generatorを活用してメモリを節約しよう」です。 お楽しみに!