Docker Compose を使用する
Docker Compose は、マルチコンテナアプリケーションを定義して共有するのに役立つツールです。Composeを使えば、サービスを定義するYAMLファイルを作成し、1つのコマンドでアプリケーション全体を立ち上げたり、終了させたりできます。
Composeを使う大きなメリットは、アプリケーションスタックをファイルで定義し、それをプロジェクトリポジトリのルートに置いてバージョン管理できることです。これにより、他の人がプロジェクトに簡単に参加できるようになります。誰かがリポジトリをクローンして、Composeを使ってアプリケーションを起動するだけで済むようになります。実際、多くのプロジェクトがGitHubやGitLabでこの方法を採用しています。
Composeファイルを作成する
getting-started-app
ディレクトリ内に、compose.yaml
というファイルを作成します。
├── getting-started-app/
│ ├── Dockerfile
│ ├── compose.yaml
│ ├── node_modules/
│ ├── package.json
│ ├── spec/
│ ├── src/
│ └── yarn.lock
アプリサービスを定義する
パート6 では、次のコマンドを使ってアプリケーションサービスを起動しました。
$ docker run -dp 127.0.0.1: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"
これを compose.yaml
ファイルでサービスとして定義します。
-
テキストエディタやコードエディタで
compose.yaml
を開き、実行する最初のサービス(またはコンテナ)の名前とイメージを定義します。名前は自動的にネットワークエイリアスとなるため、MySQLサービスを定義するときに役立ちます。services: app: image: node:18-alpine
-
通常、
command
はimage
定義の近くに置かれますが、順序に決まりはありません。compose.yaml
ファイルにcommand
を追加します。services: app: image: node:18-alpine command: sh -c "yarn install && yarn run dev"
-
次に、
-p 127.0.0.1:3000:3000
の部分をports
を使って定義します。services: app: image: node:18-alpine command: sh -c "yarn install && yarn run dev" ports: - 127.0.0.1:3000:3000
-
続いて、作業ディレクトリ (
-w /app
) とボリュームマッピング (-v "$(pwd):/app"
) をworking_dir
とvolumes
で定義します。Docker Composeのボリューム定義の利点の1つは、現在のディレクトリから相対パスを使用できることです。
services: app: image: node:18-alpine command: sh -c "yarn install && yarn run dev" ports: - 127.0.0.1:3000:3000 working_dir: /app volumes: - ./:/app
-
最後に、環境変数定義を
environment
キーを使って移行します。services: app: image: node:18-alpine command: sh -c "yarn install && yarn run dev" ports: - 127.0.0.1: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:8.0
-
新しいサービスを定義し、名前を
mysql
にして自動的にネットワークエイリアスを取得します。また、使用するイメージも指定します。services: app: # The app service definition mysql: image: mysql:8.0
-
次にボリュームマッピングを定義します。
docker run
を使用してコンテナを実行したとき、Dockerは自動的に名前付きボリュームを作成しましたが、Composeで実行する場合にはそれが自動的には行われません。トップレベルのvolumes:
セクションでボリュームを定義し、サービス設定でマウントポイントを指定する必要があります。ボリューム名だけを指定すると、デフォルトのオプションが使用されます。services: app: # The app service definition mysql: image: mysql:8.0 volumes: - todo-mysql-data:/var/lib/mysql volumes: todo-mysql-data:
-
最後に、環境変数を指定します。
services: app: # The app service definition mysql: image: mysql:8.0 volumes: - todo-mysql-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: secret MYSQL_DATABASE: todos volumes: todo-mysql-data:
ここで、compose.yaml
全体は次のようになります。
services:
app:
image: node:18-alpine
command: sh -c "yarn install && yarn run dev"
ports:
- 127.0.0.1:3000:3000
working_dir: /app
volumes:
- ./:/app
environment:
MYSQL_HOST: mysql
MYSQL_USER: root
MYSQL_PASSWORD: secret
MYSQL_DB: todos
mysql:
image: mysql:8.0
volumes:
- todo-mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: todos
volumes:
todo-mysql-data:
アプリケーションスタックを実行する
compose.yaml
ファイルができたので、アプリケーションを起動できます。
-
最初に、他のコンテナが実行されていないことを確認してください。
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がボリュームやネットワークを作成していることに注目してください。デフォルトでは、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: '8.0.31' 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
のように、ログコマンドの末尾にサービス名を追加します。 -
この時点で、http://localhost:3000 でアプリケーションを開き、動作を確認できるはずです。
Docker Dashboardでアプリスタックを確認する
Docker Dashboardを見ると、getting-started-app という名前のグループがあることがわかります。これはDocker Composeからのプロジェクト名で、コンテナをグループ化するために使用されます。デフォルトでは、プロジェクト名は compose.yaml
が存在するディレクトリの名前になります。
スタックを展開すると、Composeファイルで定義した2つのコンテナが表示されます。名前も少し説明的になり、<サービス名>-<レプリカ番号>
というパターンに従っています。これにより、どのコンテナがアプリで、どのコンテナがMySQLデータベースかをすぐに見分けることができます。
すべてを削除する
すべてを削除する準備ができたら、単に docker compose down
コマンドを実行するか、Docker Dashboardでアプリ全体のゴミ箱アイコンをクリックします。コンテナは停止し、ネットワークが削除されます。
警告
デフォルトでは、Composeファイルに記載された名前付きボリュームは、
docker compose down
コマンドを実行しても削除されません。ボリュームを削除したい場合は、--volumes
フラグを追加する必要があります。Docker Dashboardでアプリスタックを削除しても、ボリュームは削除されません。
まとめ
このセクションでは、Docker Composeについて学び、マルチサービスアプリケーションを定義し、共有する方法を簡単にする方法を学びました。
関連情報:
次のステップ
次は、Dockerfileを改善するためのベストプラクティスについて学びます。