2016-11-06 130 views
12

裏面我Dockerfile:如何在Dockerfile CMD中使用變量?

ENV PROJECTNAME mytestwebsite 
CMD ["django-admin", "startproject", "$PROJECTNAME"] 

錯誤:

CommandError: '$PROJECTNAME' is not a valid project name 

什麼是這裏最快的解決方法嗎? Docker是否有計劃在更高版本的Docker中「修復」或引入此功能?

注:如果我從泊塢文件中刪除CMD行,然後運行多克爾容器,我可以手動從容器內運行Django的管理startproject命令$ PROJECTNAME,它會創建項目...

+1

如何以及何時被你定義'$ PROJECTNAME'? –

+0

使用ENV在我的Dockerfile的開始處。此外,我忘了提及,如果我從Dockerfile中移除CMD行,然後運行容器,那麼可以從容器內運行此命令,並且它將創建項目(即ENV變量有效)。 – david

+0

你的意思是什麼類型的變量:dockerfile變量或環境變量(如在你的系統運行時)? –

回答

18

當您使用執行列表,如...

CMD ["django-admin", "startproject", "$PROJECTNAME"] 

...那麼多克將執行給定的命令直接,不涉及一個殼。由於沒有涉及的外殼,這意味着:

  • 否變量擴展
  • 沒有通配符擴展
  • 沒有I/O重定向與><|
  • 否多個命令經由command1; command2
  • 等等。

如果你想要你的CMD展開變量,你需要安排一個shell。你可以是這樣做的:

CMD ["sh", "-c", "django-admin startproject $PROJECTNAME"] 

或者你可以使用一個簡單的字符串,而不是執行列表,它可以讓你在很大程度上等同於前面的例子結果:

CMD django-admin startproject $PROJECTNAME 
+0

在Docker的問題跟蹤器中閱讀了一些內容:https://github.com/docker/docker/issues/5509 – jannis

+0

「c」後缺少逗號。 – Ako

+0

@ako,謝謝,修復。 – larsks

1

比方說,你想在一個容器內啓動一個java進程。在這種情況下,您需要更多選項,並且您希望直接啓動進程(例如,在沒有tomcat的情況下,不包含catalina.sh包裝器)。首先使用catalina.sh包裝器啓動過程。然後在容器中使用ps ef | less獲取進程的執行語句。現在細分選項和命令部分,這將是您的新CMD。

例Dockerfile摘錄:

ENV JAVA_OPTS -XX +UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1 -XshowSettings:vm 
... 
ENTRYPOINT ["/sbin/tini", "--", "entrypoint.sh"] 
CMD ["myprocess", "${JAVA_OPTS}", "-myargument=true"] 

例entrypoint.sh摘錄:

#!/bin/sh 
... 
echo "*** Startup $0 suceeded now starting service using eval to expand CMD variables ***" 
exec su-exec mytechuser $(eval echo "[email protected]")