Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What are the problem?
@hoto17296

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

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

ハマったこと

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
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?