簡體   English   中英

Dockerfile - ENTRYPOINT 的執行形式和 CMD 的 shell 形式

[英]Dockerfile - exec form of ENTRYPOINT and shell form of CMD

我正在查看 Docker 的文檔,以了解以 exec 形式定義的 ENTRYPOINT 和以CMD形式定義的ENTRYPOINT的行為。

文檔中的示例僅顯示類似exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd的內容,但沒有告訴我任何信息。

例如,如果我們有:

ENV JAVA_OPTS '-XX:+UseG1GC -Xms512m -Xmx1536m'
ENTRYPOINT ["java"]
CMD $JAVA_OPTS -jar app.jar

信號傳播的問題是否存在於此(換句話說,是否會在此處生成任何額外的子外殼)?

  1. 如果ENTRYPOINTCMD不是 JSON arrays,它們將被解釋為字符串並轉換為長度為 3 的數組["/bin/sh", "-c", "..."]
  2. 將生成的兩個列表連接起來。

所以在你的例子中,最終的命令列表是

["java", "/bin/sh", "-c", "$JAVA_OPTS -jar app.jar"]

或 Bourne shell 語法

java /bin/sh -c '$JAVA_OPTS -jar app.jar'

這將 shell 解釋器/bin/sh作為參數傳遞給java 這幾乎肯定不是你想要的。

如果CMD不是完整的命令,它必須使用 JSON 數組語法,這反過來意味着它不能使用任何 shell 功能,也不能擴展環境變量引用。 這將包括“容器作為命令”模式,其中ENTRYPOINT是要運行的命令和CMD它的 arguments,以及您在此處顯示的反模式,其中ENTRYPOINT僅是解釋器(並且您必須重復-jar app.jar選項在docker run命令覆蓋中)。

我更喜歡CMD始終是完整的 shell 命令的設置。 如果您有一個ENTRYPOINT ,它是一個腳本,它執行一些啟動時設置,然后運行exec "$@"以運行作為 arguments 傳遞的命令。這可以接受CMD的任何一種形式。

# ENTRYPOINT ["./docker-entrypoint.sh"]  # optional
CMD java $JAVA_OPTS -jar app.jar         # in a single shell-format CMD

我花了一段時間,但我終於弄清楚/bin/sh -c在這個用例中的意義是什么。 例如,我們可以使用tini作為入口點

ENTRYPOINT ["tini", "--"]

然后是 CMD 的 shell,但是我們需要使用exec來替換子 shell,即

CMD exec java $JAVA_OPTS -jar app.jar

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM