この記事は「ウィルゲート 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.ymlthat 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を活用してメモリを節約しよう」です。 お楽しみに!