2016-11-06 129 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]")