127レイヤーの壁複雑な Docker イメージの構築を進めていると、数十のステップを順調に通過したところで、突然プロセスが停止し、次のようなイライラさせるエラーが発生することがあります。
failed to register layer: max depth exceeded
Docker にはイメージに含めることができるレイヤー数に厳しい制限があります。標準的な overlay2 ストレージドライバの場合、その制限はちょうど 127レイヤー です。Dockerfile の命令とベースイメージから継承されたレイヤーの合計がこの数を超えると、ビルドは必ず失敗します。
TL;DR: クイックフィックス- コマンドを連結する: && と \ を使用して、複数の RUN 命令を1つにまとめます。- マルチステージビルドを採用する: 最終的なバイナリのみを新しいステージにコピーし、レイヤーカウンターをゼロにリセットします。- ベースイメージを確認する: node:18 のような重いベースイメージは、最初の1行を書く前ですでに15以上のレイヤーを使用している場合があります。## 内部で何が起きているのか?Docker イメージをパンケーキの積み重ねのように考えてみてください。RUN、COPY、ADD 命令を実行するたびに、新しいパンケーキ(読み取り専用レイヤー)がスタックに追加されます。このアーキテクチャによりキャッシュ効率は非常に高くなりますが、ストレージドライバには構造上の制限があります。レイヤーを重ねすぎると、ファイルシステムのルックアップ性能や安定性が低下し始めます。
通常、Dockerfile を自動生成するツールを使用したり、ファイルを綺麗に見せるためにすべてのコマンドを個別の行に記述して「モジュール化」しすぎたりすると、この壁に突き当たります。
エラーの解決方法### 1. RUN命令を連結するこれはイメージをスリム化する最も効果的な方法です。各 RUN 命令はレイヤーを作成します。これらを組み合わせることで、4つや5つのレイヤーを1つにまとめることができます。
肥大化した書き方(4つのレイヤーを作成):
RUN apt-get update
RUN apt-get install -y python3
RUN apt-get install -y pip
RUN rm -rf /var/lib/apt/lists/*
最適化された書き方(1つのレイヤーを作成):
RUN apt-get update && apt-get install -y \
python3 \
pip && \
rm -rf /var/lib/apt/lists/*
2. マルチステージビルドを使用する本番環境のイメージに gcc、make、そして node_modules フォルダ全体が本当に必要でしょうか? おそらく不要です。マルチステージビルドを使用すると、アプリのコンパイルに100レイヤー費やしたとしても、その結果だけを新しい小さなイメージに COPY することができます。
# ステージ 1: ビルド(ここではレイヤー数は問題になりません)
FROM node:18 AS builder
WORKDIR /app
COPY . .
RUN npm install && npm run build
# ステージ 2: 最終成果物(2〜3レイヤーのみ)
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
3. 乱雑なイメージをフラット化するすでに120レイヤーに達している「ブラックボックス」なイメージを引き継ぐことがあります。Dockerfile を書き直せない場合は、export と import を使用してイメージ全体を1つのレイヤーにフラット化できます。ただし、ENV や ENTRYPOINT などのメタデータが消去されるため、再設定が必要になることに注意してください。
# 一時コンテナを作成
docker create --name temp-container my-bloated-image
# 1つのレイヤーにフラット化
docker export temp-container | docker import - my-flattened-image
# クリーンアップ
docker rm temp-container
4. --squash フラグ(試験運用機能)Docker デーモンで試験運用機能(experimental features)が有効になっている場合、ビルド時に --squash フラグを使用できます。これにより、最終的にすべての新しいレイヤーが1つにまとめられます。
docker build --squash -t my-image .
検証:レイヤー数をカウントする制限にどれくらい近づいているかを確認するには、docker history コマンドを使用します。イメージ内のすべてのレイヤーが上から順に表示されます。
docker history my-image-name
出力の行数を数えてみてください。100行を超えている場合はリファクタリングの時期です。より視覚的なアプローチとしては、Dive を試してみてください。これは、各レイヤーを探索して、どのファイルが容量を増やしているかを正確に確認できる人気のオープンソースツールです。

