¿Cómo puedo usar una variable dentro de un CMD Dockerfile?
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 ejecutarlo manualmente django-admin startproject $PROJECTNAME
desde dentro del contenedor y se creará el proyecto...
Cuando usas una lista de ejecución, como en...
CMD ["django-admin", "startproject", "$PROJECTNAME"]
...luego Docker ejecutará el comando dado directamente , sin involucrar un shell. Como no hay ningún shell involucrado, eso significa:
- Sin expansión variable
- Sin expansión comodín
- Sin redirección de E/S con
>
,<
,|
, etc. - No hay múltiples comandos a través de
command1; command2
- Etcétera.
Si desea CMD
expandir las variables, debe disponer de 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 dará un resultado prácticamente idéntico al del ejemplo anterior:
CMD django-admin startproject $PROJECTNAME
Si desea utilizar el valor en tiempo de ejecución, establezca el ENV
valor en el archivo Dockerfile
. Si desea usarlo en el momento de la compilación, entonces debe usar ARG
.
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"
También puedes usar exec
Esta es la única forma conocida de manejar señales y usar variables env simultáneamente. Puede ser útil al intentar implementar algo como un apagado elegante según Docker github.
Ejemplo:
ENV PROJECTNAME mytestwebsite
CMD exec django-admin startproject $PROJECTNAME
Digamos que desea iniciar un proceso 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 "$@")