Docker Compose を使う¶
Docker Compose とは、複数コンテナのアプリケーションを定義・共有するために役立つように、開発されたツールです。Compose があれば、サービスを定義する YAML ファイルを作成し、コマンドを1つ実行するだけで、瞬時にすべて立ち上げたり、すべて解体できます。
Compose を使う「大きな」利点は、アプリケーション スタックをファイルに定義し、プロジェクト用リポジトリの一番上に置けるため(これでバージョン管理できます)、プロジェクトに貢献しようとしている誰もが簡単に利用できます。誰もが必要なのは、リポジトリをクローンし、それから
それでは、どのようにして使い始めるのでしょうか?
Docker Compose のインストール¶
Window や Mac で、 Docker Desktop または Toolbox をインストール済みであれば、Docker Compose が入っています! Play-wih-Docker インスタンスも、同様に Docker Compose がインストール済みです。Linux マシンを使う場合は、 Docker Compose のインストール が必要です。
インストール後は、以下のように実行できるようになり、バージョン情報が表示されます。
$ docker-compose version
Compose ファイルの作成¶
アプリプロジェクトのルートで、
docker-compose.yml
という名前のファイルを作成します。
この compose ファイル内では、
スキーマ バージョン の定義から書き始めます。ほとんどの場合、サポートされている最新バージョンを使うのが一番良いでしょう。現時点のスキーマ バージョンと互換表については Compose ファイル リファレンス をご覧ください。version: "3.7"
次に、アプリケーションの一部として実行したいサービス(またはコンテナ)一覧を定義します。
version: "3.7" services:
それでは、 compose ファイルへ、サービスを一気に移行しましょう。
アプリのサービス定義¶
覚えていますか、以下はアプリ用コンテナの定義に使ったコマンドです。
$ docker run -dp 3000:3000 \
-w /app -v "$(pwd):/app" \
--network todo-app \
-e MYSQL_HOST=mysql \
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=secret \
-e MYSQL_DB=todos \
node:18-alpine \
sh -c "yarn install && yarn run dev"
PowerShell の場合は、こちらのコマンドを使っていました。
PS> docker run -dp 3000:3000 `
-w /app -v "$(pwd):/app" `
--network todo-app `
-e MYSQL_HOST=mysql `
-e MYSQL_USER=root `
-e MYSQL_PASSWORD=secret `
-e MYSQL_DB=todos `
node:18-alpine `
sh -c "yarn install && yarn run dev"
はじめに、サービスのエントリとコンテナ用のイメージを定義しましょう。サービスには様々な名前を選べます。この名前が、自動的にネットワーク エイリアスとなり、MySQL サービスの定義時に役立ちます。
version: "3.7" services: app: image: node:18-alpine
通常、
image
定義の近くにcommand
がありますが、順番は無関係です。それでは、ファイルを先へと進めましょう。version: "3.7" services: app: image: node:18-alpine command: sh -c "yarn install && yarn run dev"
コマンドの
-p 3000:3000
を移行するには、サービス用のports
を定義しましょう。ここでは 短い構文 を使いますが、より細かな 長い構文 も同様に使えます。version: "3.7" services: app: image: node:18-alpine command: sh -c "yarn install && yarn run dev" ports: - 3000:3000
次に、作業ディレクトリ(
-w /app
)とボリュームの割り当て (-v "$(pwd):/app"
)の両方を移行するため、working_dir
とvolumes
定義を使います。ボリュームも 短い構文 と 長い構文 があります。Docker Compose でボリューム定義を使う利点の1つは、現在のディレクトリからの相対パスが使える点です。
version: "3.7"
services:
app:
image: node:18-alpine
command: sh -c "yarn install && yarn run dev"
ports:
- 3000:3000
working_dir: /app
volumes:
- ./:/app
最後は、
environment
キーを使って環境変数の定義を移行する必要があります。
version: "3.7"
services:
app:
image: node:18-alpine
command: sh -c "yarn install && yarn run dev"
ports:
- 3000:3000
working_dir: /app
volumes:
- ./:/app
environment:
MYSQL_HOST: mysql
MYSQL_USER: root
MYSQL_PASSWORD: secret
MYSQL_DB: todos
MySQL サービスの定義¶
それでは、 MySQL サービスを定義しましょう。先ほどコンテナを使うために実行したコマンドが、こちらです。
$ docker run -d \
--network todo-app --network-alias mysql \
-v todo-mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=todos \
mysql:5.7
PowerShell の場合は、以下のコマンドを使います。
PS> docker run -d `
--network todo-app --network-alias mysql `
-v todo-mysql-data:/var/lib/mysql `
-e MYSQL_ROOT_PASSWORD=secret `
-e MYSQL_DATABASE=todos `
mysql:5.7
まず新しいサービスと、その名前を
mysql
と定義すると、ネットワーク エイリアスも自動的に得られます。次に進み、使用するイメージも同様に定義します。version: "3.7" services: app: # The app service definition mysql: image: mysql:5.7
次に、ボリューム
割り当て を定義します。docker run
でコンテナを実行した時は、名前付きボリューム が自動的に作成されました。ですが、 Compose の実行時には、そのようになりません。トップレベルのvolume:
セクションでボリュームを定義する必要があり、さらに、サービス設定でもマウントポイントの指定が必要です。単にボリューム名だけを指定すると、デフォルトのオプションが使われます。他にもさらに多くの利用可能なオプション があります。version: "3.7" services: app: # The app service definition mysql: image: mysql:5.7 volumes: - todo-mysql-data:/var/lib/mysql volumes: todo-mysql-data:
さいごに、環境変数のみを指定する必要があります。
version: "3.7" services: app: # The app service definition mysql: image: mysql:5.7 volumes: - todo-mysql-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: secret MYSQL_DATABASE: todos volumes: todo-mysql-data:
これで、 docker-compose.yml
の全体は、このようになっているでしょう。
version: "3.7"
services:
app:
image: node:18-alpine
command: sh -c "yarn install && yarn run dev"
ports:
- 3000:3000
working_dir: /app
volumes:
- ./:/app
environment:
MYSQL_HOST: mysql
MYSQL_USER: root
MYSQL_PASSWORD: secret
MYSQL_DB: todos
mysql:
image: mysql:5.7
volumes:
- todo-mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: todos
volumes:
todo-mysql-data:
アプリケーション スタックの実行¶
ようやく docker-compose.yml
ファイルの準備ができましたので、これで起動できます!
まず、app や db のコピーが確実に停止しているのを確認します(
docker ps
を実行してから、docker rm -f <ids>
を実行 )。
アプリケーション スタックを起動するため、
docker-compose up
コマンドを使います。バックグランドですべてを実行するため、-d
フラグを追加します。$ docker-compose up -d
実行すると、次のような出力が見えます。
Creating network "app_default" with the default driver Creating volume "app_todo-mysql-data" with default driver Creating app_app_1 ... done Creating app_mysql_1 ... done
ボリュームと同時にネットワークも作成されたのが分かるでしょう! デフォルトでは、 Docker Compose はアプリケーション スタックに指定したネットワークを自動的に作成します(そのため、 compose ファイル内にネットワークを定義しませんでした)。
ログを調べるため、
docker-compose logs -f
コマンドを使います。1つの流れの中に、各サービスのログが相互に見えるでしょう。これは、タイミングに関連する問題を監視したい場合に、とても役立ちます。-f
フラグはログを「フォロー 」(追跡)しますので、生成されたログはリアルタイムに表示され続けます。コマンドが実行済みであれば、このような出力になっているでしょう。
mysql_1 | 2019-10-03T03:07:16.083639Z 0 [Note] mysqld: ready for connections. mysql_1 | Version: '5.7.27' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL) app_1 | Connected to mysql db at host mysql app_1 | Listening on port 3000
サービス名が行の始めに(たいてい色が付いて)表示されているため、メッセージの識別に役立ちます。特定のサービスに対するログを表示したい場合は、ログコマンドの最後にサービス名を追加できます(例:
docker-compose logs -f app
)。
これでアプリが開けるようになり、実行中だと分かります。そして、どうでしょう! たった1つのコマンドでできました!
Docker ダッシュボードでアプリのスタックを表示¶
Docker ダッシュボードを見ると、 app という名前のグループが見えます。これは Docker Compose による「プロジェクト名」で、同じグループのコンテナに対して使われます。デフォルトでは、プロジェクト名はシンプルに docker-compose.yaml
が置かれているディレクトリ名です。
app の▶マークをクリックして展開すると、compose ファイルで定義した2つのコンテナが見えます。コンテナ名も説明的になり、 <サービス名>-<レプリカ数>
のパターンに従います。そのため、どのコンテナがアプリで、どのコンテナが mysql データベースなのかを、素早く見つけるのが簡単になります。
全てを削除¶
すべてを解体(終了および削除)する準備が調えば、シンプルに docker-compose down
を実行するか、Docker ダッシュボード上でアプリ全体のゴミ箱をクリックします。コンテナは停止され、ネットワークも削除されます。
警告
ボリュームの削除
デフォルトでは、compose ファイルの名前付きボリュームは docker-compose down
の実行では削除「されません」。ボリュームも削除したい場合は、 --volumes
フラグも追加する必要があります。
Docker ダッシュボードではアプリのスタックを削除しても、ボリュームは削除「されません」。
解体が終われば、他のプロジェクトに切り替えができ、 docker-compose up
を実行すると、そのプロジェクトに貢献する準備が調います! これ以上、本当にシンプルなことはありません!
まとめ¶
このセクションでは、 Docker Compose について学びました。 Docker Compose があれば、複数のサービスがあるアプリケーションの定義と共有が、劇的に簡単にするのに役立ちます。また、実行していたコマンドを適切な compose 形式へ変換し、 Compose ファイルを作成しました。
これで、チュートリアルの仕上げに入りましょう。その前に、イメージの構築に関するいくつかのベストプラクティスについて扱いたいと思います。これまで使っていた Dockerfile には大きな問題があるためです。それでは見てみましょう!
参考
- Use Docker Compose