SSD Nodes Learn Hosting plans →
ガイド Matt Connor著者 Matt Connor

Docker Compose実運用コマンドチートシート

Docker Compose V2で日常的に使う約12コマンドを、起動・変更反映・ログ・シェル・ネットワーク・volume・安全な削除の用途別に整理しています。

実際に使う Compose コマンド

Docker Compose には多数のサブコマンドがあります。サーバーの日常的な作業で使うのは、そのうち約 12 個です。このページでは、作業内容ごとにコマンドを分類し、それぞれの用途を簡潔に説明します。また、コマンドに潜む注意点を詳しく説明するページも示します。

ここでは Compose V2 または V5 を使用します。つまり、スペースを含む docker compose であり、従来の docker-compose スクリプトではありません。どちらも Go プラグインです。Linux では、Compose プラグインを Docker Engine とは別にインストールします。Ubuntu 24.04 LTS では、universe リポジトリに従来の Python V1 ツールが docker-compose version 1.29.2-6ubuntu1 として提供されています。docker compose version で確認してください。コマンドを利用できない場合は、Docker のリポジトリを設定し、docker-compose-plugin パッケージをインストールしてください。

以下のコマンドはすべて、compose.yaml を置いているディレクトリから実行します。Compose は、上書きしない限り、そのディレクトリ名をデフォルトのプロジェクト名として使用します。-f または COMPOSE_FILE を指定しない場合、Compose は作業ディレクトリとその親ディレクトリを検索して設定ファイルを探します。そのため、1 つ上のディレクトリから実行した場合、設定ファイルがその検索パス上に残っている場合に限り、対象のスタックを見つけられます。ファイル形式自体に慣れていない場合は、まず VPS で最初の Compose ファイルを作成する を読み、その後このページでコマンドを確認してください。

ライフサイクル: 入力する4つのコマンドと、コンテナを削除する1つのコマンド

docker compose up -d
docker compose up -d --wait
docker compose stop
docker compose start
docker compose restart web
docker compose down

up -dはネットワークとコンテナを作成し、コンテナを起動して終了します。アプリケーションの準備完了を待たずにコンテナの起動後に終了するため、これに続けて curl プローブを実行するデプロイスクリプトは、初回に失敗することがよくあります。up -d --waitは、healthcheck が設定されたサービスが healthy になり、設定されていないサービスが running になるまで待機します。サービスが unhealthy になるか、--wait-timeout の期限が切れると、ゼロ以外の終了ステータスになります。このフラグの信頼性は、その背後にあるチェック次第です。そのため、自動化で使用する前に、Compose が信頼できる healthcheckを作成してください。

stopはコンテナを停止して保持します。そのため、startを実行すると、同じ書き込み可能レイヤーを持つ同じコンテナが再び起動します。downはコンテナを停止した後、コンテナとプロジェクトネットワークを削除します。volume の外側でコンテナ内に書き込まれたデータは、コンテナとともに失われます。これは Compose で最も影響の大きい誤解です。down と stop の完全な違いでは、どのような場面で問題になるかを説明しています。

restartは reload ではありません。既存の設定を使って同じコンテナを停止・起動するだけなので、変更した環境変数、新しい image tag、編集した port mapping はまったく反映されません。ファイルの変更を適用するには、up -dをもう一度実行します。Compose は各サービスと実行中のコンテナを比較し、設定または image が変更されたコンテナを再作成します。

変更の適用: 再作成、pull、または再ビルド

docker compose up -d --force-recreate
docker compose pull && docker compose up -d
docker compose build --no-cache web
docker compose up -d --build web

up -d は、設定とイメージが変わっていない場合、実行中のコンテナを再利用します。イメージの pull と build は、サービスの pull ポリシーに従います。--force-recreate はこの比較を上書きし、設定が同一でもすべてのコンテナを置き換えます。そのため、コンテナ内に残った不審な状態を解消する最も速い方法です。

明示的にイメージを更新する手順で 2 つのコマンドを使うのは、それぞれの役割が異なるためです。pull は、ファイル内で指定された各タグの現在のイメージをダウンロードします。続いて up -d が、サービスのイメージ ID と実行中のコンテナのイメージ ID が一致しないことを検出し、コンテナを再作成します。デフォルトの missing pull ポリシーでは、latest を除き、キャッシュ済みのタグが再利用されます。latest は常に pull されます。反対に、複数サービスのスタックでは、すべてのサービスに対して一度に latest を pull すると、10 秒前まで正常に動作していたアプリケーションが壊れる可能性があります。そのため、self-hosted AFFiNE ワークスペースでは、代わりにアプリケーションイメージとマイグレーションイメージを同じ digest に固定することを推奨しています。固定すると、タグを意図的に編集してから同じ pull と再作成を実行する、明確なアップグレード手順になります。起動時にデータベースをマイグレーションするスタックでは、どちらのコマンドを実行する前にも dump を用意しておく必要があります。これは、self-hosted Chatwoot サポートデスクがすべてのバージョン更新で実施している手順です。

build は、build: セクションを宣言するサービスに適用されます。image: も宣言するサービスが含まれます。up -d --build は build と起動を 1 つの手順で実行します。コードを変更している間は、これが通常の反復手順です。キャッシュされた layer が明らかに古い場合に限り --no-cache を使用してください。すべての layer が最初から再 build されるためです。プロジェクトによっては、1 つの clone 済みリポジトリから両方の方法を提供しています。その場合、2 つの手順は別々の更新方法です。self-hosted openGym ワークアウトトラッカーは、固定した checkout を build するために docker compose up -d --build を使用します。latest のイメージを pull すると、その checkout より新しい release が実行される可能性があるためです。

実行中の状態を確認する

docker compose ps
docker compose ps -a
docker compose logs -f --tail=100
docker compose logs --since 15m --timestamps db
docker compose top
docker compose ls

ps は、実行中のコンテナだけを一覧表示します。起動中にクラッシュしたサービスは、-a を追加するまでここには表示されません。そのため、ps には表示されない一方で、ps -a では Exited (1) と表示されるコンテナがある場合、これは通常の起動失敗の状態です。終了コードを確認してから、ログを確認します。

logs -f は、すべてのサービスを同時に追跡し、各行の先頭にサービス名を付けます。サービス間の通信やイベントの順序を確認したい場合に適した表示です。サービス名を指定すると対象を絞り込めます。1 か月間稼働しているコンテナでは --tail=100 が重要です。デフォルトでは履歴全体を表示するため、端末が大量のログで埋まるからです。--since 15m を使うと、通常確認したい内容、つまり直前に実行した再起動中に何が起きたかを確認できます。

top は各コンテナ内のプロセスを一覧表示します。これにより、「コンテナは実行中」と「コンテナ内のプロセスは実行中」を区別できます。ls は現在のディレクトリから離れ、ホスト上で実行中の Compose プロジェクトとその状態を一覧表示します。停止したプロジェクトも含めるには -a を追加します。

サービス内でシェルを起動する

docker compose exec web sh
docker compose exec -u root web sh
docker compose run --rm web env
docker compose run --rm --no-deps web sh

execは、すでに起動しているコンテナ内でコマンドを実行します。runは、同じサービス定義から新しいコンテナを起動します。これは、サービスが起動したままにならず、exec を実行する前に終了してしまう場合に必要です。runは必ず--rmと組み合わせてください。これを付けないと、実行するたびに停止済みコンテナが残り、数が増えてdocker compose ps -aが読みづらくなります。

bashを実行する前に、shを試してください。Alpine ベースのイメージにはbashが含まれている場合があります。公式の PostgreSQL Alpine イメージもその 1 つです。存在しない場合は、exec: "bash": executable file not found in $PATHというエラーになります。runに--no-depsを追加すると、サービスの依存関係を無視できます。これにより、簡単な設定確認のためにデータベース全体が起動するのを防げます。

run --rm web envを使うと、すべての.envファイル、environment:ブロック、シェル変数がマージされた後に、サービスが実際に受け取った環境を最も速く確認できます。値が誤っている場合は、通常、マージ順序が原因です。Compose が env ファイルと Secret を解決する方法では、どのソースが優先されるかを説明しています。

ネットワーク、ポート、名前解決

docker compose port web 80
docker compose exec web getent hosts db
docker compose config --networks

デフォルトでは、Compose はすべてのサービスを 1 つのプロジェクトネットワークに配置し、各サービス名をそのネットワーク上の DNS 名として扱います。イメージに getent が含まれている場合、web 内で getent hosts db を実行すると名前解決を確認できます。ただし、db が接続を受け付けるかどうかは確認できません。名前解決はできても接続が拒否される場合は、サーバーが起動しており、要求されたアドレスとポートで待ち受けていることを確認してください。127.0.0.1 のみにバインドしていることが原因の 1 つになる場合があります。同じ境界のため、プロジェクト外で docker run によって起動したコンテナや独自のスタックとして起動したコンテナから、jellyfin のようなサービス名を解決するには共有ネットワークが必要です。Jellyfin ライブラリ用の Halcyon フロントエンドが指定先のサーバーに接続できない場合は、まずここを確認してください。このモデルの詳細は、Compose のネットワークとサービス DNS の仕組みで説明しています。

port web 80 を実行すると、コンテナポートが公開されているホストアドレスとポートが表示されます。マッピングが変数から設定されている場合でも、推測する必要がありません。ポートを公開すると、Docker が管理するファイアウォールルールも作成されます。このルールはユーザー自身のルールより先に適用されるため、非公開だと思っていたサービスがインターネットに公開される可能性があります。このケースについては、公開された Docker ポートが ufw を迂回する理由で説明しています。これらのポートを公開せず、プロジェクトネットワーク上に認証プロキシを 1 つ配置してサービスの前段に置く方が安全です。Authentik をシングルサインオン層として実行するでは、この構成を実現できます。

ボリュームとデータ

docker compose config --volumes
docker compose cp db:/etc/postgresql/pg_hba.conf ./pg_hba.conf
docker compose down -v

config --volumes は、プロジェクトで宣言された名前付きボリュームを 1 行に 1 つずつ表示します。この一覧はバックアップ対象の一部にすぎません。bind mount と設定ファイルも確認する必要があります。ボリュームに代替できないデータが保存されている場合は、正確なバックアップコマンドが一覧と同じくらい重要です。そのため、PhotoPrism と Immich の比較では、各フォトサーバーに必要なダンプおよびコピーのコマンドを具体的に示しています。cp はシェルを開かずにコンテナとの間でファイルをコピーします。コンテナ側には service:path 形式を使用します。

down -v は、外部ボリュームを除く宣言済みの名前付きボリュームと、コンテナに接続された匿名ボリュームを、コンテナとともに削除します。テスト用のスタックを破棄する場合には適切なコマンドですが、必要なデータを保持している環境では使用してはいけません。確認プロンプトは表示されず、元に戻すこともできないためです。bind mount はホストのファイルシステム上に存在するため、この操作の影響を受けません。この影響範囲の違いが、bind mount と名前付きボリュームを意図的に使い分ける理由の 1 つです。

データを失わずにディスク領域を解放するクリーンアップ

docker compose down --remove-orphans
docker system df
docker image prune -a
docker builder prune

--remove-orphans は、プロジェクトに属しているものの、ファイルに存在しなくなったコンテナを削除します。これは、サービス名を変更した後に発生する状態と同じです。これを実行しないと、そのコンテナは動作し続けます。また、docker compose ps はデフォルトで実行中の孤立コンテナも対象にします。

docker system df は、削除する前にディスク領域の使用状況を表示します。イメージ、コンテナ、local volume、build cache を分けて表示し、それぞれについて解放可能な容量も示します。image prune -a は、どのコンテナからも使用されていないイメージを、タグの有無にかかわらずすべて削除します。大容量イメージの複数のバージョンを取得したサーバーでは、通常これが最も大きな効果を得られます。builder prune はデフォルトで dangling build cache を削除します。未使用の build cache をすべて削除するには、-a を追加します。

これらのコマンドは、いずれも named volume には影響しません。docker volume prune --all、docker compose down -v、docker volume rm は named volume を削除します。単独の docker volume prune は anonymous volume のみを削除します。

変更による影響が出る前にファイルを確認する

docker compose config --quiet
docker compose config --services
docker compose --dry-run up -d

config --quiet は成功時に何も出力せずに検証するため、デプロイ前の手順や git hook に組み込めます。単独の config は、変数の展開と上書きファイルの適用が想定どおりか確認できるよう、マージと補間が完了したファイルを出力します。未設定の変数は、警告 The "X" variable is not set. Defaulting to a blank string. とともに空の値として表示されます。

--dry-run はサブコマンドのフラグではなくグローバルフラグであるため、up より前に指定します。Compose が実行するすべての操作を表示し、状態は変更しません。重要なスタックで down を実行する前に、この 30 秒の確認を行う価値があります。

ファイル、プロファイル、プロジェクトをまたいだ運用

docker compose -f compose.yaml -f compose.prod.yaml up -d
docker compose --profile debug up -d
docker compose -p staging up -d

複数の -f フラグは指定順にマージされ、後のファイルがキー単位で前のファイルを上書きします。これは、1 つのベースファイルに小規模な本番用上書きを組み合わせる標準的な方法です。ただし、リストとマップではルールが異なるため、予期しない結果を調査する前に Compose が複数のファイルをマージする方法 を確認してください。

--profile は、そのプロファイルが付いたサービスを、プロファイルの付いていないサービスとともに起動します。これにより、通常の up にデバッグ用ツールが含まれなくなります。-p はプロジェクト名を設定するため、1 つのスタックを 2 つ並行して実行し、それぞれに別のネットワーク名とボリューム名を割り当てられます。再起動後にスタックを復旧するには、restart policy または Compose を実行する unit を使用します。詳細は 起動時に Compose スタックを開始する方法 を参照してください。

FAQ

ハイフン付きの docker-compose に置き換わったものは何ですか?

スペースで区切って docker compose として実行する Compose V2 と V5 です。Linux では Compose は別途インストールするプラグインです。Ubuntu 24.04 LTS では、universe リポジトリに V1 の Python ツールが現在も用意されています。スペース形式を利用できない場合は、Docker のリポジトリを設定して docker-compose-plugin パッケージをインストールします。V2 には V1 に存在しなかったフラグがあるため、エイリアスを追加するのではなく、古いスクリプトをスペース形式へ更新してください。

docker compose restart で設定変更が反映されないのはなぜですか?

restart は、既存のコンテナを作成時の設定で停止・起動するだけで、compose.yaml を再読み込みしません。環境変数、ポート、ボリューム、イメージタグを変更した場合は docker compose up -d が必要です。これは各サービスを実行中のコンテナと比較し、差異があるコンテナを再作成します。ファイルの内容に変更がない場合でも置き換えるには --force-recreate を追加します。

サービスを新しいイメージに更新するにはどうすればよいですか?

docker compose pull を実行し、続いて docker compose up -d を実行します。pull により、ファイル内の各タグに対応する最新のイメージが取得されます。up -d は、イメージ ID がコンテナと一致しなくなったサービスを再作成します。up -d だけを実行した場合は、pull ポリシーに従います。デフォルトの missing ポリシーでは、latest を除き、キャッシュ済みのイメージが再利用されます。latest は常に pull されます。

稼働中のサーバーで安全に実行できるクリーンアップコマンドはどれですか?

docker system df は削除を行わずにディスク使用量を表示します。docker image prune -a と docker builder prune は未使用のイメージとビルドキャッシュを削除するため、稼働中のサービスは影響を受けず、名前付きボリュームも変更されません。危険な組み合わせは docker compose down -v です。これはプロジェクトで宣言された外部ボリュームではない名前付きボリュームと、接続された匿名ボリュームを確認なしで削除します。docker volume prune --all は未使用のローカルボリュームを削除します。名前付きボリュームも対象で、通常は 1 回の y/N プロンプトが表示されますが、-f を指定するとプロンプトも表示されません。まず docker compose config --volumes を実行して、削除対象を確認してください。

スタック全体を起動せずに 1 つのコマンドを実行できますか?

はい。docker compose run --rm --no-deps web sh は web のサービス定義から単一のコンテナを起動し、依存関係を無視して、終了時にコンテナを削除します。コンテナがすでに実行中の場合は exec を使用してください。exec は稼働中のコンテナ内でコマンドを実行するため、サービスの実際の状態を確認できます。

この記事は役に立ちましたか?