Solución:
Asegúrese de que su Dockerfile declare una variable de entorno con ENV
:
ENV environment default_env_value
ENV cluster default_cluster_value
los ENV <key> <value>
El formulario se puede reemplazar en línea.
Entonces puede pasar una variable de entorno con docker run
docker run -p 9000:9000 -e environment=dev -e cluster=0 -d me/app
O puede configurarlos a través de su archivo de redacción:
node:
environment:
- environment=dev
- cluster=0
Tu Dockerfile CMD
puede usar esa variable de entorno, pero, como se menciona en el número 5509, debe hacerlo en un sh -c
formulario:
CMD ["sh", "-c", "node server.js ${cluster} ${environment}"]
La explicación es que el shell es responsable de expandir las variables de entorno, no Docker. Cuando usa el Sintaxis JSON, está solicitando explícitamente que su comando omita el shell y se ejecute directamente.
La misma idea con Builder RUN (se aplica a CMD
así como):
A diferencia del formulario de shell, el formulario de ejecución no invoca un shell de comandos.
Esto significa que el procesamiento de shell normal no ocurre.
Por ejemplo,
RUN [ "echo", "$HOME" ]
no hará sustitución de variables en$HOME
. Si desea un procesamiento de shell, utilice el formulario de shell o ejecute un shell directamente, por ejemplo:RUN [ "sh", "-c", "echo $HOME" ]
.
Cuando se usa el formulario exec y se ejecuta un shell directamente, como en el caso del formulario shell, es el shell el que realiza la expansión de la variable de entorno, no la ventana acoplable.
Otra opción es usar ENTRYPOINT
para especificar que node
es el ejecutable para ejecutar y CMD
para proporcionar los argumentos. Los documentos tienen un ejemplo en el formulario Exec ENTRYPOINT example.
Usando este enfoque, su Dockerfile se verá algo así como
FROM ...
ENTRYPOINT [ "node", "server.js" ]
CMD [ "0", "dev" ]
Ejecutarlo en dev usaría el mismo comando
docker run -p 9000:9000 -d me/app
y ejecutándolo en prod, pasaría los parámetros al comando de ejecución
docker run -p 9000:9000 -d me/app 1 prod
Es posible que desee omitir CMD
por completo y siempre pasar 0 dev
o 1 prod
como argumentos para el comando de ejecución. De esa manera, no inicia accidentalmente un contenedor de producción en dev o un contenedor de desarrollo en prod.
La forma típica de hacer esto en los contenedores de Docker es pasar variables de entorno:
docker run -p 9000:9000 -e NODE_ENV=dev -e CLUSTER=0 -d me/app