Docker Compose を使う¶
Docker Compose とは、複数コンテナのアプリケーションを定義・共有するために役立つように、開発されたツールです。Compose があれば、サービスを定義する YAML ファイルを作成し、コマンドを1つ実行するだけで、瞬時にすべて立ち上げたり、すべてを削除したりできます。
Compose を使う「大きな」利点は、アプリケーション スタックをファイルに定義し、プロジェクト用リポジトリの一番上に置けるため(これでバージョン管理できます)、プロジェクトに貢献しようとしている誰もが簡単に利用できます。誰もが必要なのは、リポジトリを複製(クローン)し、それから 
それでは、どのようにして使い始めるのでしょうか?
Docker Compose のインストール¶
Docker Desktop for Window や Mac や Linux をインストール済みであれば、Docker Compose が入っています! Play-wih-Docker インスタンスも、同様に Docker Compose がインストール済みです。
Docker Engine を単体でインストールした場合は、別のパッケージとして Docker Compose のインストールが必要です。 Compose プラグインのインストール を御覧ください。
インストール後は、以下のように実行できるようになり、バージョン情報が表示されます。
$ docker compose version
Compose ファイルの作成¶
- /getting-started/appフォルダのルートで- docker-compose.ymlという名前のファイルを作成します。
- compose ファイル内では、アプリケーションの一部として実行したいサービス(あるいはコンテナ)の一覧の定義から始めます。 - services: 
それでは、 compose ファイルへ、サービスを一気に移行しましょう。
アプリのサービス定義¶
覚えていますか、以下はアプリ用コンテナの定義に使ったコマンドです。
$ 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"
- まずはじめに、サービスを記述し、コンテナ用のイメージを定義しましょう。サービスには様々な名前を選べます。この名前が、自動的にネットワーク エイリアス(別名)となり、MySQL サービスの定義時に役立ちます。 - services: app: image: node:18-alpine 
- 通常、 - image定義の近くに- 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でコンテナを実行した時は、- 名前付きボリューム が自動的に作成されました。ですが、 Compose の実行時には、そのようになりません。トップレベルの- volume:セクションでボリュームを定義する必要があり、さらに、サービス設定でもマウントポイントの指定が必要です。単にボリューム名だけを指定すると、デフォルトのオプションが使われます。他にも更に- 多くの利用可能なオプション があります。- 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:
これで、 docker-compose.yml の全体は、このようになっているでしょう。
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:
アプリケーション スタックの実行¶
ようやく 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: '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)。
- これでアプリが開けるようになり、実行中だと分かります。そして、どうでしょう! たった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 を実行したら、そのプロジェクトに貢献する準備が調います! これ以上、本当にシンプルなことはありません!