Dockerfile: establezca ENV como resultado del comando


Respuestas:


23

Como una adición a la respuesta de DarkSideF.

Debe tener en cuenta que cada línea / comando en Dockerfile se ejecuta en otro contenedor.

Puedes hacer algo como esto:

RUN export bleah=$(hostname -f);echo $bleah;

Esto se ejecuta en un solo contenedor.


14
Solo para aclarar: no$bleah está disponible en ningún lugar fuera de este comando RUN, ni siquiera en la siguiente línea en el mismo archivo docker, y mucho menos en otra imagen en la que se basa. Una característica realmente obvia que falta en la ventana acoplable aquí, parece que escribir y leer en un archivo es la única forma de almacenar realmente variables (dinámicas) en imágenes y pasarlas entre imágenes, lo que parece súper hacky.
davnicwil

17

Tuve el mismo problema y encontré la manera de establecer la variable de entorno como resultado de la función usando el comando RUN en dockerfile.

Por ejemplo, necesito configurar SECRET_KEY_BASE para la aplicación Rails solo una vez sin cambiar como lo haría cuando ejecuto:

docker run  -e SECRET_KEY_BASE="$(openssl rand -hex 64)"

En su lugar, escribo en la cadena Dockerfile como:

RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" >> /etc/bash.bashrc'

y mi variable env disponible desde la raíz, incluso después de iniciar sesión en bash. o tal vez

RUN /bin/bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" > /etc/profile.d/docker_init.sh'

luego variable disponible en los comandos CMD y ENTRYPOINT

Docker lo almacena en caché como capa y solo lo cambia si cambia algunas cadenas antes.

También puede probar diferentes formas de establecer la variable de entorno.


¿Sigue existiendo /etc/profile.d/docker_init.sh? Esta respuesta es la única mención que puedo encontrar con Google, y no me funciona. ¿Fue quizás parte de un motor de ejecución de Docker en 2016 que ya no es actual?
SigmaX

1
@SigmaX No es una cosa de Docker, es más una cosa de Linux . Cualquier *.sharchivo en el interior /etc/profile.d/se utiliza para poblar el entorno
Madacol


7

Esta respuesta es una respuesta a @DarkSideF ,

El método que propone es el siguiente, en Dockerfile:

RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" >> /etc/bash.bashrc'

( agregando una exportación en el/etc/bash.bashrc )

Es bueno, pero la variable de entorno solo estará disponible para el proceso /bin/bash, y si intenta ejecutar su aplicación Docker, por ejemplo, una aplicación Node.js, /etc/bash.bashrcse ignorará por completo y su aplicación no tendrá ni idea de quéSECRET_KEY_BASE es al intentar accederprocess.env.SECRET_KEY_BASE .

Esa es la razón por la que la ENVpalabra clave es lo que todos intentan usar con un comando dinámico porque cada vez que ejecuta su contenedor o usa un execcomando, Docker verificará ENVy canalizará todos los valores en el proceso que se ejecuta actualmente (similar a-e ).

Una solución es usar un contenedor (crédito a @duglin en este número de github ). Tenga un archivo contenedor (por ejemplo envwrapper) en la raíz de su proyecto que contenga:

#!/bin/bash
export SECRET_KEY_BASE="$(openssl rand -hex 64)"
export ANOTHER_ENV "hello world"
$*

y luego en tu Dockerfile:

...
COPY . .
RUN mv envwrapper /bin/.
RUN chmod 755 /bin/envwrapper
CMD envwrapper myapp

2

Como una adición a la respuesta de @ DarkSideF, si desea reutilizar el resultado de un comando anterior en su Dockerfile durante el proceso de compilación , puede usar la siguiente solución:

  1. ejecutar un comando, almacenar el resultado en un archivo
  2. use la sustitución de comandos para obtener el resultado anterior de ese archivo en otro comando

Por ejemplo :

RUN echo "bla" > ./result
RUN echo $(cat ./result)

Para algo más limpio, puede usar también la siguiente esencia que proporciona una pequeña CLI llamada envstore.py:

RUN envstore.py set MY_VAR bla
RUN echo $(envstore.py get MY_VAR)

O puede usar la biblioteca python-dotenv que tiene una CLI similar.


2

No estoy seguro de si esto es lo que estaba buscando, pero para inyectar ENV vars o ARGS en su .Dockerfile, este patrón funciona.

en su my_build.sh:

echo getting version of osbase image to build from
OSBASE=$(grep "osbase_version" .version | sed 's/^.*: //')

echo building docker
docker build -f \
--build-arg ARTIFACT_TAG=$OSBASE \
PATH_TO_MY.Dockerfile \
-t my_artifact_home_url/bucketname:$TAG .

para obtener un ARG en su .Dockerfile, el fragmento podría verse así:

FROM scratch
ARG ARTIFACT_TAG
FROM my_artifact_home_url/bucketname:${ARTIFACT_TAG}

alternativamente, para obtener un ENV en su .Dockerfile, el fragmento podría verse así:

FROM someimage:latest
ARG ARTIFACT_TAG
ENV ARTIFACT_TAG=${ARTIFACT_TAG}

la idea es ejecutar el script de shell y eso llama al .Dockerfile con los argumentos pasados ​​como opciones en la compilación.

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.