【Docker】初心者のための Docker Compose まとめ
- 更新履歴
- はじめに
- Docker Compose まとめ
- おわりに
更新履歴
2023/05/05
はじめに
2021 年現在、本番環境や開発環境を問わず Docker (コンテナ技術) は当たり前のものとして使用されるようになりました。
いちエンジニアの立場としても、開発環境をコンテナでスピーディに構築するだけでなく、ちょっとしたお試し環境を用意したいときなど、手軽に環境を Scrap and build できる Docker はもはや無くてはならない存在です。
Docker Compose の詳細については Docker 公式ドキュメントの Docker Compose のページ を参照いただくとして、当記事では Docker 初心者が Docker Compose を使用するにあたり、よく使うんだけどまだちゃんと覚えていない…というような内容をまとめました。
当記事でゼロから Docker Compose を学ぶということではなく、 Docker Compose を一通り学んだ初心者がリファレンス的に使用することを想定しています。
慣れてしまえば難しいことはありませんが、そもそも Docker とは、コンテナ技術とは、という部分が不安な方は Docker 公式ドキュメント を一読することをお勧めします。
ただし、 Docker 公式ドキュメントを一読したなら、そもそもこの記事を読む必要は無いと思いますけどね…
動作環境
OS | Version |
---|---|
Ubuntu | 22.04.2 LTS |
※ Windows 10 Pro の Windows Subsystem for Linux (WSL 2) を使用
Docker Products | Version |
---|---|
Docker Engine | 23.0.5 |
Docker Compose | v2.17.3 |
Docker Compose まとめ
前述した通り、 Docker Compose についての詳細は Docker 公式ドキュメントをご参照ください。
ざっくりと超訳すれば、 Docker Compose は複数のコンテナをまとめて定義・管理することができる Docker のためのツールです。
Compose ファイル (docker-compose.yml)
version: '3.8' services: [service_name]: build: [context_path] image: [image_name]:[tag_name] container_name: [container_name] command: [command] environment: [variable_name]: [value] volumes: - [volume_name]:[container_directory_path]:[mode] - [host_directory_path]:[container_directory_path]:[mode] - type: volume source: [volume_name] target: [container_directory_path] - type: bind source: [host_directory_path] target: [container_directory_path] networks: - [network_name] ports: - '[host_port]:[container_port]' tty: [boolean] restart: [restart_policy] depends_on: - [other_service_name] [other_service_name]: ... volumes: [volume_name]: networks: [network_name]:
Compose ファイルには、 Docker Compose で実行する Docker アプリケーションの設定を定義します。
ファイルは YAML 形式で記述しますが、 JSON 形式でも記述可能です。
コンテナ (services) だけでなく、各コンテナ間のネットワーク (networks) やボリューム (volumes) についても定義でき、各セクションの設定項目は多岐にわたります。
ここでは、 (僕が) よく使用する項目を中心に記載しました。
version (Compose ファイルフォーマットのバージョン)
version: "3.8"
Compose ファイルフォーマットのバージョンを指定します。
使用する Docker Engine のバージョン毎にサポートされる Compose ファイルフォーマットのバージョンが異なるので、 Docker Engine のバージョンに合わせて Compose ファイルのバージョンを指定する必要があります。
以下はその一例です。
Compose file format | Docker Engine release |
---|---|
3.8 | 19.03.0+ |
3.7 | 18.06.0+ |
3.0 | 1.13.0+ |
※ 注意点として、 Compose ファイルのバージョンを指定する場合は、メジャーバージョンとマイナーバージョンの両方を明示的に記述 (version: "3.8"
) する必要があります。
もしメジャーバージョンのみを記述した場合、マイナーバージョンは最新バージョンではなくデフォルトの 0
が補完されます。 (version: "3.0"
)
services セクション
services:
サービス (コンテナ) を定義します。
services
セクション直下に複数のサービスを列記することができます。
[service_name] (サービス名)
[service_name]: # e.g. web:
サービスの名前を指定します。
後述する build
と image
で構築される Docker イメージに名前を付けていない場合、構築されるイメージ名は [project_name]_[service_name]
になります。
プロジェクト名 (project_name
) が特に指定されていない場合は、 Compose ファイルが配置されているディレクトリ名がプロジェクト名になります。
build (Dockerfile)
build: [context_path] # e.g. build: .
build
の指定方法の一つとして、 Dockerfile を含むディレクトリのパスを指定します。
Dockerfile のファイル名やビルド引数などの詳細を指定する方法もありますが、今回は割愛します。
後述する image
を指定することで、構築される Docker イメージに名前を付けることができます。
Dockerfile については 別記事 にまとめていますので、そちらをご覧ください。
image (Docker イメージ名)
image: [image_name]:[tag_name] # e.g. image: python-flask:latest
コンテナで起動する Docker イメージを指定します。
前述の build
が指定されている場合は、 build
で指定された Dockerfile から Docker イメージが構築され、そのイメージ名が image
で指定した名前になります。
build
を指定しない (Dockerfile からイメージを構築しない) 場合、ここで指定された Docker イメージからコンテナを作成しますが、指定した Docker イメージがローカルに存在しない場合は、 Docker Hub から Pull (取得) した上でコンテナが作成されます。
container_name (Docker コンテナ名)
container_name: [container_name] # e.g. container_name: python-flask
構築された Docker イメージから作成されるコンテナの名前を指定します。
command (コマンド)
command: [command] # e.g. command: flask run
Docker Compose でコンテナを開始する際に実行されるコマンドを指定します。
build
セクションや image
セクションの Dockerfile や Docker イメージで定義されている CMD
に代わり、ここで指定したコマンドが実行されます。
environment (環境変数)
environment: [variable_name]: [value] # e.g. environment: FLASK_ENV: development SECRET_KEY
コンテナで使用する環境変数を指定します。
環境変数名のみを指定した場合、 Docker Compose が起動しているシェルで定義されている同名の環境変数がコンテナへ渡されます。
注意点として、 build
セクションで Dockerfile をビルドする際はここで指定した環境変数は使用できません。
ビルド時の環境変数は build
セクションのサブセクションである args
セクションで指定します。
volumes (ボリューム)
volumes: - [volume_name]:[container_directory_path]:[mode] - [host_directory_path]:[container_directory_path]:[mode] - type: volume source: [volume_name] target: [container_directory_path] - type: bind source: [host_directory_path] target: [container_directory_path] # e.g. volumes: - ./src:/src:rw
コンテナで使用するボリュームを指定します。
ボリュームの指定には、 type
(ボリュームのマウント種類) などを省略して一行で書く方法と、詳細を複数行にわたって細かく指定する二通りの書き方があります。
type | source | target |
---|---|---|
volume |
volumes セクションで定義した名前付きボリューム ([volume_name] ) を指定 |
ボリュームがマウントされるコンテナのパス ([container_directory_path] ) を指定 |
bind |
ホストマシンのパス ([host_directory_path] ) を指定 |
ボリュームがマウントされるコンテナのパス ([container_directory_path] ) を指定 |
tmpfs |
- | ボリュームがマウントされるコンテナのパス ([container_directory_path] ) を指定 |
bind
で指定するホストマシンのパス ([host_directory_path]
) には、 Compose ファイルからの相対パス (./
) やユーザのホームディレクトリからの相対パス (~/
) が指定できます。
コンテナのパス ([container_directory_path]
) に Docker イメージに存在しないディレクトリを指定した場合、自動的に当該ディレクトリ (親パス含む) が作成され、ボリュームがマウントされます。
一行で指定する場合の mode
には、読み取り専用の ro
と読み書き可の rw
が指定でき、省略時のデフォルトは rw
になります。
Bind mounts の注意点
マウントするホスト側のディレクトリとマウントされるコンテナ側のディレクトリのいずれかが空でない場合、ホスト側のディレクトリが優先されることになります。
Host side directory | Container side directory | Mounted result |
---|---|---|
空 | 空 | 空になる |
空でない | 空 | ホスト側のディレクトリ内のデータがマウントされる |
空 | 空でない | 空になる |
空でない | 空でない | ホスト側のディレクトリ内のデータがマウントされる |
簡単に言ってしまえば、一部の例外的な Docker イメージを除き、常にホスト側のディレクトリでコンテナ側のディレクトリが置き換わります。
これはディレクトリの統合 (merge) ではないため、たとえホスト側のディレクトリが空であっても、コンテナ側のディレクトリ内のファイル有無に関わらず、結果としてコンテナ内のマウント先ディレクトリは空になります。
誤ってマウント先のファイルを消してしまうことがないように注意しましょう。
ただ、間違った設定をしてしまったとしても、 Compose ファイルを修正して再度コンテナを作成すれば問題ありません。
これも Scrap and build が容易な Docker の良いところです。
networks (ネットワーク)
networks: - [network_name]
コンテナが接続するネットワークを指定します。
後述する最上位の networks
セクションで定義したネットワークを指定することで、明示的にコンテナが接続するネットワークを選択できます。
独自のネットワーク設定を行わなかった場合、コンテナは既定のネットワーク ([project_name]_default
) に接続され、各サービスのコンテナ間は [service_name]
をホスト名としてアクセスすることができます。
ports (ポート)
ports: - "[host_port]:[container_port]" # e.g. ports: - "5000:5000"
ホスト側ポートとコンテナ側ポートのマッピングを指定します。
コンテナ側のポート番号のみを指定した場合、ホスト側のポート番号は空ポートが自動的に割り当てられます。
注意点として、設定にもよりますが、コンテナ内で起動した開発サーバなどが localhost
(127.0.0.1
) からの接続のみを許可している場合、ホスト側から localhost
(127.0.0.1
) で接続することができないことがあります。
これはホスト側からポートフォワードされた際、 localhost
(127.0.0.1
) がコンテナ内の OS の IP アドレスに変換され、外部 (localhost
(127.0.0.1
) 以外) からのアクセスと判断されてしまうためで、解決策としてコンテナ内で起動するサーバへのアクセス制限を無くす必要があります。
tty (疑似 TTY)
tty: [boolean]
疑似 TTY の割り当てを指定します。
true
を指定すると、コンテナを開始時に疑似 TTY が割り当てられます。
restart (サービス再起動ポリシー)
restart: [restart_policy]
サービスの再起動ポリシーを指定します。
ここでは、 Docker を起動した際にコンテナを自動的に開始するかどうかを制御することができます。
Restart policies | Description |
---|---|
"no" |
自動でコンテナを開始しない (既定値) |
always |
常にコンテナを開始する |
on-failure |
エラー発生によりコンテナが終了した場合、コンテナを開始する |
unless-stopped |
コンテナを手動等で停止した場合を除き、常にコンテナを開始する |
いずれの場合も、手動でコンテナを停止した直後にコンテナが再起動することはありません。
always
と unless-stopped
の違いは、手動でコンテナを停止した後、 Docker の (再) 起動時にコンテナが自動的に開始されるかどうかになります。
depends_on (サービス間の依存関係)
depends_on: - [other_service_name]
サービス間の依存関係を定義します。
ここで他サービスを指定した場合、 docker-compose up
コマンドによるコンテナの開始時、依存する他サービス ([other_service_name]
) のコンテナを開始してから当サービス ([service_name]
) のコンテナを開始します。
また、 docker-compose stop
コマンドによるコンテナの停止時も、依存する他サービスのコンテナが停止してから当サービスのコンテナを停止します。
volumes セクション
volumes: [volume_name]:
サービスで使用するボリュームを定義します。
volumes
セクション直下に列記した名前付きボリュームは、前述した services
セクションの各サービスの volumes
に指定して使用できます。
詳細な設定については、今回は割愛します。
networks セクション
networks: [network_name]:
サービスで使用するネットワークを定義します。
networks
セクション直下に列記したネットワークは、前述した services
セクションの各サービスの network
に指定して使用できます。
詳細な設定については、今回は割愛します。
Docker CLI (Compose V2)
docker compose [options] [command] [arguments]
Compose ファイルに定義された複数のサービスは、 docker compose
コマンドで一括、または個別に操作することができます。
既定ではカレントディレクトリにある docker-compose.yml
を Compose ファイルとして使用しますが、以下の -f
オプションを使用すれば、任意の場所にある Compose ファイルを指定することができます。
Options | Description | Example |
---|---|---|
-f [compose file] |
任意の Compose ファイルを指定。 | -f ./others/docker-compose-sub.yml |
--compatibility |
各サービスの deploy セクションの内容を読み取り、 Compose ファイルのバージョン 2 のパラメータとして変換・実行する。 |
--compatibility |
build (イメージ構築)
docker compose build [options] [service]
Compose ファイルに定義された各サービスの Docker イメージを構築します。
サービスの Dockerfile やイメージ構築時のディレクトリ構成・内容を変更した場合は、 docker compose build
コマンドでイメージを再構築する必要があります。
Options | Description |
---|---|
--no-cache |
イメージ構築時に、イメージのキャッシュを使用しない。 |
run (コンテナを開始してコマンド実行)
docker compose run [option] [service] [command] [arguments]
Compose ファイルに定義されたサービスのコンテナを開始し、開始したコンテナ内でコマンドを実行します。
run
サブコマンドではサービスの指定は必須です。
イメージが存在しない場合は、合わせて構築されます。
オプションを指定しない場合、デフォルトでは以下の動作となります。
- Compose ファイルのサービスで定義されたコマンドを実行するが、
run
コマンドで実行するコマンドを指定した場合、コンテナ内で実行されるコマンドを上書きすることが可能 - Compose ファイルのサービスで定義されたポートを作成しない
- 疑似ターミナル (TTY) が割り当てられる
Options | Description | Example |
---|---|---|
--name |
開始するコンテナに名前を設定。 | --name container_name |
-d |
コンテナをバックグラウンドで実行。 | -d |
--rm |
コンテナを実行後に削除。バックグラウンドで実行した場合は無視される。 | --rm |
--service-ports |
Compose ファイルで定義したポートを作成。 | --service-ports |
-p , --publish |
コンテナのポートをホストへ公開。 | -p 8080:80 |
-T |
疑似ターミナル (TTY) を割り当てしない。 | -T |
start (コンテナ開始)
docker compose start [service]
サービスのコンテナを開始します。
stop (コンテナ停止)
docker compose stop [service]
稼働中のサービスのコンテナを削除せずに停止します。
停止したサービスのコンテナは、 start
コマンドで再度開始できます。
restart (コンテナ再起動)
docker compose restart [service]
停止中・実行中にかかわらず、 Compose ファイルで定義されたサービスのコンテナすべてを再起動します。
注意点として、 Compose ファイルを変更して restart
コマンドを実行しても、変更内容はコンテナには反映されません。
rm (コンテナ削除)
docker compose rm [option] [service]
Compose ファイルで定義された停止中のサービスのコンテナを削除します。
デフォルトでは、コンテナにアタッチした匿名ボリュームは削除されません。
Options | Description |
---|---|
-v |
コンテナにアタッチした匿名ボリュームを削除。 |
up (イメージ構築、コンテナ作成・開始・アタッチ)
docker compose up [option] [service]
Compose ファイルで定義されたサービスのイメージの構築、コンテナの作成・開始・アタッチを行います。
もし、既に存在するコンテナのサービスの設定やイメージが変更されていた場合、設定を反映するためにコンテナの停止・再作成が行われます。
Options | Description |
---|---|
-d |
コンテナをバックグラウンドで実行。 |
--force-recreate |
Compose ファイルや使用されるイメージに変更が無くても、コンテナを再作成。 |
--no-recreate |
コンテナが存在する場合、再作成しない。 |
--no-build |
イメージを構築しない。イメージが存在しない場合はエラー。 |
--build |
イメージを構築後、コンテナを開始。イメージに変更があれば、コンテナは再作成される。 |
--no-start |
コンテナを開始しない。 |
down (コンテナ停止・削除)
docker compose down [options]
Compose ファイルで定義されたサービスのコンテナを停止し、 up
コマンドで作成されたイメージ・コンテナ・ネットワーク・ボリュームを削除します。
オプションを指定しなければ、デフォルトで削除されるのは以下のコンテナとネットワークのみです。
- Compose ファイルで定義されたサービスのコンテナ
- Compose ファイルの network セクションで定義されたネットワーク
- default ネットワーク(使用している場合のみ)
Options | Description | Example |
---|---|---|
--rmi [type] |
イメージを削除。 type に all を指定するとすべてのイメージを、 local を指定すると image フィールドにカスタムタグのないイメージだけを削除します。 |
--rmi all |
-v , --volumes |
volumes セクションの名前付きボリューム、および、コンテナにアタッチした匿名ボリュームを削除。 | -v |
exec (稼働中のコンテナでコマンド実行)
docker compose exec [options] [service] [command] [arguments]
Compose ファイルで定義されたサービスの稼働中のコンテナ内で、指定したコマンドを実行します。
コンテナが開始していない場合は、コマンドは実行されません。
exec
サブコマンドではサービスの指定は必須です。
オプションを指定しない場合、デフォルトでは疑似ターミナル (TTY) が割り当てられます。
Options | Description | Example |
---|---|---|
-d , --detach |
コマンドをバックグラウンドで実行。 | -d |
-T |
疑似ターミナル (TTY) を割り当てしない。 | -T |
-e , --env |
環境変数を設定。 | -e KEY=value |
-w , --workdir |
コマンドを実行するディレクトリを指定。 | -w /path/to/workdir |
ps (コンテナ一覧表示)
docker compose ps [options] [service]
Compose ファイルで定義されたサービスのコンテナを一覧表示します。
オプションを指定しなければ、デフォルトで表示されるのは稼働中のコンテナのみです。
Options | Description |
---|---|
-q , --quiet |
コンテナ ID のみを表示。 |
--services |
コンテナのサービス名を表示。 |
-a , --all |
停止中のコンテナを含んだすべてのコンテナを表示。 |
logs (ログ表示)
docker compose logs [options] [service]
Compose ファイルで定義されたサービスのログを表示します。
Options | Description |
---|---|
-f , --follow |
ログを出力し続けます。ログ出力の停止は Ctrl + C で行います。 |
-t , --timestamps |
ログにタイムスタンプを出力します。 |
おわりに
とりあえず Docker Compose を使用するだけなら今回まとめた内容で事足りると思いますが、 Docker Compose は Dockerfile ほどではないにせよ奥が深く、より効率良く運用するためには Docker 公式ドキュメント をしっかり理解する必要があります。
また、 Docker が登場してから既に 8 年以上が経過し、その間、既に非推奨になった内容や新たに追加された仕様も複数存在します。
今回は Docker 公式ドキュメントを参考にしつつ 2021 年 8 月現在の最新情報でまとめたつもりなので、これから Docker Compose を本格的に使用しようと考えている方は、いったんここで最低限必要な内容を押さえ、あとは使いながら深い内容をキャッチアップしていっていただければと思います。
と、これまでさも知っている風に色々書いてきましたが、僕が Docker を使い始めたのは今年からになります。
はい、僕も完全に初心者ですね。イキりました。すいません _(┐「ε¦)_