[英]Dockerfile ENTRYPOINT EXEC form not working with Powershell
[英]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
信號傳播的問題是否存在於此(換句話說,是否會在此處生成任何額外的子外殼)?
ENTRYPOINT
或CMD
不是 JSON arrays,它們將被解釋為字符串並轉換為長度為 3 的數組["/bin/sh", "-c", "..."]
。所以在你的例子中,最終的命令列表是
["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.