È possibile impostare una variabile ENV docker sul risultato di un comando? Piace:
ENV MY_VAR whoami
voglio che MY_VAR ottenga il valore "root" o qualunque cosa restituisca whoami
Risposte:
In aggiunta alla risposta di DarkSideF.
È necessario essere consapevoli che ogni riga / comando in Dockerfile viene eseguito in un altro contenitore.
Puoi fare qualcosa del genere:
RUN export bleah=$(hostname -f);echo $bleah;
Viene eseguito in un unico contenitore.
$bleah
è disponibile da nessuna parte al di fuori di questo comando RUN, nemmeno sulla riga successiva nello stesso dockerfile, figuriamoci in un'altra immagine su cui è basato. Funzionalità mancante davvero ovvia dalla finestra mobile qui, sembra che scrivere e leggere da un file sia l'unico modo per memorizzare effettivamente le variabili (dinamiche) nelle immagini e passarle tra le immagini, il che sembra super hacky.
Ho avuto lo stesso problema e ho trovato il modo per impostare la variabile di ambiente come risultato della funzione utilizzando il comando RUN in dockerfile.
Ad esempio, devo impostare SECRET_KEY_BASE per l'app Rails solo una volta senza cambiare come farebbe quando eseguo:
docker run -e SECRET_KEY_BASE="$(openssl rand -hex 64)"
Invece scrivo sulla stringa Dockerfile come:
RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" >> /etc/bash.bashrc'
e la mia variabile env disponibile da root, anche dopo il login bash. o forse
RUN /bin/bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" > /etc/profile.d/docker_init.sh'
quindi variabile disponibile nei comandi CMD e ENTRYPOINT
Docker lo memorizza nella cache come livello e cambia solo se modifichi alcune stringhe prima di esso.
Puoi anche provare diversi modi per impostare la variabile d'ambiente.
*.sh
file all'interno /etc/profile.d/
viene utilizzato per popolare l'ambiente
A questo punto, un risultato del comando può essere utilizzato con RUN export
, ma non può essere assegnato a un fileENV
variabile.
Problema noto: https://github.com/docker/docker/issues/29110
Questa risposta è una risposta a @DarkSideF ,
Il metodo che propone è il seguente, in Dockerfile
:
RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" >> /etc/bash.bashrc'
( aggiungendo un'esportazione nel file/etc/bash.bashrc
)
Va bene ma la variabile di ambiente sarà disponibile solo per il processo /bin/bash
e se provi a eseguire la tua applicazione docker, ad esempio un'applicazione Node.js, /etc/bash.bashrc
verrà completamente ignorata e la tua applicazione non avrà la minima idea di cosa SECRET_KEY_BASE
sia quando provi accedereprocess.env.SECRET_KEY_BASE
.
Questo è il motivo per cui la ENV
parola chiave è ciò che tutti cercano di utilizzare con un comando dinamico perché ogni volta che si esegue il contenitore o si utilizza un exec
comando, Docker controllerà ENV
e reindirizzerà ogni valore nel processo attualmente in esecuzione (simile a -e
).
Una soluzione è usare un wrapper (credito a @duglin in questo problema di GitHub ). Avere un file wrapper (ad esempio envwrapper
) nella radice del progetto contenente:
#!/bin/bash
export SECRET_KEY_BASE="$(openssl rand -hex 64)"
export ANOTHER_ENV "hello world"
$*
e poi nel tuo Dockerfile
:
...
COPY . .
RUN mv envwrapper /bin/.
RUN chmod 755 /bin/envwrapper
CMD envwrapper myapp
In aggiunta alla risposta di @ DarkSideF, se desideri riutilizzare il risultato di un comando precedente Dockerfile
durante il processo di compilazione , puoi utilizzare la seguente soluzione alternativa:
Per esempio :
RUN echo "bla" > ./result
RUN echo $(cat ./result)
Per qualcosa di più pulito, puoi usare anche la seguente sintesi che fornisce una piccola CLI chiamata envstore.py
:
RUN envstore.py set MY_VAR bla
RUN echo $(envstore.py get MY_VAR)
Oppure puoi usare la libreria python-dotenv che ha una CLI simile.
Non sono sicuro che questo sia ciò che stavi cercando, ma per iniettare ENV vars o ARGS nel tuo .Dockerfile, questo modello funziona.
nel tuo 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 .
per ottenere un ARG nel tuo .Dockerfile, lo snippet potrebbe essere simile a questo:
FROM scratch
ARG ARTIFACT_TAG
FROM my_artifact_home_url/bucketname:${ARTIFACT_TAG}
in alternativa per ottenere un ENV nel tuo .Dockerfile, lo snippet potrebbe essere simile a questo:
FROM someimage:latest
ARG ARTIFACT_TAG
ENV ARTIFACT_TAG=${ARTIFACT_TAG}
l'idea è che tu esegua lo script della shell e che richiami .Dockerfile con gli argomenti passati come opzioni nella build.