Docker Compose の基本的な使い方
docker をインストールすると、多くのコンテナサービスを起動することになります。しかし、これらのコンテナをどう統一的にオーケストレーションするか、ネットワークグループの管理、起動順序、データボリュームのマウントなどが課題になってきます。そこで docker チームは、コンテナのオーケストレーションを容易にする docker-compose コンポーネントを開発しました。
なぜオーケストレーションが必要なのか
単一のコンテナなら docker run で起動できますが、実際のアプリケーションがコンテナ 1 つだけで済むことはめったにありません。Web サービスにはたいていデータベース、キャッシュ、メッセージキューが付いてきます。これらのコンテナ間には依存関係があり、同じネットワーク内で互いにアクセスできる必要があり、それぞれデータボリュームのマウントも必要です。すべてを手打ちの docker run に頼っていると、パラメータが長くなれば誰も覚えていられませんし、別のマシンに再デプロイするのはもはや苦行です。
docker-compose が解決するのはまさにこの問題です。すべてのコンテナの起動パラメータを 1 枚の YAML ファイルに固定化してバージョン管理に組み込めば、誰でもファイルさえあれば 1 コマンドで環境一式を再現できます。
インストール
オープンソースプロジェクトのアドレス:
https://github.com/docker/compose
プロジェクトの Releases ページから、システムアーキテクチャに対応するバイナリファイルをダウンロードするだけです。インストールは 2 ステップです。
1、ファイルをダウンロードしてサーバーの /usr/local/bin フォルダにアップロードします。
/usr/local/bin に置くのは、このディレクトリがデフォルトで PATH に含まれているからです。ここに置けば、どのパスからでも直接 docker-compose コマンドを打てます。
2、ファイルに実行権限を付与します
# 実行権限を付与する。付与しないと shell が Permission denied と表示する
sudo chmod +x /usr/local/bin/docker-compose
インストール後は docker-compose version を実行して確認できます。バージョン情報が表示されればインストール完了です。
動作の仕組み
docker-compose は単なるバイナリファイルで、linux システム上で直接実行できます。docker-compose を使うと、yaml ファイルでアプリケーションに必要なすべてのコンテナを設定できます。そして docker-compose up -d という 1 つのコマンドで、yaml ファイルの設定からすべてのサービスを作成・起動できます。
docker-compose 自体は別のコンテナエンジンではなく、低レイヤーでやっていることは手動の docker run とまったく同じです。YAML を解析した後、docker の API を呼び出してネットワーク、ボリューム、コンテナを作成します。いくつかの重要な仕組みを挙げます。
1)プロジェクト(project):compose はデフォルトで yaml ファイルのあるディレクトリ名をプロジェクト名とし、同じプロジェクト配下に作成されたコンテナ、ネットワーク、ボリュームにはこのプレフィックスが付き、互いに分離されます。
2)デフォルトネットワーク:up の際にブリッジネットワークが自動作成され、ファイルに定義されたすべてのサービスがそこに入ります。同じネットワーク内のコンテナはサービス名をホスト名として互いにアクセスでき、コンテナの IP を意識する必要はありません。
3)宣言的管理:再度 up を実行すると、compose は yaml と現在のコンテナの状態を比較し、変更のあったサービスだけを再作成し、変わっていないものはそのまま維持します。
典型的な docker-compose.yml はだいたい次のような形です。
version: "3"
services:
web:
image: nginx # 使用するイメージ
ports:
- "80:80" # ホスト側ポート:コンテナ側ポート
volumes:
- ./html:/usr/share/nginx/html # データボリュームのマウント
depends_on:
- app # 起動順序の宣言:先に app を起動してから web を起動
app:
build: ./app # Dockerfile からその場でビルドすることも可能
restart: always # コンテナが異常終了したら自動で再起動
よく使うコマンド
以下のコマンドはすべて docker-compose.yml のあるディレクトリで実行するか、-f でファイルパスを指定する必要があります。
よく使うコマンド:
docker-compose up [コンテナを起動 -d 付きでバックグラウンド起動]
docker-compose stop [コンテナを停止]
docker-compose ps [現在のすべてのオーケストレーション済みサービスを確認]
docker-compose logs -f --tail=500 <コンテナName> [コンテナのリアルタイムログを確認]
docker-compose restart [コンテナを再起動]
docker-compose rm [コンテナを削除]
docker-compose build [イメージをビルド]
いくつか補足します。
upを-dなしで実行するとフォアグラウンドで動作し、すべてのコンテナのログが現在のターミナルに流れます。デバッグ時にはとても便利で、Ctrl+C を押せば停止します。日常のデプロイでは基本的にup -dです。logsの--tail=500は、最後の 500 行だけ表示してから追跡を始めるという意味です。付けないと過去のログが全部流れてきて、ログ量が多いとターミナルが長時間固まります。stopはコンテナを停止するだけで削除はしません。rmが削除するのは停止済みのコンテナです。コンテナとネットワークを一括で停止・削除したい場合はdocker-compose downを使います。- Dockerfile を変更した後にそのまま
up -dしてもイメージは再ビルドされません。先にbuildしてからupするか、up -d --buildを直接実行します。
ハマりどころと注意点
1)yaml を変更したら忘れずに再度 up する:設定を変更した後に restart だけしても反映されません。restart は古いコンテナを再起動するだけです。新しい設定を反映させるには、もう一度 up -d を実行して、compose に変更のあったコンテナを再作成させる必要があります。
2)depends_on が保証するのは起動順序だけ:コンテナが順番どおりに起動することは保証しますが、依存先のサービスが本当に準備完了していることは保証しません。たとえばデータベースコンテナは起動したもののプロセスがまだ接続を受け付けていない場合、アプリケーションがこのタイミングで接続しにいくとエラーになります。アプリケーション側に再接続のロジックが必要です。
3)データボリュームで相対パスを使うときは実行ディレクトリに注意:yaml 内の相対パスは yaml ファイルの位置を基準に解決されます。別のディレクトリから実行するときは -f でファイルを明示的に指定し、マウント先を間違えないようにするのがよいでしょう。
docker-compose down に -v パラメータを付けるとデータボリュームも一緒に削除されます。ステートフルなサービス(データベースなど)に対して実行する前に、ボリューム内のデータを破棄してよいか必ず確認してください。
まとめ
docker-compose は本質的に、大量の docker run パラメータをバージョン管理可能な 1 枚の YAML に固定化するものです。up -d 1 発でサービス一式が起動し、logs、ps、restart で日常運用をカバーできます。単一マシン環境ならこれで十分快適です。サービスの規模が大きくなってマルチマシンのスケジューリングが必要になったら、そのとき Kubernetes のようなオーケストレーションシステムを検討しても遅くはありません。
COMMENTS