Ottieni il valore della variabile di ambiente in Dockerfile


254

Sto costruendo un contenitore per un'app rubino. La configurazione della mia app è contenuta nelle variabili di ambiente (caricate all'interno dell'app con dotenv ).

Una di queste variabili di configurazione è l'ip pubblico dell'app, che viene utilizzato internamente per creare collegamenti. Ho bisogno di aggiungere una voce dnsmasq che punta questo ip a 127.0.0.1 all'interno del contenitore, in modo che possa recuperare i collegamenti dell'app come se non fosse containerizzata.

Sto quindi cercando di impostare un ENVnel mio Dockerfile che passerebbe una variabile d'ambiente al contenitore.

Ho provato alcune cose.

ENV REQUEST_DOMAIN $REQUEST_DOMAIN
ENV REQUEST_DOMAIN `REQUEST_DOMAIN`

Tutto passa comunque la stringa "REQUEST_DOMAIN" invece del valore della variabile d'ambiente. Esiste un modo per passare i valori delle variabili di ambiente dal computer host al contenitore?

Risposte:


392

Dovresti usare la ARGdirettiva nel tuo Dockerfile che è pensata per questo scopo.

L' ARGistruzione definisce una variabile che gli utenti possono passare in fase di compilazione al builder con il comando build docker utilizzando il --build-arg <varname>=<value>flag.

Quindi il tuo Dockerfile avrà questa linea:

ARG request_domain

o se preferisci un valore predefinito:

ARG request_domain=127.0.0.1

Ora puoi fare riferimento a questa variabile nel tuo Dockerfile:

ENV request_domain=$request_domain

allora costruirai il tuo contenitore in questo modo:

$ docker build --build-arg request_domain=mydomain Dockerfile


Nota 1: l'immagine non verrà ARGcreata se si fa riferimento a nel file Docker ma lo si è escluso --build-arg.

Nota 2: se un utente specifica un argomento di build che non è stato definito nel Dockerfile, la build genera un avviso:

[Avvertimento] Uno o più build-args [pippo] non sono stati consumati.


12
ARG è disponibile dalla finestra mobile v1.9 in poi.
Synesso,

è supportato per essere costruito in remoto sul repository docker?
James Lin,

4
Your image will not build if you have referenced an ARG in your Dockerfile but excluded it in --build-argTui hai torto. Puoi creare un'immagine con riferimenti anche senza --build-arg. Inoltre è possibile impostare il valore predefinito per l'argomento build.
ALex_hha,

1
Qual è lo scopo della linea ENV? Per me --build-arg + ARG era abbastanza.
Phil

3
L'ARG definisce una variabile da utilizzare all'interno del file docker nei comandi successivi. ENV definisce una variabile di ambiente che viene passata al contenitore.
herm,

56

Quindi puoi fare: cat Dockerfile | envsubst | docker build -t my-target -

Quindi avere un Dockerfile con qualcosa del tipo:

ENV MY_ENV_VAR $MY_ENV_VAR

Suppongo che potrebbe esserci un problema con alcuni personaggi speciali, ma questo funziona almeno per la maggior parte dei casi.


13
Questo non sembra funzionare se è necessario AGGIUNGERE file dalla directory contenente il Dockerfile.
Tom Hennen,

2
Ottima soluzione! Su un Mac puoi farne envsubstparte brew install gettext. Ma a causa di possibili conflitti con il sistema di build BSD, è "solo barile" e non viene creato alcun symlnk. Tuttavia, è sicuro ln -s /usr/local/Cellar/gettext/*/bin/envsubst /usr/local/bin/aggiungere questo comando al PERCORSO. (Sono proprio le librerie a preoccupare.) Oppure puoi usarlo nella sua /usr/local/Cellar/gettext/*/bin/envsubstposizione
Bruno Bronosky,

1
Per chiarire il commento di @ TomHennen, eseguire il piping del Dockerfile docker build -è, nello specifico, ciò che non funziona quando si fa riferimento a percorsi relativi dal proprio Dockerfile, indipendentemente dalla sostituzione di env var.
superEb,

4
Re @ commento di TomHennen, se non desidera utilizzare i comandi dipendenti dal contesto come copia nella Dockerfile si può sempre reindirizzare l'output di envsubst in un file temporaneo e poi alimentare che in docker buildinvece. Esempio:, cat Dockerfile | envsubst > DockerfileWithEnvVarsquindi docker build -t my-target -f DockerfileWithEnvVars ., quindirm DockerfileWithEnvVars
Snark

Oppure puoi usare la spugna dal pacchetto envsubst < Dockerfile | sponge Dockerfile
moreutils

19

Un'alternativa che usa envsubstsenza perdere la capacità di usare comandi come COPYo ADD, e senza usare file intermedi sarebbe quella di usare la sostituzione di processo di Bash :

docker build -f <(envsubst < Dockerfile) -t my-target .

3
sfortunatamente non sembra funzionare (Docker 17.09), ricevo l'erroreunable to prepare context: the Dockerfile (/dev/fd/63) must be within the build context
Alexander Klimetschek,

11

Caricare le variabili di ambiente da un file creato in fase di esecuzione.

export MYVAR="my_var_outside"
cat > build/env.sh <<EOF
MYVAR=${MYVAR}
EOF

... quindi nel Dockerfile

ADD build /build
RUN /build/test.sh

dove test.sh carica MYVAR da env.sh

#!/bin/bash
. /build/env.sh
echo $MYVAR > /tmp/testfile

4

Se vuoi solo trovare e sostituire tutte le variabili d'ambiente ($ ExampleEnvVar) in un Dockerfile, costruiscilo funzionerebbe:

envsubst < /path/to/Dockerfile | docker build -t myDockerImage . -f -


La migliore risposta qui, e in base a ciò, è stata in grado di fare: envsubst < ./Dockerfile | docker build -squash -t ${DOCKIMG}:${VERSION} . -f -dove la FROMlinea sta usando la variabile d'ambiente.
mikequentel,

-6

aggiungi -echiave per passare variabili d'ambiente al contenitore. esempio:

$ MYSQLHOSTIP=$(sudo docker inspect -format="{{ .NetworkSettings.IPAddress }}" $MYSQL_CONRAINER_ID)
$ sudo docker run -e DBIP=$MYSQLHOSTIP -i -t myimage /bin/bash

root@87f235949a13:/# echo $DBIP
172.17.0.2

6
Damien sta cercando di costruire un'immagine. -e funziona invece con il comando run.
Andres Restrepo,
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.