Dockerfile の COPY でファイルが見つからずビルドできない
COPY のソースは Dockerfile があるディレクトリではなく build context 基準で解決される。
.dockerignore で除外されている、または build context 外を指していないか確認する。
公開: 更新:
要約
Dockerfile の COPY は build context (docker build の最後の引数で指定したディレクトリ)の配下しか参照できない。failed to compute cache key: not found や COPY failed: file not found が出るときは、対象ファイルが context 外、もしくは .dockerignore で除外されていることがほとんど。
よくある原因
- build context 外を参照している:
COPY ../shared/lib /app/libのように一つ上の階層を指しているが、docker build .で context をカレントだけに絞っている。 - .dockerignore で除外:
node_modulesを.dockerignoreで無視しているのに、Dockerfile ではCOPY node_modules ./と書いている。 - Dockerfile 相対と勘違い: 「Dockerfile があるディレクトリからの相対パス」と思っているが、実際は build context ルートからの相対。
- 大文字小文字の差: ファイル名
Config.jsonをconfig.jsonで COPY しているが macOS / Windows ではビルドが通り Linux で落ちる、など。
解決策
1. build context を確認する
docker build -f path/to/Dockerfile . の . の部分が context。
BuildKit は最初に context を tar で収集する。
docker build -t myapp -f docker/Dockerfile .context 内に対象ファイルがあるかは次のコマンドで簡易確認できる。
find . -name "needed-file" 2>/dev/null | head公式ドキュメント のとおり、context 外への参照は許されない。
2. .dockerignore を疑う
意図せず除外されていないか調べる。
mv .dockerignore .dockerignore.bak
docker build -t myapp .通れば .dockerignore の特定行が原因。
マッチング書式は .gitignore と同様だが、否定パターンの挙動は微妙に異なるので 1 行ずつ確認する。
3. context を広げて Dockerfile を書き直す
親階層の共通ライブラリを参照したい場合、context をプロジェクトルートに広げて Dockerfile 側のパスを書き直す。
project/
├── docker/Dockerfile
├── shared/lib/
└── app/# docker/Dockerfile
COPY shared/lib /app/lib
COPY app /appビルドは docker build -f docker/Dockerfile .(プロジェクトルートで実行)。
4. 環境差をなくす
CI が Linux のときはローカル macOS と挙動が違う。COPY のパスは小文字で揃え、ファイル名のリネームを Git で確実に追跡する(git mv を使う)。