Kubernetes・コンテナ

docker-composeとは?複数コンテナをymlで定義し一括管理する仕組みを解説

docker-composeとは?複数コンテナをymlで定義し一括管理する仕組みを解説

docker-composeは、複数のコンテナで構成されるアプリケーションを1つのYAMLファイル(compose.yaml)に宣言し、docker compose upという単一コマンドで一括起動・停止できるツールです。WebサーバーとAPI、データベース、キャッシュを別々のdocker runで立ち上げていた手作業を、定義ファイル1枚に集約します。この記事では、compose.yamlの書式と日常で使う主要コマンド、Python実装のV1から現行のv5系に至る変遷、単一ホストで完結させてよい境界からKubernetesへ移すべき条件までを、公式ドキュメントを引きながら整理しました。コピーしてそのまま動く compose.yaml とコマンド例も併記。

まとめ:docker-composeで複数コンテナを一括管理する要点

docker-composeの本質は、複数コンテナの構成・依存関係・ネットワーク・永続化をcompose.yamlに宣言し、1コマンドで環境ごと再現できる点にあります。docker runを人手で何度も打つ運用を置き換え、開発者ごとの環境差をなくすのが最大の効き目です。

現行のCLIはGo実装で、コマンドはdocker-compose(ハイフン)からdocker compose(スペース区切りのサブコマンド)へ移りました。版番号は長く2.x系でしたが、2025年12月2日のv5.0.0で3.x・4.xを飛ばして5系へ移り、確認時点(2026年9月9日)の最新はv5.5.1系です。用途としては、単一ホストでの開発・検証・小規模な本番までがdocker-composeの守備範囲。複数ホストの冗長構成や自動スケールが要件になった時点でKubernetesへ移す、という線引きは判断の章で示します。

docker-composeの仕組みと単一コマンドで複数コンテナを動かす構成

まず押さえるべきは、docker-composeが「何を宣言し、何を自動化するか」です。ここでの起点は、複数コンテナの定義を1ファイルにまとめる宣言的な考え方にあります。コンテナ技術そのものの基礎や企業の導入判断は、コンテナと仮想マシンの違いから導入判断までの解説で先に押さえておくと、composeが解く課題をつかみやすくなります。

services・networks・volumesをyamlで宣言する基本構成

compose.yamlは、大きく3つの要素で成り立ちます。servicesが起動するコンテナ群の定義、networksがコンテナ間の仮想ネットワーク、volumesがデータを永続化する名前付きボリュームです。1つのservice(例:webとdb)ごとにイメージ・公開ポート・環境変数を書き、Composeは起動時に既定のネットワークを自動生成して、サービス名(例:db)をホスト名としてコンテナ間の名前解決を通します。公式のネットワーク機能の項でも、サービス名でのアクセスが既定の挙動。この「サービス名で相互に呼べる」性質が、複数コンテナ構成を簡潔にします。

書式そのものはCLIとは別リポジトリのCompose Specificationで管理されています。CLIの版番号とファイル書式の版番号は別物、と切り分けて覚えておくと混乱しません。

docker runの手打ちをcompose.yamlへ置き換える一元管理

Docker単体では、コンテナごとにdocker run -d --name db -e ...を個別に実行し、ネットワークやボリュームも手で作る必要があります。docker-composeは、これらをファイルに宣言し、docker compose up一発へまとめる仕組みです。単一コンテナの起動そのものはDockerの仕組みとコンテナ隔離の解説で扱うdocker runが基礎になりますが、composeはその手順書をコード化し、誰が実行しても同じ構成が立ち上がる再現性をもたらします。手打ちのミスや順序の取り違えが減るのが実務上の差。

ランタイムを入れ替える前提で書くなら、Podmanとdockerの違いと移行判断で差分を先に確認しておくと手戻りが減ります。

Compose V1からv5系までのバージョン変遷と現行の呼び出し方

Python実装の初代docker-compose(V1)は、公式の廃止済みプロダクト一覧に「no longer maintained」として掲載され、Compose v2への移行が案内されています。Docker社は2023年1月の告知でV1のサポート終了を2023年6月以降と示し、以降のDocker DesktopからV1を外しました。

後継のGo実装は長く2.x系でしたが、2025年12月2日のv5.0.0で番号が飛びます。リリースノートは3.0.0と4.0.0を意図的に飛ばした理由を、V1時代のファイル書式の版数「2.x」「3.x」との混同を避けるためと明記しました。同じv5.0.0で内部のBuildKitビルダーが外され、ビルドはdocker buildと同じDocker Bakeへ委譲されています。ビルド側の挙動を追う必要があるならBuildKitの仕組みとキャッシュ設計の解説が前提知識になります。確認時点(2026年9月9日)の最新はv5.5.1で、v5.3.0の初期化コンテナ、v5.4.0のネットワーク再構成のモデル化など、機能追加が続いている段階です。

呼び出し方はV2から変わりません。ハイフンのdocker-composeではなく、スペース区切りのdocker composeサブコマンドを使います。ファイル名はcompose.yamlが推奨。従来のdocker-compose.ymlも引き続き読み込まれます。かつて先頭に書いたversion: "3.8"の指定については、version and name の公式リファレンスが「Composeは常に最新スキーマでファイルを検証する」ためversionは情報提供のみで、記述すると非推奨の警告が出ると説明しています。新規に書くならversion行は省く形です。

compose.yamlを書いてdocker compose upで起動するまでの手順

次に、compose.yamlの書き方と起動から確認までのコマンドを見ていきます。ここが日々の運用で最も触れる部分です。ビルド定義はDockerfileをそのまま参照するため、Dockerfileの書き方と主要命令の解説と組み合わせると、イメージのビルドから起動までが一続きになります。

services定義でimage・ports・environmentを指定する書式

各serviceには、既存イメージを使うimage:か、Dockerfileからビルドするbuild:のどちらかを指定します。ports:でホストとコンテナのポート対応(例:"8080:80")を、environment:で環境変数を渡す形です。データベースのように状態を持つserviceにはvolumes:で名前付きボリュームを割り当て、コンテナを作り直してもデータが消えないようにします。次のcompose.yamlは、web・redis・dbの3サービスをそのまま起動できる最小構成です。

services:
  web:
    build: .
    ports:
      - "8080:80"
    environment:
      DATABASE_HOST: db
      REDIS_HOST: redis
    depends_on:
      db:
        condition: service_healthy
        restart: true
      redis:
        condition: service_started

  redis:
    image: redis:alpine

  db:
    image: postgres:18
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: app
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
      interval: 10s
      retries: 5
      start_period: 30s
      timeout: 10s

volumes:
  db-data:

PostgreSQLを例にしたボリューム定義と初期化SQLの具体はDocker PostgreSQL構築の手順|18で変わったボリューム位置とcompose定義で扱っています。パスワードを平文で置いているのは開発用の割り切りで、本番ではsecretsによる受け渡しへ切り替えます。

depends_onとhealthcheckで起動順と依存を制御する方法

上のファイルで使ったdepends_onは、サービスの起動順序を制御します。ただし既定のdepends_onは「コンテナが起動したか」しか見ず、中のDBが接続を受け付ける状態かまでは待ちません。そこで各serviceにhealthcheckを定義し、depends_on側でcondition: service_healthyを指定すると、DBが実際に応答可能になってからwebを起動できます。

公式の起動順の制御に関するドキュメントは、conditionに指定できる値として、コンテナが実行状態になれば進むservice_started、ヘルスチェックが通るまで待つservice_healthy、依存先が終了コード0で完了するまで待つservice_completed_successfullyの3種を挙げています。加えてrestart: trueを添えると、依存先のdbが更新・再起動されたときにwebも自動で再起動し、接続を張り直します。起動直後の接続失敗を避けたい構成では、この3点を組み合わせるのが定石。

up・down・ps・logs・execなど日常運用で使う主要コマンド

Compose v5系で頻用するコマンドを、役割ごとに整理します。基本は起動・停止・状態確認・ログ・コンテナ内操作の5系統です。

コマンド 役割
docker compose up -d 全サービスを背後で起動
docker compose down コンテナと網を停止・削除
docker compose ps 起動中サービスと公開ポート
docker compose logs -f 全サービスのログを追従表示
docker compose exec web 稼働中コンテナ内で実行
docker compose build build指定のサービス再ビルド

実際に打つ順番で並べると次のようになります。

# 全サービスをバックグラウンドで起動する
docker compose up -d

# 起動中のサービスと公開ポートを確認する
docker compose ps

# webサービスのログだけを追従表示する
docker compose logs -f web

# 稼働中のdbコンテナへ入ってSQLを叩く
docker compose exec db psql -U app -d app

# 停止して削除する(名前付きボリュームは残る)
docker compose down

# ボリュームごと消してデータを初期化する
docker compose down -v

downの既定では名前付きボリュームは残るため、データ保持と初期化を-vの有無で使い分けられます。

pre_startのinitコンテナでDB初期化を先に走らせる書き方

v5.3.0で入ったpre_startは、サービスコンテナが起動する前に別の一時コンテナを順番に走らせる仕組みです。servicesリファレンスは、各ステップが宣言順に完了まで実行され、すべてが終了コード0で終わったあとにサービスコンテナが起動すると定めています。マイグレーションや権限調整のように「本体より前に1回だけ通したい処理」を、起動スクリプトの中へ押し込まずに宣言できます。

services:
  app:
    image: myapp:latest
    depends_on:
      db:
        condition: service_healthy
    pre_start:
      - command: ["./manage.py", "migrate"]
      - image: busybox
        command: sh -c 'chown -R 1000:1000 /data'
    volumes:
      - data:/data

  db:
    image: postgres:18

volumes:
  data:

指定できるキーはcommandのほか、別イメージで走らせるimage、実行ユーザーのuser、privileged、working_dir、environment、レプリカごとに走らせるかを決めるper_replicaです。per_replicaの既定はfalseで、この場合に使えるマウントは名前付きボリュームやバインドマウントのようにレプリカ間で共有されるものに限られます。起動後に走らせたい処理にはpost_startという対になるフックがあり、v5.5.1ではフックの出力を拾って表示する改善が入りました。

開発・検証・本番の各段階で使うdocker-composeの実務的な使いどころ

docker-composeが最も効くのは、複数サービスをまとめて再現したい場面です。段階ごとに使い方と注意点が変わります。

開発環境をcompose一発で再現しチーム間の差異をなくす使い方

新しくチームに加わった開発者が、リポジトリをgit cloneしてdocker compose upを打つだけで、Web・API・DB・キャッシュが揃った同一の開発環境を得られます。ローカルにDBやミドルウェアを個別インストールせずに済み、「自分の環境では動く」というOS差・バージョン差も起きにくいのが利点。compose.yamlをリポジトリに含めれば、環境構築の手順書がコードとして共有されます。

フロントエンドを含む構成の具体例としては、Next.jsをDockerで動かす開発Compose構成と本番イメージの作り方が参考になります。OSS一式をまとめて自前運用する規模の実例なら、Supabaseセルフホストの構成と運用で20近いサービスを1ファイルで束ねた構成を追えます。

profilesとCompose Watchで行うサービス切替とホットリロード

profilesを使うと、通常は起動しない管理ツールやテスト用サービスを、必要なときだけ有効化できます。サービス側にprofiles: [debug]と書いておき、docker compose --profile debug upあるいは環境変数COMPOSE_PROFILESで有効化する形です。プロファイルを付けていないサービスは常に起動するため、既定の構成を壊さずに管理画面だけを足せます。

もう一方のCompose Watchは、ホスト側のファイル変更を検知してコンテナへ反映する仕組みで、develop.watchに監視ルールを書きます。actionは、ファイルをコンテナ内へ同期するsync、BuildKitで新しいイメージを作って差し替えるrebuild、同期したうえで再起動するsync+restartの3種です。

services:
  api:
    build: .
    command: npm start
    develop:
      watch:
        - action: sync
          path: ./api
          target: /src/api
          initial_sync: true
          ignore:
            - node_modules/
        - action: rebuild
          path: package.json

起動はdocker compose watchかdocker compose up --watchです。ignoreのパターンはプロジェクト直下ではなく、そのwatchルールのpathからの相対で解釈される点に注意してください。エディタ側で環境を揃えたい場合はDev Containerで開発環境を統一する仕組みと併用する手もあります。

単一ホストの小規模本番やステージングで使う際の運用上の注意点

docker-composeは、1台のサーバー上で完結する小規模な本番やステージングにも使えます。ただし、コンテナが落ちたときの自動復旧は再起動ポリシー頼みです。servicesリファレンスのrestartは、既定のno、削除されるまで常に再起動するalways、エラー終了時のみ再試行するon-failure、明示的に停止するまで再起動するunless-stoppedの4値をとります。

複数ホストへの分散や無停止デプロイの仕組みは持ちません。単一ホストである以上、そのサーバー自体が単一障害点になります。可用性が要件になったら、次章の境界で移行を判断してください。製品固有の設定が要る例としては、ElasticsearchをDockerで構築する手順が参考になります。

compose.production.yamlに環境差分を分けて本番へ適用する手順

開発と本番で設定を分けるとき、ファイルを丸ごと複製すると差分が追えなくなります。本番運用のドキュメントが示すのは、共通定義をcompose.yamlに置き、変えたい項目だけをcompose.production.yamlに書いて重ねる方法です。同ページは本番で変更すべき項目として、アプリコード用のボリュームバインドを外してコードをイメージ内に持たせること、ホスト側で別ポートに割り当てること、ログの冗長度を下げる環境変数を入れること、ダウンタイムを避けるためrestart: alwaysを指定することを挙げています。

# 共通定義に本番差分を重ねて起動する
docker compose -f compose.yaml -f compose.production.yaml up -d

# コード変更後にwebだけ作り直す(依存サービスは触らない)
docker compose build web
docker compose up --no-deps -d web

2つ目の手順は、同ドキュメントが挙げているデプロイ更新の流れそのものです。--no-depsを付けることで、DBやキャッシュを巻き込まずにアプリだけを差し替えられます。継続的デリバリーへ載せるなら、GitHub Actionsのサービスコンテナで結合テストを回す設計でビルドとテストの経路を先に固めておくと安定します。

docker-composeを採用すべき条件と本番でKubernetesへ移す境界

ここまでを踏まえ、composeで完結させてよい場合と、別基盤へ移すべき場合を条件で言い切ります。「規模による」で終わらせず、判断軸を具体化します。

composeだけで完結させてよいシステム規模と構成の判断基準

次の条件をすべて満たすなら、docker-composeのまま運用して差し支えありません。

  • アプリケーションが1台のホストに収まり、水平スケールの要件がない
  • 数分程度の再起動を許容でき、無停止デプロイまでは求められない
  • サービス数が十数個までで、compose.yamlで見通しよく管理できる
  • 開発・検証環境や、社内利用・小規模なサービスの本番である

小さく始めるフェーズでは、Kubernetesの運用コストを負うより、composeで素早く回すほうが合理的です。1つでも外れた時点で、移行の検討に入ってください。

複数ホストと冗長化が要る本番でKubernetesへ移行する境界線

逆に、次のいずれかに至ったらオーケストレーション基盤への移行を検討します。複数ホストへコンテナを分散して冗長化したい、負荷に応じて自動でスケールさせたい、無停止でローリングデプロイしたい、といった要件です。Kubernetesの公式概要は、コンテナ化されたワークロードとサービスを管理し、宣言的な設定と自動化を扱う移植可能なプラットフォームとして自らを定義しています。単一ホスト前提のcomposeでは、可用性と自動スケールを満たせないのが移行の境界線。

移行先の全体像はKubernetesの仕組みとDockerとの違いの解説、判断軸の整理はコンテナオーケストレーションとKubernetesの役割の解説にまとめています。本番のコンテナ基盤をAWS・GCP・Azure上で設計・移行したい場合は、AWS/GCP/Azureでのインフラ構築の相談から具体的な構成を詰められます。

docker-composeで失敗しやすい典型パターンと回避策の実装

よくある失敗は、開発用のcompose.yamlをそのまま本番へ持ち込むことです。開発向けのポート全公開・デバッグ設定・平文の環境変数を本番に流用すると、セキュリティと安定性の両面で問題になります。回避策は前節の差分ファイル方式で、共通定義をcompose.yamlに置き、環境差分を別ファイルへ分離し、機密値は.envやsecretsで外へ出します。

2つ目の典型は、depends_onだけで起動順を担保したつもりになるパターン。DBが接続を受け付ける前にアプリが起動し、初回だけ失敗する形で表面化します。3つ目は、composeで無理にスケールさせようとして単一ホストの限界にぶつかるパターンで、これは移行の境界を越えたサインです。

docker-composeの仕組みと使い方に関するよくある質問

導入検討でよく挙がる質問に実装の観点から答えます。

docker-composeとdocker composeの違いは何ですか?

ハイフンのdocker-composeはPython製の旧V1、スペース区切りのdocker composeはGo製の後継で、現行はこちらです。V1はDocker公式の廃止済みプロダクト一覧に「no longer maintained」として載っており、サポートは2023年6月以降に終了しました。後継は上位互換で、既存のdocker-compose.ymlもそのまま読み込めます。新規に始めるならdocker composeコマンドを使ってください。

Composeのバージョンが2から5に飛んだのはなぜですか?

2025年12月2日のv5.0.0リリースノートが理由を明記しています。V1時代から引き継がれたcompose.yaml側の書式版数「2.x」「3.x」と、CLIの版番号との混同を避けるため、3.0.0と4.0.0を意図的に飛ばしたと説明されています。同リリースでは内部のBuildKitビルダーが外れてビルドがDocker Bakeへ委譲され、ComposeをSDKとして他ソフトへ組み込む使い方も公式にサポートされました。確認時点の最新はv5.5.1です。

compose.yamlとdocker-compose.ymlはどちらを使うべきですか?

新規作成ではcompose.yamlが推奨のファイル名です。従来のdocker-compose.ymlも引き続き認識されるため、既存プロジェクトを無理に改名する必要はありません。中身の書式は同じで、ファイル名の差だけです。迷うならcompose.yamlで統一してください。

versionの記述は今も必要ですか?

不要です。公式のversion and nameリファレンスは、Composeが常に最新スキーマでファイルを検証するためversionフィールドは情報提供のみだと述べており、記述すると非推奨の警告が出ます。古い記事の書式をそのまま残すと混乱のもとになるため、新規のcompose.yamlではversion行を省いてservicesから書き始めてください。

compose内の複数コンテナはどう通信しますか?

Composeが自動生成する既定ネットワーク上で、サービス名をホスト名として名前解決できます。例えばwebからDBへは、IPではなくdbというサービス名で接続する形です。別ネットワークに分離したい場合はnetworksを明示的に定義し、どのサービスをどのネットワークに属させるかを指定します。公式のネットワークのドキュメントも、この名前解決を既定の挙動として説明しています。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

ほか 9 件の記事からもリンクされています。

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.06 テックブログ 大和証券の不正アクセスと約11万人分の口座番号:問い合わせ管理の委託先に残さない設計
  2. 2026.10.06 テックブログ 焼肉きんぐの不正アクセスと1,078万件の会員情報|全件規模の流出を防ぐAPIとログの点検
  3. 2024.06.11 コラム 個人情報漏えい件数の推移をグラフで解説|最新データと過去最多(約1.9万件)
  4. 2026.10.05 テックブログ WSL Containersとは?wslcの使い方とDocker Desktopとの使い分け【WSL 3.0.1時点】
  5. 2026.10.05 テックブログ 東京メトロ(メトポ)の不正アクセスと約5.9万件のメールアドレス|配信停止リストを残さない設計

RELATED POSTS 関連記事

目次