便利なcompose.yaml の機能
なんの記事?
Docker compose の管理・運用が楽になる細かい話のまとめ
compose の機能
volumes
コンテナとホストOS間でデータを共有する
volume の種類は3通りある
| 特徴 | 保存先 | 利用例 | 削除方法 | |
|---|---|---|---|---|
| ボリュームマウント | Dockerによって管理される永続化ストレージ | /var/lib/docker/volumes |
DBデータ、ログ | docker volume rm <ボリューム名> |
| バインドマウント | ホストOSのファイルシステム上の任意のディレクトリをコンテナにマウント | 任意のホストディレクトリ | 設定ファイル | ホストOSから手動で削除 |
| tmpfs マウント | 一時的なストレージ | メモリ内 | 機密情報、一時ファイル | コンテナ停止時に自動削除 |
services:
backend:
...
volumes:
# ボリュームマウントの定義
# source: Dockerによって管理される名前付きボリュームの名前
# target: コンテナ内のマウントパス
- type: volume
source: my_volume
target: /app/data
read_only: false
# バインドマウントの定義
# source: ホストOS上のパス (Docker Composeファイルからの相対パス)
# target: コンテナ内のマウントパス
- type: bind
source: ./config
target: /app/config
read_only: true
# tmpfs マウントの定義
# target: コンテナ内のマウントパス
# type: 'tmpfs' を明示的に指定
# tmpfs: tmpfs に特化したオプションを指定
- type: tmpfs
target: /app/tmp_cache
tmpfs:
size: 100m # tmpfs の最大サイズを100MBに制限
mode: '0755' # tmpfs のディレクトリ権限を 'drwxr-xr-x' に設定
volumes:
# 'my_volume' の定義
my_volume:
driver: local
ややこしいことにvolumesの定義はlong syntax と short syntaxがあり、バインドマウントのショートシンタックスは挙動が異なる
- long: ホストOS側にバインド元のフォルダが無ければエラー
- short: ホスト側にバインド元のフォルダが無ければ自動生成
- エラー無し&ログにも出ないので気が付きにくく、「なぜかフォルダがマウントされていない」状況に陥りやすい (私見)
services:
backend:
volumes:
# ボリュームマウントの定義
- my_volume:/app/data
# バインドマウントの定義
- ./data:/app/config:ro
volumes:
my_volume:
driver: local
profile
各コンテナにプロファイルを付与し、起動するコンテナを up -d 時に制御する
ローカル環境では設定をこっち!開発環境ではこっち!という場合に有効かも
services:
web:
profiles: ["dev", "debug"]
image: web
backend:
image: backend
profiles: ["dev"]
db:
image: mysql
phpmyadmin:
image: phpmyadmin
profiles: ["debug"]
起動方法は以下のように --profile を指定してあげる
-
up(profile指定なし): profile無しのdbが起動する -
--profile dev up: profile無しのdbとweb, backendが起動する -
--profile debug up: profile無しのdbとweb, phpmyadminが起動する -
--profile debug --profile dev up: 全サービスが起動する
docker compose --profile <プロファイル名> up -d
COMPOSE_PROFILES=<プロファイル名> docker compose up -d
depends_on
コンテナ間の依存関係を明示する
コンテナAが起動した後にコンテナBを起動しなければいけない場合など有効かも
以下の例の場合
-
docker compose up -dを実行する - webとdbが起動する
- dbが起動したら、apiが起動する
services:
web:
image: web
api:
image: api
depends_on:
- db
db:
image: db
dbの起動まで待機ではなく、ヘルスチェックの完了まで待ちたい場合は下記のようにする
api:
image: api
depends_on:
db:
condition: service_healthy
healthcheck
コンテナ内のサービスが正常しているかを判断する
- test: 正常性確認のために実行するコマンド
- interval:
testの実行頻度 (defalut: 30s) - timeout:
testの実行結果待機時間 (defalut: 30s) - retries:
testの再試行回数 (defalut: 3) - start_period:
testの実行開始までの時間 (defalut: 0s)
healthcheckの結果は、 docker compose ps で確認可能
- success: testコマンドの戻り値が"0"
- unhealthy: testコマンドの戻り値が"1"
- reserved: testコマンドの戻り値が"2" (使用禁止)
services:
backend:
...
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
env_file
環境変数を外部ファイルから参照する
compose.yamlに記載したくない機密情報や環境ごとに切り替える必要のある設定を保有する場合に有効かも
※機密情報を .env に書いていいかは別の話
services:
backend:
...
environment:
TZ: jst
env_file:
- ./.prod.env
- ./.credential.env
entrypoint
コンテナ起動時に実行されるコマンドを定義する
DockerfileのENTRYPOINT命令と同じ役割を持つが、Docker Composeファイルで指定することで、Dockerfileを編集せずにエントリポイントを上書き可能
以下の場合、 $ /app/start.sh run がコンテナ上で実行される
services:
backend:
image: my-backend-image
# コンテナ起動時に `/app/start.sh` を実行する
entrypoint: ["/app/start.sh"]
command: ["run"]
複数のyamlファイル
extends
複数のDocker Composeファイル間で共通の設定を共有するための機能
ベースとなるComposeファイルを指定し、その設定を継承・拡張することができる。
設定をDRYにでき、管理を容易にする
services:
web:
image: nginx
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
services:
web:
# base-compose.yaml#web 設定を継承
extends:
file: base-compose.yaml
service: web
# 開発環境向けの追加設定
# --------------------------------------
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf # 別のボリュームを追加
environment:
VAL: development
override
Docker Composeで複数のComposeファイルを使用する際に、設定を上書きするための機能
compose.yml をベースとして、compose.override.yml というファイルが存在する場合、
- composeは両ファイルを読み込み
- compose.yamlの設定をcompose.override.yml で上書き
- コンテナ起動
となる
環境ごとの設定や一時的なデバッグ設定などを、元のComposeファイルを変更せずに適用できる
services:
web:
image: my-web-app:latest
ports:
- "80:80"
environment:
APP_ENV: production
services:
web:
# web ポートと環境変数を上書き
ports:
- "8080:80"
environment:
APP_ENV: development
volumes:
- ./app:/app
環境ごとのyaml
Docker Composeで複数のComposeファイルを使用する際に、環境ごとにyamlを作成しておくテクニック
- prod環境へは、compose.prod.yaml を適用する
- dev環境へは、compose.dev.yaml を適用する
- ローカル環境へは、compose.yaml を適用する
下記のように -f でcomposeファイルを明示的に指定すればOK
overrideやextendsと組み合わせるとより構造的にファイル管理ができる
※やりすぎ注意
docker compose -f compose.prod.yaml up -d
参考
Discussion