¿Es posible establecer una variable ENV de la ventana acoplable como resultado de un comando? Me gusta:
ENV MY_VAR whoami
quiero que MY_VAR obtenga el valor "root" o lo que sea que devuelva whoami
Respuestas:
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.
$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.
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.
*.sh
archivo en el interior /etc/profile.d/
se utiliza para poblar el entorno
En este momento, el resultado de un comando se puede usar con RUN export
, pero no se puede asignar a unENV
variable.
Problema conocido: https://github.com/docker/docker/issues/29110
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.bashrc
se 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 ENV
palabra clave es lo que todos intentan usar con un comando dinámico porque cada vez que ejecuta su contenedor o usa un exec
comando, Docker verificará ENV
y 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
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:
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.
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.