tl; dr
- Dockerfile の heredoc 機能の中で凝ったことをやるときはコマンド群の最初に
set -e
とか書くのが無難そう
近年 Dockerfile 内で heredoc 記法が使えるようになったことが知られていて、
www.docker.com
割と凝ったことができる機能で、シンプルには以下のように RUN
にずらずら書くときシュッと書けて便利、というのがわかりやすいと思う。
思うんだけど、こういうふうに heredoc の中でなんかミスってしまったときに何が起こるかというと、
FROM debian
RUN <<EOF
apt-get install packagewhichdoesnotexists
ls
EOF
こういう感じで docker build
は成功扱いになってしまう。
% docker build --no-cache .
[+] Building 2.2s (10/10) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
(中略)
=> CACHED [1/2] FROM docker.io/library/debian@sha256:2ce44bbc00a79113c296d9d25524e15d423b23303fdbbe20190d2f96e0aeb251 0.0s
=> [2/2] RUN <<EOF (apt-get install packagewhichdoesnotexists...) 0.3s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:e62007bb070cd3bacbf16cb21cdca776022865ee5f8a7b7ca4f037dd712f1230 0.0s
Debian に packagewhichdoesnotexists パッケージが存在するわけもなく、直感的には docker build
が失敗してほしいと思うんだけど、成功扱いになってしまう……。
実装された p-r を見てみると、上記のように RUN
に素朴に heredoc を渡した場合は、その中身が sh -c
で実行される、という雰囲気になっているように見えた。heredoc の中身がそのままシェルスクリプトとして実行されるようなものと捉えればよいだろうか。
github.com
という話を同僚の
id:dekokun さんとしていて、set -e
してみたらどうなるかという話になるわけだけど、こうするとしっかり docker build は失敗してくれた。
FROM debian
RUN <<EOF
set -e
apt-get install packagewhichdoesnotexists
ls
EOF
% docker build --no-cache .
[+] Building 3.2s (9/9) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
(中略)
=> CACHED [1/2] FROM docker.io/library/debian@sha256:2ce44bbc00a79113c296d9d25524e15d423b23303fdbbe20190d2f96e0aeb251 0.0s
=> ERROR [2/2] RUN <<EOF (set -e...) 0.3s
------
> [2/2] RUN <<EOF (set -e...):
#9 0.229 Reading package lists...
#9 0.237 Building dependency tree...
#9 0.239 Reading state information...
#9 0.241 E: Unable to locate package packagewhichdoesnotexists
------
executor failed running [/bin/sh -c set -e
apt-get install packagewhichdoesnotexists
ls
]: exit code: 100
完全に忘れてたけどこういう話もある!
b.hatena.ne.jp
これも docker build
成功してしまうけど、
FROM debian
RUN <<EOF
set -e
apt-get install packagewhichdoesnotexists | cat
ls
EOF
Debian ではこれは dash で実行されていて、こういう話になってしまう!
Dockerfile 内でこれをやりたい人はいないでしょって感じで厳しい……。
stackoverflow.com
qiita.com