エラーの内容
ディスク容量を確保するために docker rmi <image> を実行すると、Dockerが次のエラーを返します:
Error response from daemon: conflict: unable to delete a1b2c3d4e5f6 (must be forced) - image is being used by stopped container 9f8e7d6c5b4a
コンテナは停止中(実行中ではない)にもかかわらず、Dockerは削除を拒否します。これは多くの人を混乱させます。停止中のコンテナはリソースを保持しないという思い込みがありますが、実際には保持しています。停止中のコンテナは、明示的に削除するまでディスク上にレイヤー参照を保持し続けます。
なぜこうなるのか
Dockerイメージは読み取り専用のレイヤーのスタックです。イメージからコンテナを起動すると、Dockerはその上に薄い書き込み可能なレイヤーを追加します。コンテナを停止しても、そのレイヤーと元のイメージへの参照は、docker rm を実行するまでディスク上に残り続けます。
依存関係のチェーンはシンプルです:イメージ → コンテナ(停止中)。Dockerは、たとえ停止中であっても、コンテナが使用しているイメージを削除しません。これは、参照先のない宙ぶらりんの書き込み可能レイヤーが残るのを防ぐための保護機能です。
クイック修正:先にブロックしているコンテナを削除する
イメージを保持しているコンテナを探します:
docker ps -a --filter ancestor=<image_name_or_id> --format "table {{.ID}}\t{{.Names}}\t{{.Status}}"
またはエラーメッセージに記載されているコンテナIDを直接確認します:
docker inspect 9f8e7d6c5b4a --format '{{.Name}} — {{.State.Status}}'
削除しても安全であることを確認したら:
docker rm 9f8e7d6c5b4a
docker rmi <image_name_or_id>
完了です。コンテナを削除すると参照が解放され、rmi がスムーズに実行されます。
停止中のコンテナが多数ある場合
ビルドを繰り返したりCIパイプラインを実行したりした後、docker ps -a には50〜100個の停止中コンテナがリストされ、それぞれが元のイメージへの参照を保持していることがあります。1つずつ削除するのは現実的ではありません。一度にすべて削除しましょう:
# 停止中のコンテナをすべて削除
docker container prune
# 確認プロンプトをスキップ
docker container prune -f
その後、イメージの削除を再試行します:
docker rmi <image_name_or_id>
強制削除という選択肢
-f オプションで2ステップの手順を省略できます:
docker rmi -f <image_name_or_id>
**-f が実際に行うこと:**イメージのタグを外して削除しますが、停止中のコンテナの書き込み可能レイヤーは壊れた参照として残り続けます。そのコンテナは docker ps -a に引き続き表示され、存在しないイメージを参照した状態になります。このゴーストエントリは後々混乱を招く可能性があります。強制削除は完全な環境リセット時のみ使用し、通常のクリーンアップには2ステップの方法を使いましょう。
システム全体のクリーンアップ
未使用のリソースをまとめて削除したい場合、docker system prune で停止中のコンテナ、宙ぶらりんのイメージ、未使用のネットワーク、ビルドキャッシュをまとめて処理できます:
# 安全:未使用・宙ぶらりんのリソースのみ削除
docker system prune
# 積極的:実行中のコンテナが使用していないイメージも削除
docker system prune -a
# 確認をスキップ
docker system prune -a -f
-a の使用には注意が必要です。node:20-alpine や python:3.12-slim など、ダウンロードに時間がかかったベースイメージのキャッシュも削除されます。次のビルド時に再ダウンロードが必要になります。-a は完全にクリーンな状態から始めたい場合にのみ使用してください。
コンポーネント別の対象クリーンアップ
# 停止中のコンテナをすべて削除
docker container prune -f
# 宙ぶらりんのイメージを削除(タグなし、<none>:<none>)
docker image prune
# 未使用のイメージをすべて削除
docker image prune -a
# 未使用のボリュームを削除
docker volume prune -f
# 未使用のネットワークを削除
docker network prune -f
修正の確認
コンテナとイメージが実際に削除されたことを確認します:
# 何も返らないはず
docker ps -a | grep 9f8e7d6c5b4a
# 何も返らないはず
docker images | grep <image_name>
# 残っている宙ぶらりんのイメージを確認
docker images -f dangling=true
最後のコマンドで <none>:<none> エントリが表示された場合は、クリーンアップします:
docker image prune -f
このエラーを繰り返さないために
以下の習慣をワークフローに取り入れることで、このエラーに悩まされることはほぼなくなります:
- 使い捨てのコンテナには
--rmを使用する — 終了時に自動削除されます:docker run --rm myimage - CIパイプラインでは、ジョブ終了前のポストビルドステップとして
docker system prune -fを追加する - Composeプロジェクトのシャットダウンには、単純な
docker compose downではなくdocker compose down --rmi allを使用する — コンテナとイメージを1つのコマンドで削除できます - 長期稼働するビルドサーバーでは、cronで週次の
docker system prune -a -fをスケジュールする。放置すると、Dockerは1ヶ月で20〜40 GBのディスクを消費することがあります
まとめ
image is being used by stopped container は、コンテナのレコードがディスク上に残存し、そのイメージへの参照を保持していることを意味します。解決策は docker rm <container_id> を実行してから docker rmi <image> を実行することです。大量のコンテナをまとめてクリーンアップするには、docker container prune の後に docker image prune を実行すれば、2つのコマンドで完了します。

