Dockerfile: imposta ENV sul risultato del comando


Risposte:


21

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.


15
Giusto per chiarire: non$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.
davnicwil

17

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.


/Etc/profile.d/docker_init.sh è ancora una cosa? Questa risposta è l'unica menzione che posso trovare con Google e non funziona per me. Forse faceva parte di un motore di esecuzione Docker nel 2016 che non è più attuale?
SigmaX

1
@SigmaX Non è una cosa docker, è più una cosa Linux . Qualsiasi *.shfile all'interno /etc/profile.d/viene utilizzato per popolare l'ambiente
Madacol


7

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/bashe se provi a eseguire la tua applicazione docker, ad esempio un'applicazione Node.js, /etc/bash.bashrcverrà completamente ignorata e la tua applicazione non avrà la minima idea di cosa SECRET_KEY_BASEsia quando provi accedereprocess.env.SECRET_KEY_BASE .

Questo è il motivo per cui la ENVparola chiave è ciò che tutti cercano di utilizzare con un comando dinamico perché ogni volta che si esegue il contenitore o si utilizza un execcomando, Docker controllerà ENVe 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

4

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:

  1. eseguire un comando, memorizzare il risultato in un file
  2. utilizzare la sostituzione del comando per ottenere il risultato precedente da quel file in un altro comando

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.


2

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.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.