Skip to content

Instantly share code, notes, and snippets.

@mapk0y
Last active May 4, 2020
Embed
What would you like to do?
docker build 時に特定のディレクトリのコピーだけ除外したい

やりたいこと

手元のディレクトリが次のような構成で

./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 がホストのファイルで上書きされてないことを確認

1回目のテスト

イメージの作成

[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

2回目のテスト

イメージの作成

  • 最初に .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 などなければキャッシュがうまく活用されていたようだが、通常は開発環境ではそれらのファイルがあるので上書きされてしまって、キャッシュの有効活用しにくかったはず

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment