current - entrypoint docker example
ENV condicional en Dockerfile (5)
¿Es posible establecer condicionalmente una variable
ENV
en un Dockerfile en función del valor de un
ARG
compilación?
Ej: algo como
ARG BUILDVAR=sad
ENV SOMEVAR=if $BUILDVAR -eq "SO"; then echo "hello"; else echo "world"; fi
Actualización: uso actual basado en la respuesta de Mario:
ARG BUILD_ENV=prod
ENV NODE_ENV=production
RUN if [ "${BUILD_ENV}" = "test" ]; then export NODE_ENV=development; fi
Sin embargo, ejecutando con
--build-arg BUILD_ENV=test
y luego yendo al host, todavía obtengo
docker run -it mycontainer bin/bash
[root@brbqw1231 /]# echo $NODE_ENV
production
Pasar valores a Dockerfile y luego al script de punto de entrada
Desde la línea de comando pase su valor requerido (TARG)
docker run --env TARG=T1_WS01 -i projects/msbob
Luego en su
Dockerfile
ponga algo como esto
Dockerfile:
# if $TARG is not set then "entrypoint" defaults to Q0_WS01
CMD ./entrypoint.sh ${TARG} Q0_WS01
El script
entrypoint.sh
solo lee el primer argumento
entrypoint.sh:
#!/bin/bash
[ $1 ] || { echo "usage: entrypoint.sh <$TARG>" ; exit ; }
target_env=$1
No puede ejecutar el código bash en el
Dockerfile
directamente, pero debe usar el comando
EJECUTAR
.
Entonces, por ejemplo, puede cambiar
ENV
con
RUN
y exportar la variable en el
if
, como a continuación:
ARG BUILDVAR=sad
RUN if [ "$BUILDVAR" == "SO"]; /
then export SOMEVAR=hello; /
else export SOMEVAR=world; /
fi
No lo intenté pero debería funcionar.
Sí, es posible, pero debe usar su argumento de compilación como indicador. Puede usar la función de expansión de parámetros del shell para verificar la condición. Aquí hay un archivo Docker de prueba de concepto:
FROM debian:stable
ARG BUILD_DEVELOPMENT
# if --build-arg BUILD_DEVELOPMENT=1, set NODE_ENV to ''development'' or set to null otherwise.
ENV NODE_ENV=${BUILD_DEVELOPMENT:+development}
# if NODE_ENV is null, set it to ''production'' (or leave as is otherwise).
ENV NODE_ENV=${NODE_ENV:-production}
Prueba de compilación:
docker build --rm -t env_prod ./
...
docker run -it env_prod bash
root@2a2c93f80ad3:/# echo $NODE_ENV
production
root@2a2c93f80ad3:/# exit
docker build --rm -t env_dev --build-arg BUILD_DEVELOPMENT=1 ./
...
docker run -it env_dev bash
root@2db6d7931f34:/# echo $NODE_ENV
development
Si bien no puede establecer variables
ENV
condicionales, puede lograr lo que busca con el comando EJECUTAR y una variable de entorno de fusión
null-coalescing
:
RUN node /var/app/current/index.js --env ${BUILD_ENV:-${NODE_ENV:-"development"}}
Tu lógica es realmente correcta.
El problema aquí es que
RUN export ...
no funcionará en un Dockerfile porque el comando de
export
no persistirá en las imágenes.
Los archivos Docker crean un contenedor temporal para generar la imagen, por lo que las variables de entorno no existirán.
ENV
por otro lado, según los estados de la
documentación
:
Las variables de entorno establecidas mediante
ENV
persistirán cuando se ejecute un contenedor desde la imagen resultante.
La única forma de hacerlo es durante el comando de
docker run
al generar el contenedor a partir de su imagen, y envolver su lógica alrededor de eso:
if [ "${BUILD_ENV}" = "test" ]; then
docker run -e NODE_ENV=development myimage
else
docker run myimage
fi