読者です 読者をやめる 読者になる 読者になる

Shred IT!!!!

IT全般について試したこと・勉強したことを綴ったり、趣味について語るブログ

docker build すると ADD, COPY で no such file or directory になる問題の解決方法

docker 導入に関する記事を別で書くつもりだが、 今やっているプロジェクトで docker build で大ハマりしたので、 その解決方法をメモしておく。

概要


上記環境だが、特に 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

これで何もエラーが出ずにビルドすることができた。

まとめ


チームで使うソフトのバージョンはみんな合わせましょう・・・