冒頭まとめ
no space left on device は Docker が判定した結果ではありません。書き込みを試みた先のファイルシステムが返した結果を、そのまま表示したものです。
したがって最初にやるべきことは、対処ではなくどこが満杯なのかの確定です。候補は3つあります。
1つ目はホスト上のデータ保存先です。既定では /var/lib/docker で、イメージ、コンテナ、ボリューム、構築のキャッシュ、そしてログがすべてここに集まります。
2つ目は Docker Desktop の仮想ディスクです。この場合、ホストのディスクに空きがあっても関係ありません。上限は設定で決まっており、その中が満杯になれば同じエラーになります。
3つ目はコンテナの中です。共有メモリ用の領域は既定で 64MiB しかなく、これを超える書き込みでも同じ文言が出ます。
そしてもう1つ、見落とされやすい前提があります。Docker には自動的に減る仕組みがほとんどありません。公式文書によれば、ログの上限は既定で無制限、ボリュームはデータ破壊を避けるため自動削除されません。放置すれば埋まるのは仕様どおりの挙動です。
エラーの概要
文言は操作によって前後が変わりますが、末尾は共通です。
# 構築時
ERROR: failed to solve: failed to create temp dir:
mkdir /var/lib/docker/tmp/buildkit-mount123: no space left on device
# 起動時
docker: Error response from daemon:
mkdir /var/lib/docker/tmp/docker-builder553623694: no space left on device
読むべきはどの経路への書き込みで失敗したかです。/var/lib/docker 配下ならホストのデータ保存先、コンテナ内の経路ならコンテナ側の問題です。
使用量の全体像は専用のコマンドで確認できます。
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 15 3 21.71GB 18.17GB (83%)
Containers 7 0 5.417kB 5.417kB (100%)
Local Volumes 3 0 90.72MB 90.72MB (100%)
Build Cache 295 0 20.77GB 20.77GB
RECLAIMABLE の欄が、整理によって取り戻せる量です。どの種類が大きいかで、次にやることが決まります。
まず最初に:どこが満杯かを確定する
第一に、使用量の内訳を見ます。docker system df で、どの種類が占めているかが分かります。
第二に、データ保存先の空き容量を確認します。既定は /var/lib/docker ですが、設定で変更できるため、実際の場所を確認してから測ってください。
第三に、ファイル数の上限も確認します。容量に空きがあっても、ファイルの管理情報を使い切れば同じエラーになります。df -h では見えません。
第四に、Docker Desktop を使っているかを確認します。使っている場合、見るべきはホストのディスクではなく仮想ディスクの側です。
よくある原因と解決手順
原因1:ログが回っていない
最も静かに進行する形です。公式のリファレンスによれば、既定のログの記録方式では、1ファイルあたりの上限は -1、つまり無制限です。世代数の指定も、上限を設定している場合にのみ効く、と明記されています。
つまり、既定のままではログは永久に増え続けます。長期間動くコンテナほど危険です。
Before(既定のまま動かす):
docker run -d myapp
# → ログが上限なく増え続ける
After(回転を設定する):
// /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": { "max-size": "10m", "max-file": "3" }
}
注意点が1つあります。この設定は新しく作られるコンテナにのみ適用されます。既存のコンテナは作り直さない限り、以前のままです。
緊急時は、ログファイルの中身だけを空にすれば容量を戻せます。削除ではなく切り詰めにするのは、ファイルを開いたままのプロセスがあるためです。
原因2:イメージ・コンテナ・構築キャッシュの堆積
docker system df で Images や Build Cache が大きい場合です。整理のコマンドがありますが、何が消えるかを正確に知ってから使ってください。
公式文書によれば、まとめて整理するコマンドが消すのは、停止中のコンテナ、使われていないネットワーク、参照されていないイメージ、使われていない構築キャッシュです。
# 対象を確認してから実行する
docker system prune
# 使用中のコンテナが無いイメージもすべて消す(影響が大きい)
docker system prune -a
ボリュームは既定では消えません。公式文書に理由まで書かれており、データを破壊する恐れがあるため自動的には削除しない、という方針です。消す場合は明示的な指定が要ります。裏を返せば、ボリュームは意識して消さない限り永久に残ります。
構築のキャッシュについては、公式に自動整理の方針が説明されています。おおよその内容は、容易に再生成できるキャッシュを48時間、使われていないキャッシュを60日、そして上限を超えた分を削除する、というものです。自動整理はありますが、上限に達するまでは減りません。継続的な構築を回している環境では、上限そのものを見直してください。
原因3:容量ではなくファイル数の枯渇
df -h では空きがあるのに同じエラーが出る場合です。ファイルシステムが管理できるファイルの数を使い切っています。
# 容量ではなくファイル数の使用率を見る
df -i /var/lib/docker
IUse% が 100% に近ければ、この形です。イメージの層は小さなファイルの集合体なので、イメージが多い環境で起きやすくなります。
対処は容量の場合と同じで、不要なイメージを減らすことです。ただし、容量だけを見て「まだ空いている」と判断すると原因に辿り着けません。両方を確認してください。
原因4:Docker Desktop の仮想ディスクが上限に達している
Docker Desktop では、コンテナとイメージは専用の仮想ディスクに保存されます。公式の設定項目にも、使用できるディスク量の上限と、その保存場所を指定する項目が用意されています。
この場合、ホスト側で空き容量を測っても意味がありません。上限はホストの空き容量とは独立して決まっているためです。
対処は2つです。設定で上限を引き上げるか、中身を整理することです。整理を先に試すのが安全ですが、上限そのものが小さければ根本的には解決しません。
なお、整理しても仮想ディスクのファイル自体は自動的には小さくなりません。中の空きは戻っていても、外から見たファイルの大きさは変わらないことがあります。外側の大きさだけを見て「減っていない」と判断しないでください。
原因5:コンテナ内の共有メモリや一時領域
コンテナの中で動くプログラムが出す場合です。公式のリファレンスによれば、共有メモリ用の領域の既定は 64MiB です。
この領域を多く使うソフトウェアでは、ホストのディスクに十分な空きがあっても不足します。データベースやブラウザをコンテナで動かす場合に遭遇しやすい形です。
# 起動時に共有メモリの大きさを指定する
docker run --shm-size=1g myapp
コンテナの中で df -h を実行し、どの経路が満杯かを確認すれば、ホスト側の問題と区別できます。
補足:似ているが別のもの
同じ文言でも、原因が容量ではない場合があります。書き込もうとした場所が存在しない、あるいは書き込みの許可が無い場合にも、似た形のエラーとして現れることが報告されています。整理しても改善せず、使用量にも余裕がある場合は、経路と権限を疑ってください。
構築の途中で失敗する場合、経路が /var/lib/docker/tmp 配下であればホスト側、コンテナ内の経路であれば構築中の処理そのものが原因です。文言に含まれる経路で切り分けられます。
データ保存先そのものを移す方法もあります。設定で保存先を変更すれば、容量の大きいファイルシステムへ移動できます。ただし移動中は停止が必要で、既存のデータの引っ越しも伴います。
イメージが起動できない場合のエラーは別系統です(Docker の exec format error の記事)。取得の回数制限も別物です(Docker の 429 の記事)。
切り分けの順序
- 文言に含まれる経路を読む。
/var/lib/docker配下か、コンテナ内か。 docker system dfで内訳を見る。どの種類が大きいか。- データ保存先の空き容量を測る。設定で変更されていないか先に確認する。
- ファイル数の使用率も測る。容量に空きがあっても枯渇する。
- Docker Desktop なら、ホストではなく仮想ディスクの上限を見る。
- ログの設定を確認する。既定は無制限で、設定は新しいコンテナにしか効かない。
- 整理は対象を確認してから。ボリュームは明示しない限り消えない。
- 使用量に余裕があるのに直らないなら、経路と権限を疑う。
確認コマンド集
# 1. 使用量の内訳と、取り戻せる量を確認する
docker system df
docker system df -v | head -30
# 2. データ保存先の実際の場所を確認する
docker info --format '{{.DockerRootDir}}'
# 3. 容量とファイル数の両方を測る
df -h "$(docker info --format '{{.DockerRootDir}}')"
df -i "$(docker info --format '{{.DockerRootDir}}')"
# 4. ログファイルの大きさを一覧する(上位10件)
sudo du -sh /var/lib/docker/containers/*/*-json.log 2>/dev/null | sort -rh | head -10
# 5. ログの中身だけを空にする(削除ではなく切り詰め)
sudo truncate -s 0 /var/lib/docker/containers/<ID>/<ID>-json.log
# 6. ログの設定が効いているかをコンテナ単位で確認する
docker inspect <コンテナ> --format '{{.HostConfig.LogConfig}}'
# 7. 構築キャッシュだけを整理する
docker buildx du
docker builder prune
# 8. コンテナの中の空き容量を確認する(共有メモリを含む)
docker exec <コンテナ> df -h
Editor’s Note
このエラーで最も多い遠回りは、整理したのに直らないという状況です。
その典型が記録されています(No space left on device even after system prune -a --force)。2019年2月、まとめて整理するコマンドを強制指定で実行しても、コンテナを起動しようとすると同じエラーが出続ける、という報告です。報告者はイメージの一覧も確認しており、大量に残っているわけではないと述べています。
報告の中で確認されているのが、仮想ディスクのファイルの大きさでした。60GB。整理しても、このファイル自体は小さくならなかったわけです。報告者はこのファイルを削除することで一時的に解決していますが、数回動かすとまた同じ状態に戻る、とも書いています。
ここから読み取れることが2つあります。1つは、ホスト側のディスクを見ても答えは出ないこと。もう1つは、整理の効果と、外から見たファイルの大きさは一致しないことです。「空けたはずなのに変わらない」という感覚は、この構造から来ます。
もう1つ、文言そのものが誤解を招く例もあります(Misleading error about no space left)。構築時に容量不足のエラーが出たものの、実際にはデータ保存先のディレクトリを作って書き込みの許可を与えるだけで解決した、という報告です。容量の話だと書いてあるからといって、容量の問題とは限りません。
このエラーに当たったら、まず内訳を見る。次に、容量とファイル数の両方を測る。そして、Docker Desktop なら見る場所がそもそも違う。整理コマンドを打つのは、そのあとです。
免責事項:本記事の内容は、執筆時点の公開情報をもとに作成したものです。ソフトウェアの仕様は予告なく変更されることがあります。最新の情報は各ツールの公式サポートページをご確認ください。本記事の情報を利用した結果生じたいかなる損害についても、著者および運営者は責任を負いかねます。
この記事でエラーは解決しましたか?