docker compose downとstopの違いは?
docker compose stopはコンテナを残して停止し、downはコンテナとネットワークを削除します。named volumeはどちらも削除せず、データ消去は--volumes指定時だけです。
簡潔な答え
docker compose stop はコンテナを停止し、ディスク上に残します。docker compose down はコンテナを停止した後、コンテナとプロジェクト用に Compose が作成したネットワークを削除します。どちらのコマンドも named volume には影響しません。データベースが削除されるのは -v を追加した場合だけです。たとえば docker compose down -v は、Compose ファイルの volumes セクションで宣言された named volume を削除します。
違いはこれだけです。このガイドの残りでは、down の後も存続し、down -v で削除される Postgres volume を確認して説明します。また、--force-recreate が必要になる2つのケースも説明します。
docker compose stop: コンテナが停止後も残る
stop は各コンテナのメインプロセスに SIGTERM を送信して待機し、プロセスがまだ実行中の場合は SIGKILL を送信します。デフォルトの待機時間は 10 秒で、-t で変更できます。コンテナは削除されません。コンテナ ID、書き込み可能レイヤー、IP 予約、ログは保持されます。
docker compose stop
docker compose ps -adocker compose ps は実行中のコンテナだけを表示します。そのため、stop の実行後は空の表が表示され、コンテナが削除されたと誤解されます。ps -a は停止済みのコンテナも含めます。各サービスの横に Exited (0) が表示されます。docker compose start で再起動すると、まったく同じコンテナが再利用されます。
コンテナはまだ存在するため、ボリューム以外の場所に書き込まれたデータも残ります。これには、docker compose exec で手動インストールしたパッケージや、コンテナ内で編集した設定ファイルが含まれます。デバッグ中に stop を優先する実用的な理由はここにあります。同じ状態で再起動できるためです。
docker compose down: コンテナとネットワークが削除されます
down はコンテナを停止し、その後、コンテナとプロジェクト用に Compose が作成したデフォルトネットワークを削除します。Docker のドキュメントでは、up が作成したコンテナ、ネットワーク、ボリューム、イメージを停止・削除すると説明されています。ただし、ボリュームとイメージの削除は、-v と --rmi を指定した場合にのみ実行されます。
docker compose down
docker compose ps -a
docker network lsdown の実行後、ps -a はプロジェクトのコンテナを表示せず、<project>_default ネットワークも削除されています。プロジェクト名は、Compose ファイルで name: を設定するか、-p を指定しない限り、ディレクトリ名から決まります。コンテナの書き込み可能レイヤー内で行った変更は復元できなくなります。そのため、down はコンテナを破棄し、ボリュームに保存したデータは保持するコマンドとして扱ってください。
誤ったディレクトリで実行すると、no configuration file provided: not found が表示されます。Compose は対象のプロジェクトを特定できないため、実行を拒否します。プロジェクトのディレクトリにいない場合は、docker compose -f /srv/myapp/compose.yaml down を使用してください。
docker compose down でボリュームは削除されますか?
いいえ。トップレベルの volumes キーで宣言した名前付きボリュームは、down より長く存続し、アタッチされていたコンテナが削除された後も残ります。これは、このコマンドについて最もよくある懸念です。Compose v2 でも答えは変わりません。
検証用のスタックを用意します。空のディレクトリ voltest に compose.yaml として次の内容を保存します。
services:
db:
image: postgres:16.4
restart: unless-stopped
environment:
POSTGRES_PASSWORD: example
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:起動し、後で識別できる行を書き込みます。
docker compose up -d
sleep 10
docker compose exec -T db psql -U postgres -c "create table marker (note text);"
docker compose exec -T db psql -U postgres -c "insert into marker values ('survived');"次にコンテナを削除し、ボリュームを確認します。
docker compose down
docker volume ls出力には voltest_pgdata が引き続き表示されます。コンテナは削除されましたが、データは残っています。スタックを再起動し、行を読み取ります。
docker compose up -d
sleep 10
docker compose exec -T db psql -U postgres -c "select * from marker;"survived を含む1行が表示されます。新しいコンテナは、異なるIDを持つ別のコンテナですが、同じボリュームにアタッチされています。全体像を確認するには、Composeの基本ガイドで、名前付きボリュームとbind mountの違い、およびそれぞれがホスト上のどこに存在するかを説明しています。
down -vが正確に削除するもの
-v(長形式は--volumes)は、Composeファイルのvolumesセクションで宣言された名前付きボリュームと、コンテナに接続された匿名ボリュームを削除します。同じスタックに対して実行してください。
docker compose down -v
docker volume lsvoltest_pgdataは一覧に表示されなくなります。スタックを再び起動すると、Postgresのエントリポイントは空のデータディレクトリを検出し、新しいクラスターを初期化します。コンテナログにもその内容が明記されます。
The files belonging to this database system will be owned by user "postgres".
PostgreSQL init process complete; ready for start up.数か月稼働しているスタックでこのブロックが表示された場合、ボリュームは削除されています。markerテーブルは失われており、復旧する方法はバックアップだけです。
-vでは削除されないストレージもあります。bind mountはホストパスなので、Dockerはアンマウントするだけで、ファイルはその場所に残ります。external: trueとマークされたボリュームは、このプロジェクトの外部にあるものとして宣言されているため、Composeは削除しません。down -vを実行する前にComposeファイルから削除した名前付きボリュームは、すでに宣言されていないため、Composeは削除対象として認識できず、docker volume pruneの孤立リソースとして残ります。
この最後のケースは、リファクタリング中に問題になります。サービスとそのボリュームをファイルから削除してからdown -vを実行すると、ファイルに記載されていないため、ボリュームは残ります。ファイルを編集する前にdown -vを実行してください。編集した後ではありません。
--force-recreate が実際に必要な場合
docker compose up -d は毎回すべてを再構築するわけではありません。Compose は各サービスの解決済み設定のハッシュを、ラベルとしてコンテナに保存します。ハッシュとイメージ ID が一致している場合、コンテナはそのまま維持され、Recreated ではなく Container voltest-db-1 Running になります。これが通常ほぼ常に望ましい動作です。up -d を繰り返し安全に実行できるためです。
このため、一部の編集が何も変更しないように見えることもあります。Compose がハッシュ化するのは、定義が参照するファイルの内容ではなく、解決済みのサービス定義です。コンテナにマウントされ、起動時に一度だけ読み込まれる設定ファイルを編集しても、マウントパスは変わらないため、再作成は発生しません。サービスは起動時に読み込んだ値のまま実行されます。
docker compose up -d --force-recreate各コンテナを停止して削除し、同じ定義から新しいコンテナを作成します。マウントした設定ファイルを編集した後や、コンテナの状態が原因不明の状態になった場合に使用します。ボリュームには影響しないため、force recreate を実行してもデータベースは保持されます。同じタグの新しいイメージを取得するには、pull も必要です。
docker compose pull
docker compose up -dpull は新しいイメージ ID を取得します。その後、up -d が実行中のコンテナと異なるイメージ ID を検出し、自動的に再作成します。pull なしで --force-recreate を追加すると、同じ古いイメージから新しいコンテナが作成されます。そのため、「force recreate を実行したのにまだ古いバージョンのままだ」という問題がよく発生します。
docker compose restart はこれらの処理を行いません。既存のコンテナを再起動するだけで、Compose ファイルを再読み込みしません。そのため、変更した環境変数やポートマッピングは反映されません。ファイルを編集した場合は、up -d を使用してください。
維持すべきメンタルモデル
コンテナは交換可能です。コンテナはプロセスと薄い書き込み可能レイヤーで構成され、Compose はファイルから約1秒で同一のコンテナを構築できます。ボリュームは交換できません。リポジトリ内のどのファイルからも再生成できない状態の唯一のコピーを保持しているためです。
Compose の各操作は、この分離に対応しています。stop と start はコンテナを維持します。down と up はコンテナを交換し、ボリュームを維持します。down -v は状態を削除する唯一の通常のコマンドです。そのため、明示的なフラグが必要です。実環境で実行する前に、バックアップがあり、少なくとも1回は復元済みであることを確認してください。
同じ考え方はシークレットにも適用されます。POSTGRES_PASSWORD で設定したパスワードは、データベースの初期化時に1回だけ読み取られます。そのため、環境ファイルでパスワードを変更して up -d を実行すると、password authentication failed for user "postgres" になります。コンテナは新しくなりますが、ボリュームは古いままです。古いボリュームには、引き続き古いパスワードが保存されています。Compose が env ファイルとシークレットを解決する方法では、同じ変数が2回設定された場合に、どのレイヤーが優先されるかを説明しています。
障害の種類と表示される文字列
no configuration file provided: not found は、Compose が compose.yaml も docker-compose.yml もないディレクトリで実行されていることを示します。完全なパスを指定して -f を渡してください。
down で network voltest_default has active endpoints が表示される場合、このプロジェクト外のコンテナがプロジェクトのネットワークに接続されています。通常は docker run --network で手動起動したコンテナです。そのコンテナを削除してから、もう一度 down を実行してください。
Found orphan containers ([voltest-old-1]) for this project は、サービスの名前を変更または削除した後に表示されます。古いコンテナには、まだプロジェクトラベルが付いています。docker compose down --remove-orphans でそのコンテナを削除できます。正常なスタックに対して実行しても安全です。
手動で docker volume rm を実行したときに Error response from daemon: remove voltest_pgdata: volume is in use が表示される場合、停止中のものを含め、いずれかのコンテナがそのボリュームを参照しています。まず docker compose down を実行してからボリュームを削除するか、down -v を使用してください。規模の大きいプロジェクトでは、複数サービスの Compose スタックを使うと、1つのプロジェクトで蓄積するボリューム数を確認できます。
FAQ
docker compose down を実行するとデータベースは削除されますか?
データベースが名前付きボリュームまたは bind mount に保存されている場合は削除されません。down はコンテナとプロジェクトネットワークを削除しますが、ボリュームはデータを保持したままディスクに残ります。次の docker compose up -d は同じボリュームを新しいコンテナに接続するため、データを引き続き利用できます。名前付きボリュームを削除するのは docker compose down -v だけです。対象になるのは、Compose ファイルの volumes セクションで宣言されたボリュームだけです。
再起動するコンテナでは、stop と down にどのような違いがありますか?
stop はコンテナを保持するため、docker compose start を実行すると同じ書き込みレイヤーを持つ同じコンテナに戻ります。コンテナ内で手動でインストールまたは編集した内容も残ります。down はコンテナを削除するため、次の up -d はイメージから新しいコンテナを作成し、手動で行った変更は失われます。デバッグ中は stop を使用してください。
Compose プロジェクトが作成したすべてのものを削除するにはどうすればよいですか?
docker compose down -v --rmi all --remove-orphans は、コンテナ、プロジェクトネットワーク、ファイルで宣言された名前付きボリューム、サービスが使用したイメージ、およびプロジェクト名のラベルが付いたコンテナを削除します。bind mount や external: true とマークされたボリュームには影響しません。実行前に docker volume ls で削除対象を確認してください。
マウントした設定ファイルを変更したのに、コンテナが変更を無視するのはなぜですか?
Compose は、解決済みサービス定義のハッシュを比較してコンテナを再作成するかどうかを判断します。このハッシュには、マウントしたファイルの内容は含まれません。パスが変わっていないため、Compose はコンテナを実行したままにし、起動時に読み込んだ値を使い続けます。docker compose up -d --force-recreate を実行すると、ファイルを再読み込みする新しいコンテナを作成できます。
変更した新しい POSTGRES_PASSWORD が機能しないのはなぜですか?
Postgres イメージは、空のデータディレクトリを初期化するときにのみ POSTGRES_PASSWORD を読み取ります。ボリュームにはすでに初期化済みのクラスタがあるため、この変数は無視され、古いパスワードが引き続き適用されます。password authentication failed for user "postgres" が表示されます。実行中のデータベース内で ALTER USER を使用してパスワードを変更してください。データの消失を受け入れて最初からやり直す場合は、docker compose down -v を使用します。