¿Cómo puedo usar una variable dentro de una CMD de Dockerfile?


104

Dentro de mi Dockerfile:

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

Error:

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

¿Cuál es la solución más rápida aquí? ¿Tiene Docker algún plan para "arreglar" o introducir esta funcionalidad en versiones posteriores de Docker?

NOTA: Si elimino la línea CMD del archivo Docker y luego ejecuto el contenedor Docker, puedo ejecutar manualmente Django-admin startproject $ PROJECTNAME desde el interior del contenedor y creará el proyecto ...


1
¿Cómo y cuándo estás definiendo $PROJECTNAME?
— Piotr Wittchen

Al comienzo de mi Dockerfile usando ENV. También olvidé mencionar que si elimino la línea CMD del Dockerfile y luego ejecuto el contenedor, desde dentro del contenedor puedo ejecutar este comando y creará el proyecto (lo que significa que la variable ENV es válida).
— David

¿A qué tipo de variable se refiere: variable dockerfile o variable de entorno (como en el tiempo de ejecución de su sistema)?
— emix

Respuestas:


164

Cuando usa una lista de ejecución, como en ...

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

... entonces Docker ejecutará el comando dado directamente , sin involucrar un shell. Dado que no hay shell involucrado, eso significa:

  • Sin expansión variable
  • Sin expansión con comodines
  • Sin i / o redirección con >, <,| , etc.
  • No hay varios comandos a través de command1; command2
  • Etcétera.

Si desea CMDexpandir las variables, debe organizar un shell. Puedes hacerlo así:

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

O puede usar una cadena simple en lugar de una lista de ejecución, lo que le da un resultado en gran parte idéntico al ejemplo anterior:

CMD django-admin startproject $PROJECTNAME

2
Más lectura en el rastreador de problemas de Docker: github.com/docker/docker/issues/5509
— jannis

@larsks una cadena simple es INCREÍBLE
— abdoutelb

¡Me has salvado el día!
— Supratim Roy

18

Si desea utilizar el valor en tiempo de ejecución, establezca el ENVvalor en Dockerfile. Si desea usarlo en el momento de la compilación, debe usarARG .

Ejemplo:

ARG value
ENV envValue=$value
CMD ["sh", "-c", "java -jar ${envValue}.jar"]

Pase el valor en el comando de compilación:

docker build -t tagName --build-arg value="jarName"

10

Digamos que desea iniciar un proceso de Java dentro de un contenedor:

Ejemplo de extracto de Dockerfile:

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

Ejemplo de extracto de entrypoint.sh:

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

0

Inspirado en lo anterior, hice esto:

#snapshot by default. 1 is release.
ENV isTagAndRelease=0

CMD     echo is_tag: ${isTagAndRelease} && \
        if [ ${isTagAndRelease} -eq 1 ]; then echo "release build"; mvn -B release:clean release:prepare release:perform; fi && \
        if [ ${isTagAndRelease} -ne 1 ]; then echo "snapshot build"; mvn clean install; fi && \ 
       .....
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.