docker build すると ADD, COPY で no such file or directory になる問題の解決方法
docker 導入に関する記事を別で書くつもりだが、 今やっているプロジェクトで docker build で大ハマりしたので、 その解決方法をメモしておく。
概要
- CentOS 7
- Docker 1.6.2
上記環境だが、特に yum のリポジトリを更新することもなく、 下記を実行して Docker 1.6.2 をインストール。
yum install docker docker-selinux
チームで管理している Dockerfile があるので、 それを落として色々インストールした後、 docker build して docker pull する予定だった。
「no such file or directory」のエラーでビルドできない
Dockerfile は他の方が docker build 成功しているので、 俺の環境でもできるはずなのに build がどうやってもうまくいかない。
# vim Dockerfile ... ADD test.txt /tmp/test.txt ...
上記のような Dockerfile で docker build
を実行してみる。
ERRO[0000] Can't exclude whole path, excluding pattern: * ... Error build: test.txt: no such file or directory
ツリー構造的には Dockerfile と test.txt は同じディレクトリに存在しているのにエラーが出る。
docker build をしたときには context という概念が登場する。
簡単に言うとテンポラリー領域のようなもの。
Dockerfile と同じ階層にあるファイル・ディレクトリを構築する docker 環境にテンポラリー的にコピーして持ち込み、 ADD や COPY で docker 環境にファイルを配置する。
なので、context の意味がわからないうちは下記のようなエラーを起こしてしまう。
Docker: adding a file from a parent directory - Stack Overflow
.dockerignore という存在
今回は context 内のファイルを指定しているので別の原因が存在していた。
.dockerignore というファイルだ。
* !test.txt
ファイルの中身はこのようになっていた。
意図としては context にいちいちファイル・ディレクトリを全コピーすると重くなるため、
context には test.txt 以外はコピーさせないということだった。
*
の記述を消してビルドするとあっさりうまくいった。
そして、実は根本的に他の原因があった。
docker のバージョンアップ
実は docker のイメージをビルドした方の docker バージョン(1.7)と、 自分の docker バージョン(1.6)が異なっていた。
そして、バージョンアップしたら、あっさり問題解決。
# cat >/etc/yum.repos.d/docker.repo <<-EOF [dockerrepo] name=Docker Repository baseurl=https://yum.dockerproject.org/repo/main/centos/7 enabled=1 gpgcheck=1 gpgkey=https://yum.dockerproject.org/gpg EOF
↑ yum のリポジトリを追加。
↓ docker をアップデートする。
# sudo yum update docker docker-selinux
バージョンが 1.7.1 になったのだが、.dockerignore を解釈できるようになり、
* !test.txt
これで何もエラーが出ずにビルドすることができた。
まとめ
チームで使うソフトのバージョンはみんな合わせましょう・・・