Dockerfileで外部のシェルを実行する場合に、そのシェルが正常終了したのに終了ステータスが0以外を返すことがあります。
dockerは、0以外のステータスが返されるとビルドが失敗したと判断して処理を中断してしまいます。
Dockerfileを下記のように記載することで、ステータスを正しく認識してビルドを完了させることができます。
サンプル
ls
コマンドで存在しないファイル名を指定すると終了ステータスは、2になります。
$ ls sadfasf ls: 'sadfasf' にアクセスできません: そのようなファイルやディレクトリはありません $? 2 $
このコマンドを外部シェルに見立ててDockerfileを作成します。
3行目の|| RET=$?
で終了ステータスをRET
に保持し、|| true
で終了ステータスに関係なく処理を正常終了させます。
4行目の&& test $RET -eq 2
で0以外で正常と判断するステータスを検査します。
$ cat -n Dockerfile 1 FROM oraclelinux:7-slim 2 3 RUN ls sadfasf || RET=$? || true \ 4 && test $RET -eq 2 $
下記のように正しくビルドできます。
$ docker build -t test . Sending build context to Docker daemon 3.072kB Step 1/2 : FROM oraclelinux:7-slim ---> c0feb50f7527 Step 2/2 : RUN ls asdfa || RET=$? || true && test $RET -eq 2 ---> Using cache ---> cb6a5b73e7a1 Successfully built cb6a5b73e7a1 $
2行目を書き換えて、存在するパスを指定します。
$ cat -n Dockerfile 1 FROM oraclelinux:7-slim 2 3 RUN ls / || RET=$? || true \ 4 && test $RET -eq 2 $
終了ステータスが0になるとエラーと判断してビルドに失敗します。
これで、どのようなステータスを返すシェルであっても正しく扱うことができます。
$ docker build -t test . Sending build context to Docker daemon 3.072kB Step 1/2 : FROM oraclelinux:7-slim ---> c0feb50f7527 Step 2/2 : RUN ls / || RET=$? || true && test $RET -eq 2 ---> Running in 444fb925563a /bin/sh: line 0: test: -eq: unary operator expected bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var The command '/bin/sh -c ls / || RET=$? || true && test $RET -eq 2' returned a non-zero code: 2 $