こんにちは、かつコーチです。
ここまでの記事で、docker runによるコンテナ起動や、ボリューム・ネットワークの使い方を学んできました。
でも実際のWebアプリ開発では、Webサーバー用コンテナとデータベース用コンテナを別々に起動して、ネットワークでつないで……と、コマンドがどんどん長くなっていきます。
「毎回このコマンドを打つのは面倒」
「チームメンバーに同じ手順を再現してもらうのが大変」
そんな悩みを解決してくれるのが、今回紹介するdocker-composeです。
この記事では、docker-composeが何をしてくれる仕組みなのか、基本の書き方、そしてつまずきやすいポイントを解説します。
docker-composeとは?複数コンテナをまとめて管理する仕組み
docker-composeの定義(比喩:オーケストラの指揮者)
docker-composeとは、複数のDockerコンテナの設定をひとつのファイルにまとめて、一括で起動・停止できるようにするツールです。
Web用コンテナ、DB用コンテナ、キャッシュ用コンテナ……といった複数のコンテナを、それぞれdocker runで個別に管理するのは大変です。
これを、オーケストラに例えると分かりやすくなります。
バイオリン奏者、チェロ奏者、トランペット奏者がそれぞれ好き勝手に演奏しても、音楽にはなりません。
指揮者が全体のテンポや入りのタイミングを指示することで、はじめて一つの演奏としてまとまります。
docker-composeは、まさにこの指揮者の役割を果たします。
docker-compose.ymlという1枚の楽譜(設定ファイル)に「どのコンテナを」「どんな設定で」「どの順番で」動かすかを書いておけば、あとはdocker-composeがそのとおりに全コンテナを指揮してくれるのです。
なぜ必要か——docker runを何度も打つ手間をなくす
たとえば、Webサーバーとデータベースの2つのコンテナを個別に起動する場合、次のようなコマンドを2回打つ必要があります。
docker network create my-app-net
docker run -d --name db --network my-app-net -e POSTGRES_PASSWORD=secret postgres:latest
docker run -d --name web --network my-app-net -p 8080:80 my-app-image
コンテナが増えるほど、このコマンドはどんどん長くなります。
しかもこの手順は、チームメンバーに口頭やドキュメントで伝える必要があり、伝達ミスや手順の抜け漏れが起きがちです。
docker-composeを使えば、この手順すべてを1つのファイルに記録できるので、docker compose upのひとことで同じ環境を誰でも再現できます。
docker-compose.ymlの基本的な書き方
最小構成のdocker-compose.yml
まずは、先ほどのWeb+DB構成をdocker-compose.ymlで書き直してみます。
services:
web:
image: my-app-image
ports:
- "8080:80"
depends_on:
- db
db:
image: postgres:latest
environment:
POSTGRES_PASSWORD: secret
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
このファイルを作成したディレクトリで、以下のコマンドを実行するだけで、web・dbの2コンテナとネットワーク・ボリュームがまとめて作成されます。
docker compose up -d
docker runを2回打っていた作業が、たった1コマンドに集約されました。
よく使う項目(services・image・ports・volumes・environment)
docker-compose.ymlでよく使う項目を整理します。
| 項目 | 役割 |
|---|---|
services | 起動するコンテナ(サービス)を列挙するトップレベル項目 |
image | 使用するイメージ名(ビルドする場合はbuildを使う) |
ports | ホスト側とコンテナ側のポート対応("ホスト:コンテナ") |
volumes | データを永続化するボリュームのマウント設定 |
environment | コンテナ内で使う環境変数 |
depends_on | 起動順の依存関係(詳しくは次回の記事で解説します) |
servicesの下に書いたキー(上の例ではwebとdb)が、そのままコンテナ名やネットワーク内でのホスト名になります。
docker composeコマンドの基本操作
up・down・ps・logsの使い方
docker-composeの操作は、docker composeに続けてサブコマンドを打つ形式です。
| コマンド | 役割 |
|---|---|
docker compose up -d | 全コンテナをバックグラウンドで起動 |
docker compose down | 全コンテナ・ネットワークを停止&削除 |
docker compose ps | 起動中のコンテナ一覧を確認 |
docker compose logs -f web | webサービスのログをリアルタイム表示 |
-dオプションはバックグラウンド実行(デタッチモード)を意味し、docker run -dと同じ考え方です。
つけ忘れると、ターミナルがログ出力で占有されたままになるので注意しましょう。
停止と削除の違いに注意する
docker compose downを実行すると、コンテナとネットワークは削除されますが、volumesで定義したデータはデフォルトでは残ります。
データも含めて完全に削除したい場合は、-vオプションを追加します。
docker compose down -v
検証環境をまっさらにしたいときと、データは残したまま再起動したいときとで、この違いを意識して使い分けてください。
よくあるつまずきポイント
version記述の扱い(Before/After)
以前のdocker-compose.ymlでは、ファイルの先頭にversion: '3.8'のようなバージョン指定が必須でした。
しかし現在の最新安定版では、このversion項目は廃止(obsolete)扱いになっています。
❌ Before(古い書き方)
version: '3.8'
services:
web:
image: my-app-image
このままdocker compose upを実行すると、筆者の環境では実際に以下の警告が表示されました。
WARN[0000] /path/to/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
動作自体は止まりませんが、放置していると「このファイルは古い書き方のままだ」というノイズになります。
✅ After(現在の推奨)
services:
web:
image: my-app-image
version行を削除するだけで警告は消えます。
新しくファイルを作る場合は、最初からversion行を書かないのが正解です。
応用・一歩先の使い方
次回の記事では、今回作った基本形をさらに発展させて、Webアプリケーションとデータベースを実際に連携させる構成を組んでいきます。
depends_onだけでは解決できない「DBの起動完了を待つ」問題や、環境変数を使った接続情報の受け渡しなど、実務でつまずきやすいポイントを扱います。
まとめ
この記事のポイント
- docker-composeは複数コンテナの設定をまとめて管理する、いわば「オーケストラの指揮者」
docker-compose.ymlに構成を書けば、docker compose up -dだけで全コンテナを一括起動できるdocker compose downだけではボリュームのデータは残る。完全削除には-vオプションが必要version項目は現在は廃止扱い。新規作成時は書かないのが正解
次に読むべき記事
- docker-composeでWeb+DB構成を連携させる(次回)
- ボリュームでデータを永続化する
- Dockerネットワークの基本:コンテナ同士をつなぐ
タグ: Docker, 中級者向け, docker-compose