Docker Composeで複数コンテナを一括操作
複数のDockerコンテナの操作を簡単にする、Docker Composeついて紹介します。
本記事で使用するファイルはこちらからダウンロード出来ます。
docker-compose-lesson.zip
SAMPLE
Docker Composeの機能は※docker-composeコマンドで操作します。
※Docker Desktopをインストールした時点で使用可能
docker-comoseバージョン確認
(docker本体とはバージョンが分かれている)
docker-compose --version
下記の記事ではそれぞれ別々で起動したwebサーバのコンテナとDBのコンテナをネットワーク連携する方法を紹介しました。
本記事ではそれと全く同じことをDocker Composeを使ってよりカンタンに実現する手順を解説します。
環境: Docker version 19.03.13, docker-compose version 1.27.4
Docker Composeのメリット
複数のDockerコンテナからなるアプリケーションを実行する際、通常は利用するコンテナの数だけ起動を行い、docker runコマンドのオプションも毎回正しく指定しなくてはいけません。
Docker Composeを使用する場合、詳しくは後ほど紹介していきますがdocker-compose upという決まったコマンドを一度実行するだけで、アプリケーションに必要な複数のコンテナを一度にまとめて起動することが出来ます。
また、docker runコマンドで指定していたオプション等は専用の定義ファイルであるdocker-compose.ymlに記述出来るようになります。
これにより複数人で同じアプリケーションを開発する場合に毎回決められた設定で確実にDockerによる開発環境を構築出来るようになります。
起動するコンテナがひとつのみであっても通常のdocker runコマンドのように実行時に多くのオプションを必要としないメリットがあります。
Docker Compose利用の準備
Docker Composeを利用する際はサンプルのように対象のアプリケーションの実行に必要なファイル郡を一箇所にまとめておきます。
.
├── db
│ ├── Dockerfile
│ ├── settings
│ │ └── my.cnf
│ └── sqls
│ └── data.sql
├── docker-compose.yml
├── htdocs
│ └── index.php
└── web
└── Dockerfile
1. docker-compose.yml
docker-compose.ymlはDocker Composeを利用するための定義ファイルで、docker-composeコマンドを実行する際のルールをインデント(字下げ)と:(コロン)を用いるYAMLという形式で記述します。
version: '3.8'
services:
web:
build:
context: ./web
dockerfile: Dockerfile
image: php-apache-compose
container_name: php-apache-compose-cont
restart: always
ports:
- 82:80
volumes:
- ./htdocs:/var/www/html
db:
build:
context: ./db
dockerfile: Dockerfile
image: mysql-compose
container_name: mysql-compose-cont
restart: always
environment:
MYSQL_ROOT_PASSWORD: password
volumes:
- ./db/sqls:/docker-entrypoint-initdb.d
(各項目について)
version:
ファイルの記述バージョンを指定する。
Docker本体であるDocker Engineのアップデートにともない、過去の記法がサポートされなくなった場合でも、こちらに作成時点のバージョンを明示しておけば、最新バージョンのDocker Composeでも過去のバージョンの記法を使用することが出来ます。
services:
起動するコンテナごとにひとつのサービスとして定義する。
ここではWebサーバ用コンテナにweb、DBサーバ用コンテナにdbというservice名をつけて個別に定義しています。
service名は次に説明する、ビルドコンテキスト及びディレクトリ名と統一しておくことが推奨されます。
build:
イメージの元となるDockerfileの場所とDockerfileの名前を定義する。
contextにはdocker-compose.yml自身から見たDockerfileの存在するパス、Dockerfileにはcontextからのパスを記述します。
Dockerfileの名前を変更していない場合は、これらを省略して
build: ./web
とするだけでもOKです。
image:
前述のbuild:オプションでbuildするイメージ名を指定する。
build:オプションを使用しない場合は下記のように通常のdocker imageを指定する。
例)
image: php:8.0-apache
container_name:
起動するコンテナ名を指定する。
restart:
再起動ポリシーの指定。
(docker runで指定するオプションと同じ)
https://docs.docker.jp/config/container/start-containers-automatically.html
environment:
環境変数を設定する。(コンテナごとの設定値)
ports:
ポートフォワーディング設定。
volumes:
ディレクトリマウント設定。
ホスト側:コンテナ側
のように、ディレクトリ共有設定を行う。
2. 各コンテナごとのDockerfile
各コンテナの元となるイメージをビルドする場合は対象のDockerfileも用意します。
イメージをビルドしないでデフォルトの状態からコンテナを起動する際はDockerfileは必要なく、
docker-compose.ymlにもbuild: の指定は必要ありません。
(その他) 設定ファイル、ソースコード
DBの設定ファイル、テストデータ用の.sqlファイル、Webサーバの実行ファイル等を通常のdockerコンテナによる環境構築時と同様に用意しておきます。
docker-composeコマンドの実行
必要なファイルの用意が出来たら、docker-compose.ymlのパスでdocker-composeコマンドを実行していきます。
イメージのビルド
docker-compose.ymlに記述された各コンテナのイメージをまとめてビルドします。
docker-compose build
コンテナの起動
イメージのビルドに成功したら、下記コマンドを実行し、docker-compose.ymlに記述されたコンテナを一括で作成、起動します。
docker-compose up -d
コンテナの起動だけでなくこの時点で各コンテナ間を通信させるためのネットワークの作成も行われます。
イメージのビルドとコンテナの起動を同時に行う
下記のようにbuildオプションを指定することで、コンテナ起動時にイメージのビルドも行うことが出来ます。
docker-compose up -d --build
ビルドを行わないとどうなる?
ビルドを行わないとDockerfileの更新内容が反映されません。
ビルドするイメージがまだ存在していないときは、次で説明するdocker-compose upの実行だけでもビルドが行われますが、
2回目以降のコンテナ起動時には上記のオプションを使用するか、buildコマンドでビルドを明示的に行わなければDockerfileに加えた定義の変更内容がコンテナ起動時に反映されません。
サービス指定でコマンド実行
サービス名(services:)を指定することで複数まとめてでなく、単体で起動することができる。
例) 上記docker-compose.ymlのservicesのうち、webのみ起動
docker-compose up -d --build web
アプリケーションの実行確認
コンテナの起動が確認出来たらコンテナで起動中のwebサーバーにブラウザからアクセスします。
docker-compose.yml、ports:で指定した接続ポート番号でアクセス
http://localhost:82/
画面上にテスト用データが表示出来たらDocker Composeによるコンテナ操作の成功です。
docker-composeコマンドまとめ
コマンド | 動作 | 備考 |
---|---|---|
docker-compose build | イメージのビルド | オプション--no-cacheビルド時にキャッシュを利用しない |
docker-compose up | コンテナの起動 | オプション-dバックグラウンドモード(基本的に指定) --buildイメージのビルドを同時に行う |
docker-compose ps | 起動中のComposeコンテナの確認 | |
docker-compose images | Composeイメージの確認 | Container: コンテナ名 Repository: イメージ名 |
docker-compose exec ※サービス名 bash | Composeコンテナへのログイ | ※ docker-compose.yml、services:で指定した名前 |
docker-compose down | Composeコンテナをまとめて削除 | オプション--rmi allComposeイメージ、ネットワークを含め全て削除する |
docker-compose stop | Composeコンテナを停止 | 後ろにサービス名を指定しない場合は全てのComposeコンテナを停止する |
docker-compose start | 停止中のComposeコンテナを起動 | 後ろにサービス名を指定しない場合は全ての停止中Composeコンテナを起動する |
docker-composeコマンドの操作対象はdocker-compose.ymlに関連するコンテナやイメージだけで、通常のdockerコマンドで作成されたコンテナやイメージの操作は出来ません。
逆に、docker-composeコマンドで作成されたコンテナ、イメージは通常のdockerコマンドでも操作を行うことも出来ますが、複数コンテナにまたがる操作を行う場合はdocker-composeコマンドを使う事が推奨されます。
補足事項
本記事で説明しきれなかった点は下記記事で補足しています。