Risposte:
È possibile passare le variabili di ambiente ai contenitori con il -e
flag.
Un esempio da uno script di avvio:
sudo docker run -d -t -i -e REDIS_NAMESPACE='staging' \
-e POSTGRES_ENV_POSTGRES_PASSWORD='foo' \
-e POSTGRES_ENV_POSTGRES_USER='bar' \
-e POSTGRES_ENV_DB_NAME='mysite_staging' \
-e POSTGRES_PORT_5432_TCP_ADDR='docker-db-1.hidden.us-east-1.rds.amazonaws.com' \
-e SITE_URL='staging.mysite.com' \
-p 80:80 \
--link redis:redis \
--name container_name dockerhub_id/image_name
Oppure, se non si desidera avere il valore sulla riga di comando in cui verrà visualizzato ps
, ecc., È -e
possibile estrarre il valore dall'ambiente corrente se lo si dà semplicemente senza =
:
sudo PASSWORD='foo' docker run [...] -e PASSWORD [...]
Se hai molte variabili d'ambiente e specialmente se sono pensate per essere segrete, puoi usare un file env :
$ docker run --env-file ./env.list ubuntu bash
Il flag --env-file prende un nome file come argomento e si aspetta che ogni riga sia nel formato VAR = VAL, imitando l'argomento passato a --env. Le righe di commento devono essere precedute solo da #
export PASSWORD=foo
invece e la variabile verrà passata docker run
come variabile d'ambiente, facendo docker run -e PASSWORD
funzionare.
Puoi passare usando i -e
parametri con il docker run ..
comando come menzionato qui e come indicato da @errata.
Tuttavia, il possibile svantaggio di questo approccio è che le credenziali verranno visualizzate nell'elenco dei processi, dove lo si esegue.
Per renderlo più sicuro, è possibile scrivere le proprie credenziali in un file di configurazione e fare docker run
con --env-file
come accennato qui . Quindi puoi controllare l'accesso a quel file di configurazione in modo che gli altri che hanno accesso a quel computer non vedano le tue credenziali.
--env-file
, quando usi i --env
tuoi valori env verranno quotati / sfuggiti alla semantica standard di qualunque shell tu stia usando, ma quando usi --env-file
i valori che otterrai all'interno del tuo contenitore sarà diverso. Il comando docker run legge solo il file, esegue analisi di base e passa i valori al contenitore, non è equivalente al modo in cui la shell si comporta. Solo un piccolo gotcha da tenere presente se stai convertendo un sacco di --env
voci in un --env-file
.
Se stai usando 'docker-compose' come metodo per far girare i tuoi container, c'è effettivamente un modo utile per passare una variabile d'ambiente definita sul tuo server al container Docker.
Nel tuo docker-compose.yml
file, supponiamo che tu stia facendo girare un contenitore hapi-js di base e il codice assomigli a:
hapi_server:
container_name: hapi_server
image: node_image
expose:
- "3000"
Supponiamo che il server locale su cui si trova il progetto docker abbia una variabile di ambiente denominata "NODE_DB_CONNECT" che si desidera passare al contenitore hapi-js e che si desideri che il suo nuovo nome sia "HAPI_DB_CONNECT". Quindi, nel docker-compose.yml
file, passeresti la variabile di ambiente locale al contenitore e rinominalo in questo modo:
hapi_server:
container_name: hapi_server
image: node_image
environment:
- HAPI_DB_CONNECT=${NODE_DB_CONNECT}
expose:
- "3000"
Spero che questo ti aiuti a evitare di codificare a fondo una stringa di connessione al database in qualsiasi file nel tuo contenitore!
Usando docker-compose
, puoi ereditare le variabili env in docker-compose.yml e successivamente in qualsiasi Dockerfile chiamato / i da compilare docker-compose
per creare immagini. Ciò è utile quando il Dockerfile
RUN
comando deve eseguire comandi specifici per l'ambiente.
(la tua shell è RAILS_ENV=development
già esistente nell'ambiente)
docker-compose.yml :
version: '3.1'
services:
my-service:
build:
#$RAILS_ENV is referencing the shell environment RAILS_ENV variable
#and passing it to the Dockerfile ARG RAILS_ENV
#the syntax below ensures that the RAILS_ENV arg will default to
#production if empty.
#note that is dockerfile: is not specified it assumes file name: Dockerfile
context: .
args:
- RAILS_ENV=${RAILS_ENV:-production}
environment:
- RAILS_ENV=${RAILS_ENV:-production}
File Docker :
FROM ruby:2.3.4
#give ARG RAILS_ENV a default value = production
ARG RAILS_ENV=production
#assign the $RAILS_ENV arg to the RAILS_ENV ENV so that it can be accessed
#by the subsequent RUN call within the container
ENV RAILS_ENV $RAILS_ENV
#the subsequent RUN call accesses the RAILS_ENV ENV variable within the container
RUN if [ "$RAILS_ENV" = "production" ] ; then echo "production env"; else echo "non-production env: $RAILS_ENV"; fi
In questo modo non è necessario specificare le variabili di ambiente nei file o docker-compose
build
/ up
comandi:
docker-compose build
docker-compose up
Utilizzare -e
o --env value per impostare le variabili di ambiente (default []).
Un esempio da uno script di avvio:
docker run -e myhost='localhost' -it busybox sh
Se si desidera utilizzare più ambienti dalla riga di comando, prima di ogni variabile di ambiente utilizzare il -e
flag.
Esempio:
sudo docker run -d -t -i -e NAMESPACE='staging' -e PASSWORD='foo' busybox sh
Nota: assicurarsi di inserire il nome del contenitore dopo la variabile di ambiente, non prima.
Se devi impostare molte variabili, usa il --env-file
flag
Per esempio,
$ docker run --env-file ./my_env ubuntu bash
Per qualsiasi altro aiuto, consultare la guida di Docker:
$ docker run --help
Documentazione ufficiale: https://docs.docker.com/compose/environment-variables/
ubuntu bash
? Si applica alle immagini create con Ubuntu come immagine di base o ad ogni immagine?
-e
argomenti di anni fa! Non riesco nemmeno a capire perché lo abbiano reso necessario ...
C'è un bel trucco su come convogliare le variabili di ambiente della macchina host in un contenitore docker:
env > env_file && docker run --env-file env_file image_name
Utilizzare questa tecnica con molta attenzione, perché
env > env_file
scaricherà TUTTE le variabili ENV della macchina hostenv_file
e le renderà accessibili nel contenitore in esecuzione.
Per Amazon AWS ECS / ECR, è necessario gestire le variabili di ambiente (in particolare i segreti ) tramite un bucket S3 privato. Vedi post sul blog Come gestire i segreti per le applicazioni basate sul servizio container di Amazon EC2 utilizzando Amazon S3 e Docker .
Se le variabili di ambiente sono env.sh
localmente e si desidera impostarle all'avvio del contenitore, è possibile provare
COPY env.sh /env.sh
COPY <filename>.jar /<filename>.jar
ENTRYPOINT ["/bin/bash" , "-c", "source /env.sh && printenv && java -jar /<filename>.jar"]
Questo comando avvia il contenitore con una shell bash (voglio una shell bash poiché source
è un comando bash), genera il env.sh
file (che imposta le variabili di ambiente) ed esegue il file jar.
Gli env.sh
sguardi come questo,
#!/bin/bash
export FOO="BAR"
export DB_NAME="DATABASE_NAME"
Ho aggiunto il printenv
comando solo per verificare che il comando sorgente effettivo funzioni. Probabilmente dovresti rimuoverlo quando confermi che il comando source funziona correttamente o che le variabili di ambiente verranno visualizzate nei log della finestra mobile.
--env-file
arg ad un docker run
comando. Ad esempio, se si sta distribuendo un'applicazione utilizzando il motore dell'app di Google e l'app in esecuzione all'interno del contenitore necessita di variabili di ambiente impostate all'interno del contenitore docker, non si ha un approccio diretto per impostare le variabili di ambiente poiché non si ha il controllo sul docker run
comando . In tal caso, potresti avere uno script che decodifica le variabili env usando say, KMS e le aggiunge a quelle env.sh
che possono essere acquistate per impostare le variabili env.
.
comando POSIX (punto) disponibile in maniera regolare sh
anziché source
. ( source
è uguale a .
)
Utilizzando jq per convertire env in JSON:
env_as_json=`jq -c -n env`
docker run -e HOST_ENV="$env_as_json" <image>
questo richiede jq versione 1.6 o successiva
questo pust l'host env come json, essenzialmente come in Dockerfile:
ENV HOST_ENV (all env from the host as json)
docker run -e HOST_ENV="$env_as_json" <image>
? : ? Nel mio caso Docker non sembra risolvere variabili o subshells ( ${}
o $()
) quando viene passato come argomento docker. Ad esempio: A=123 docker run --rm -it -e HE="$A" ubuntu
quindi all'interno di quel contenitore: root@947c89c79397:/# echo $HE root@947c89c79397:/#
.... La HE
variabile non ce la fa.
possiamo anche ospitare la variabile di ambiente della macchina usando -e flag e $:
docker run -it -e MG_HOST=$MG_HOST -e MG_USER=$MG_USER -e MG_PASS=$MG_PASS -e MG_AUTH=$MG_AUTH -e MG_DB=$MG_DB -t image_tag_name_and_version
Utilizzando questo metodo imposta automaticamente la variabile env con il tuo nome nel mio caso (MG_HOST, MG_USER)
Se stai usando Python puoi accedere a queste variabili di ambiente all'interno della finestra mobile di
import os
host,username,password,auth,database=os.environ.get('MG_HOST'),os.environ.get('MG_USER'),os.environ.get('MG_PASS'),os.environ.get('MG_AUTH'),os.environ.get('MG_DB')
docker run --rm -it --env-file <(bash -c 'env | grep <your env data>')
È un modo per eseguire il grep dei dati archiviati in a .env
e passarli a Docker, senza che nulla venga archiviato in modo non sicuro (quindi non puoi semplicemente guardare docker history
e afferrare le chiavi.
Supponi di avere un sacco di cose AWS nel tuo .env
modo così:
AWS_ACCESS_KEY: xxxxxxx
AWS_SECRET: xxxxxx
AWS_REGION: xxxxxx
eseguendo docker con `` docker run --rm -it --env-file <(bash -c 'env | grep AWS_') afferrerà tutto e lo passerà in modo sicuro per essere accessibile dall'interno del contenitore.