手元のディレクトリが次のような構成で
./app
├── index.html
├── bar
│ └── hoge
└── foo
└── hoge
docker build 時のコピー先が以下の様な場合
/app
└── foo
└── hoge
コピー先の /app/foo/hoge
がコピー元のもので上書きされてしまうのを防ぎたい。
.dockerignore
を利用する
ディレクトリ構成
[mapk0y@kona:~/local/docker/docker-ignore]$ tree -aA
.
├── .dockerignore
├── Dockerfile
└── app
├── bar
│ └── hoge
├── foo
│ └── hoge
└── index.html
3 directories, 5 files
Dockerfile
- 見た目を良くするため tree コマンドを利用
- やってる内容は後述
[mapk0y@kona:~/local/docker/docker-ignore]$ cat Dockerfile
FROM debian
# setup tree command
RUN set -ex \
&& apt-get update \
&& apt-get install -y --no-install-recommends tree \
&& apt-get clean \
&& rm -rf /var/cache/apt
# setup
RUN set -ex \
&& mkdir -pv /app/bar \
&& echo new > /app/bar/hoge \
&& ls -l /app/bar \
&& cat /app/bar/hoge
COPY ./app /app
コピーするファイルの中身
[mapk0y@kona:~/local/docker/docker-ignore]$ head app/*/*
==> app/bar/hoge <==
bar
==> app/foo/hoge <==
foo
/app/bar/hoge
ファイルを Dockerfile で作成し中にnew
と書き込む- その後に COPY で
/app
をホストからコピー - ホストには
/app/bar/hoge
がある - 1回目は
.dockerignore
に何も記述しないでテスト - 2回目は
.dockerignore
に./app/bar
を追加してテスト - 1回目のあとは
./app/bar/hoge
がホストのファイルで上書きされていることを確認 - 2回目のあとは
./app/bar/hoge
がホストのファイルで上書きされてないことを確認
イメージの作成
[mapk0y@kona:~/local/docker/docker-ignore]$ docker build -t check .
Sending build context to Docker daemon 6.656 kB
Step 1 : FROM debian
---> 7b0a06c805e8
Step 2 : RUN set -ex && apt-get update && apt-get install -y --no-install-recommends tree && apt-get clean && rm -rf /var/cache/apt
---> Running in 320b92de1b73
+ apt-get update
Get:1 http://security.debian.org jessie/updates InRelease [63.1 kB]
Get:2 http://security.debian.org jessie/updates/main amd64 Packages [402 kB]
Ign http://deb.debian.org jessie InRelease
Get:3 http://deb.debian.org jessie-updates InRelease [145 kB]
Get:4 http://deb.debian.org jessie Release.gpg [2373 B]
Get:5 http://deb.debian.org jessie-updates/main amd64 Packages [17.6 kB]
Get:6 http://deb.debian.org jessie Release [148 kB]
Get:7 http://deb.debian.org jessie/main amd64 Packages [9064 kB]
Fetched 9842 kB in 1s (5401 kB/s)
Reading package lists...
+ apt-get install -y --no-install-recommends tree
Reading package lists...
Building dependency tree...
The following NEW packages will be installed:
tree
0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
Need to get 45.9 kB of archives.
After this operation, 102 kB of additional disk space will be used.
Get:1 http://deb.debian.org/debian/ jessie/main tree amd64 1.7.0-3 [45.9 kB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 45.9 kB in 0s (114 kB/s)
Selecting previously unselected package tree.
(Reading database ... 7548 files and directories currently installed.)
Preparing to unpack .../tree_1.7.0-3_amd64.deb ...
Unpacking tree (1.7.0-3) ...
Setting up tree (1.7.0-3) ...
+ apt-get clean
+ rm -rf /var/cache/apt
---> 93970826ee7f
Removing intermediate container 320b92de1b73
Step 3 : RUN set -ex && mkdir -pv /app/bar && echo new > /app/bar/hoge && ls -l /app/bar && cat /app/bar/hoge
---> Running in 973e3d7b2ed5
mkdir: created directory '/app'
mkdir: created directory '/app/bar'
+ mkdir -pv /app/bar
+ echo new
+ ls -l /app/bar
+ cat /app/bar/hoge
total 4
-rw-r--r-- 1 root root 4 Nov 3 03:41 hoge
new
---> 8ddfe6c26c62
Removing intermediate container 973e3d7b2ed5
Step 4 : COPY ./app /app
---> e40424820721
Removing intermediate container c20a04e24462
Successfully built e40424820721
確認
[mapk0y@kona:~/local/docker/docker-ignore]$ docker run -t --rm check sh -c 'tree -A /app && head /app/*/*'
/app
├── bar
│ └── hoge
├── foo
│ └── hoge
└── index.html
2 directories, 3 files
==> /app/bar/hoge <==
bar
==> /app/foo/hoge <==
foo
イメージの作成
- 最初に
.dockerignore
を設定しておく - "Sending build context to Docker daemon" のサイズが "6.656 kB" から "6.144 kB" に変わっている
.dockerignore
の効果で初期転送ファイルから./app/bar
以下除外されているので、送信バイト数が減っている。
- Step 3 までは上記の上記のキャッシュが使われているが特に問題はない
[mapk0y@kona:~/local/docker/docker-ignore]$ docker build -t check2 .
Sending build context to Docker daemon 6.144 kB
Step 1 : FROM debian
---> 7b0a06c805e8
Step 2 : RUN set -ex && apt-get update && apt-get install -y --no-install-recommends tree && apt-get clean && rm -rf /var/cache/apt
---> Using cache
---> 93970826ee7f
Step 3 : RUN set -ex && mkdir -pv /app/bar && echo new > /app/bar/hoge && ls -l /app/bar && cat /app/bar/hoge
---> Using cache
---> 8ddfe6c26c62
Step 4 : COPY ./app /app
---> 0b628978df89
Removing intermediate container 28a2754a6989
Successfully built 0b628978df89
確認
[mapk0y@kona:~/local/docker/docker-ignore]$ docker run -t --rm check2 sh -c 'tree -A /app && head /app/*/*'
/app
├── bar
│ └── hoge
├── foo
│ └── hoge
└── index.html
2 directories, 3 files
==> /app/bar/hoge <==
new
==> /app/foo/hoge <==
foo
上記のように上書きされてないことが確認できる。
これは bundle や golang の vendor、npm などのキャッシュをうまく使うのに利用できそう。
挙動を見る限り、今までも vendor などなければキャッシュがうまく活用されていたようだが、通常は開発環境ではそれらのファイルがあるので上書きされてしまって、キャッシュの有効活用しにくかったはず