本記事で説明している親ディレクトリを参照するやり方よりも --build-context
を使うほうが良さそうです...
Docker Compose では additional_contexts
プロパティを使用してください。
概要
1. 原因
Docker では兄弟ディレクトリを参照することはできないようになっているから
2. 対処
# 引数に
# カレントディレクトリ . ではなく
# docker image build .
# 親ディレクトリ .. を指定する
docker image build ..
詳細
1. やりたいこと
$ # 親ディレクトリ .. を起点にして2階層目までを tree で表示
$ tree -L 2 ..
.
├── backend <-- ここから
│ └── Dockerfile
├── frontend
│ └── Dockerfile
└── storage <-- ここを参照したい
└── scripts
$
$ # カレントディレクトリは backend ディレクトリにいるとします
$ pwd
/home/user/project/backend
$
2. 改善前
# 誤
# これがエラーになる
# Docker では兄弟ディレクトリを見ることはできない
COPY ../storage .
$ docker image build -t backend .
エラーになる...
=> ERROR [7/8] COPY ../storage . 0.0s
------
> [7/8] COPY ../storage .:
------
dockerfile:13
--------------------
11 |
12 | WORKDIR /storage
13 | >>> COPY ../storage .
14 |
15 | WORKDIR /app
--------------------
ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref b2b8bec0-7f16-4a4e-82ce-50cc6ea8ad78::olt6lm81xjn7ke9u319v7irsg: "/storage": not found
yaju@yaju-house:project$ docker image build -t backend -f backend/dockerfile .
[+] Building 4.2s (13/13) FINISHED
3. 改善後
# 誤
# COPY ../storage .
# 正
# storage への相対パスは親ディレクトリを起点にする
COPY storage .
$ # 誤
$ # docker image build -t backend .
$
$ # 正
$ # ビルドコンテキストを起点に Docker ファイルへのパスが指定されてしまうので
$ # -f オプションで Docker ファイルへのパスを明示する
$ # -f オプションの相対パスの起点はビルドコンテキストではなくカレントディレクトリになります。
$ docker image build -t backend -f ./Dockerfile ..
背景
1. 疑問
なんで兄弟ディレクトリを参照できないのか?不要なファイルをビルドコンテキストに含めてしまうと docker image build
が重くなってしまうらしいです。COPY
しなければ Docker image に含まれないのでは?🤔と思ったのですがそう単純ではないようです。翻訳サイトはみつかったのに英語の公式サイトでは記述が見当たらない...
イメージのビルドには必要のないファイルを誤って含めてしまうと、ビルドコンテキストがそれだけ大きくなり、結果としてサイズの大きなイメージが生成されることになります。 こうしてしまうと、イメージビルドの時間、このイメージをプッシュしたりプルしたりする時間が、その分だけ要することとなり、コンテナーの実行時の容量も増えてしまいます。 ビルドコンテキストのサイズがどれだけになったかは、Dockerfileを使ってビルド処理を行った際の以下のようなメッセージを確認すればわかります。
Sending build context to Docker daemon 187.8MB
2. 用語
- ビルドコンテキスト
Docker イメージを作成する際に使用するファイルの集まり。
The build context is the set of files that your build can access.
Build context | Docker Docs
docker image build
の位置引数、本記事で言うところの .
や ..
によって、ファイルの集まり即ちビルドコンテキストが指定される。
docker image build
コマンドにおいては「位置引数」でビルドコンテキストとなるファイルの集まりが存在するパスを指定し、「-f
オプション」で Docker ファイルのパスを指定する。
.dockerignore
.dockerignore
ファイルで指定されたファイル、ディレクトリはビルドコンテキストから除外されます。
3. 問題
親ディレクトリ ..
をビルドコンテキストに設定して、COPY ..
でなんでもかんでも放り込むのはよろしくないとのことなのでその点はご留意ください。
4. 対応
大雑把に親ディレクトリを指定するのではなく、個別にビルドコンテクストのディレクトリを指定したい方は ChatGPT 先生に聞いてください。
docker build image
コマンドにおいて複数のビルドコンテキストを含めることはできますか?
参考
これを見て解決できました。ありがとうございます。