Docker Compose env_file, environment e .env: chi fa cosa
Guida a env_file in Docker Compose
Docker Compose env_file vs environment vs .env, spiegati | We.Inc
Cosa fanno env_file, environment e il file .env in Docker Compose, quale valore vince quando entrano in conflitto e come funziona l'interpolazione ${VAR:-default}, con un risolutore.
In Docker Compose, env_file carica un file di righe KEY=value nel container di un servizio. L'attributo environment imposta le variabili del container direttamente nel file e vince su env_file quando entrambi indicano la stessa chiave. Il file .env accanto a compose.yaml è un'altra cosa: Compose lo legge per riempire i segnaposto ${VAR} nello YAML stesso.
Tre modi per passare variabili a Compose
Meccanismo
Ambito
Arriva al container?
.env accanto a compose.yaml
Interpolazione di ${VAR} nel file Compose
Solo se un servizio lo richiama
env_file: su un servizio
Il container di quel servizio
Sì, ogni riga
environment: su un servizio
Il container di quel servizio
Sì, e vince su env_file
--env-file nella CLI
Sostituisce il .env predefinito per l'interpolazione
Solo se richiamato
La confusione nasce dal nome: un file chiamato .env e un attributo chiamato env_file sembrano la stessa cosa, ma uno configura il file Compose e l'altro configura un container. Usa il risolutore per vedere quale fonte vince per una variabile, poi prova le forme di interpolazione con una variabile impostata, vuota o non impostata.
Spunta ogni punto in cui la tua variabile è impostata e scrivi il valore che ha lì.
Il risolutore percorre dall'alto l'elenco di precedenza documentato da Docker e mostra quale valore riceve il container.
Nella casella di interpolazione, scegli una forma come ${VAR:-default}, indica se VAR è impostata, vuota o non impostata, e leggi il risultato.
Esegui docker compose config nel tuo progetto per confermare cosa ha effettivamente risolto Compose.
Esegui docker compose config --environment per stampare le variabili usate da Compose per l'interpolazione. Chiude la maggior parte delle discussioni in pochi secondi.
Segna i file env opzionali con required: false (Compose 2.24.0 e successivi) così un override locale mancante non blocca lo stack.
Scrivi $$ quando ti serve un simbolo del dollaro letterale in compose.yaml, ad esempio in una password o in un comando shell.
Metti tra virgolette i booleani nella mappa environment, come SHOW: "true", così YAML non li trasforma in valori true e false.
Domande frequenti
Qual è la differenza tra env_file ed environment?
Entrambi inseriscono variabili nel container di un servizio. env_file le legge da uno o più file, environment le elenca in compose.yaml. Quando la stessa chiave compare in entrambi, vince il valore di environment, anche se è vuoto.
Compose passa automaticamente il mio file .env ai container?
No. Il file .env del progetto serve solo a sostituire ${VAR} nel file Compose. Una variabile arriva a un container solo quando un servizio la nomina sotto environment, o carica il file con env_file.
Dove cerca Compose il file .env?
Nella directory del progetto, cioè la cartella indicata con --project-directory, altrimenti la cartella del primo file -f, altrimenti la cartella corrente. Usa --env-file per puntare a un altro file; se ne usi diversi, i file successivi sovrascrivono i precedenti.
I percorsi di env_file sono relativi a dove eseguo il comando?
No. I percorsi relativi in env_file vengono risolti a partire dalla cartella che contiene il file Compose, così lo stack funziona ovunque tu lo avvii.
Cosa succede a ${VAR} quando VAR non è impostata?
Compose stampa un avviso e sostituisce una stringa vuota. Usa ${VAR:-fallback} per fornire un valore predefinito, oppure ${VAR:?message} per fermarti con un errore.
L'elenco di precedenza, dall'alto verso il basso
Docker documenta cinque livelli. Un valore passato con docker compose run -e è il più forte. Poi viene environment o env_file quando il valore è interpolato dalla tua shell o da un file di ambiente, poi un valore letterale sotto environment, poi un valore da env_file, e infine una riga ENV incorporata nell'immagine.
Nota che solo uno di questi è il file .env, e solo indirettamente: alimenta il secondo livello tramite l'interpolazione. Un valore presente in .env che nessun servizio menziona non compare mai dentro un container.
Chiavi senza valore
Un nome da solo sotto environment, come - API_TOKEN senza segno di uguale, copia il valore dalla shell che esegue Compose. Se la shell non lo ha, la variabile resta non impostata.
In un env_file, una riga che contiene solo una chiave rimuove quella variabile dall'ambiente del container, utile per cancellare di proposito qualcosa che l'immagine imposta.
Tutte le forme di interpolazione
Cosa restituisce ogni forma per una VAR impostata, vuota o non impostata
Forma
VAR=abc
VAR vuota
VAR non impostata
${VAR} o $VAR
vuoto, con un avviso
${VAR:-default}
${VAR-default}
${VAR:?msg}
errore msg
errore msg
${VAR?msg}
errore msg
${VAR:+other}
${VAR+other}
un $ letterale
un $ letterale
un $ letterale
File Compose da copiare
env_file più override con environment
Le impostazioni condivise arrivano dai file; le voci di environment vincono per le chiavi che nominano. Il file locale è opzionale.
.env del progetto usato solo per l'interpolazione
Questi due valori riempiono i segnaposto in compose.yaml. Nessuno dei due arriva a un container a meno che un servizio non lo menzioni.
Usare quei valori in compose.yaml
Il tag dell'immagine e la porta pubblicata arrivano da .env; la password deve essere impostata, altrimenti Compose si ferma con un messaggio chiaro.
Controllare cosa ha risolto Compose
config stampa il modello finale con ogni variabile compilata; --environment elenca i valori usati per la sostituzione.
Quale valore vince?
La variabile APP_MODE è impostata nei punti spuntati qui sotto.
Dove è impostata la variabile
Valore
Il container riceve APP_MODE={v} da: {n}
Non è impostata da nessuna parte, quindi APP_MODE è assente nel container.
Tester di interpolazione
Espressione
VAR è
impostata ma vuota
Valore di VAR
Risultato: {v}
Risultato: una stringa vuota
Compose si ferma con l'errore: {v}
Risultato: una stringa vuota, e Compose stampa un avviso