LoginSignup
14
11

More than 1 year has passed since last update.

Docker で entrypoint.sh がうまく動かなかった件

Posted at

しょーもないことでハマってしまったのでお焚き上げ。

ハマったこと

Dockerfile
FROM debian

ADD entrypoint.sh /
RUN chmod +x /entrypoint.sh

ENTRYPOINT /entrypoint.sh
entrypoint.sh
#!/bin/bash

exec "$@"

よくある、シェルスクリプトを ENTRYPOINT に指定した Docker イメージ。(実際には exec "$@" の前で何かしらの処理を実行することになる)

これを動かしてみるが、なんと動かない。

$ docker build . -t tmp
$ docker run -it tmp echo foo  # 何も表示されない (本当は foo と表示されてほしい)

しかも何のエラーも出ないので困ってしまった。

ナンデ???

原因

Dockerfile の ENTRYPOINT の指定が shell 形式になっていたことが原因。

shell 形式と exec 形式

Dockerfile の ENTRYPOINT や CMD には shell 形式 (shell form) と exec 形式 (exec form) の二種類があって、どちらでもビルドはできるが実行のされ方が異なる。1

shell形式
ENTRYPOINT /entrypoint.sh
exec形式
ENTRYPOINT ["/entrypoint.sh"]

exec 形式は指定したコマンドと引数がそのまま実行されるが、shell 形式で指定した場合は /bin/sh -c に渡される。

つまり、shell 形式で /entrypoint.sh と指定した場合は以下と同じ振る舞いになる。

ENTRYPOINT ["/bin/sh", "-c", "/entrypoint.sh"]

なぜ shell 形式だと動かなかったか

shell 形式だと shell -c に渡されるため、冒頭のやり方だと実行されるコマンドがこうなってしまう。

$ /bin/sh -c '/entrypoint.sh' echo foo

これでは /entrypoint.sh プロセスに echo foo というパラメータが渡らないので、echo foo は実行されずに /bin/sh プロセスは正常終了してしまう。

どうすればいいか

ENTRYPOINT や CMD は exec 形式で書こう。

Dockerfile
FROM debian

ADD entrypoint.sh /
RUN chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh
#!/bin/bash

exec "$@"
$ docker build . -t tmp
$ docker run --rm -it tmp echo foo
foo
14
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
11