I programmi spesso controllano il funzionamento tramite la configurazione in bundle con il software e le variabili di ambiente consentono agli utenti di impostarle in fase di esecuzione. Tuttavia, l'esecuzione di processi nei container Docker complica le cose, quindi come si passano le variabili di ambiente a un container?
A cosa servono le variabili d'ambiente?
Le variabili di ambiente consentono di disaccoppiare la configurazione dall'eseguibile dell'applicazione. Ad esempio, non vorresti memorizzare la password del database di produzione nella tua codebase:se lo facessi, sarebbe visibile da Git e chiunque abbia accesso al tuo codice potrebbe rimuovere il tuo database.
Invece, lo imposti con una variabile di ambiente, che memorizza una semplice coppia chiave-valore e ti consente di accedere al valore in qualsiasi applicazione in esecuzione nella stessa sessione della shell (non sono accessibili a livello globale). Questo ha anche il vantaggio di poter definire facilmente diverse configurazioni per ambienti diversi. Ad esempio, avere chiavi separate per i database di sviluppo e produzione o utilizzare un endpoint API diverso.
L'impostazione di queste variabili per i contenitori Docker può essere eseguita in tre modi principali:con argomenti CLI, .env
config o tramite docker-compose
.
Con un argomento a riga di comando
Il comando utilizzato per avviare i contenitori Docker, docker run
, accetta variabili ENV come argomenti. Basta eseguirlo con -e
flag, abbreviazione di --env
e passa la coppia chiave=valore:
sudo docker run -e POSTGRES_USER='postgres' -e POSTGRES_PASSWORD='password' ...
E, se hai già quelle variabili di ambiente impostate nell'ambiente che sta eseguendo quel comando, puoi semplicemente passarle direttamente per nome:
// set variable POSTGRES_PASSWORD='password' // use it later docker run -e POSTGRES_PASSWORD -e POSTGRES_USER ...
Sicurezza aggiuntiva con un file .env
Il passaggio di variabili con argomenti CLI funziona alla grande, ma ha uno svantaggio:quelle variabili sono visibili dall'host. Sono registrati nella cronologia dei comandi e sono visibili nell'elenco dei processi per il processo avviato.
Linux ha un modo integrato per gestire le autorizzazioni per questo:l'accesso ai file. Memorizzazione delle variabili in un .env
file ti consente di controllare l'accesso a quel file con i permessi del file (chmod
, chown
).
Crea un .env
file con variabili nel seguente formato, ciascuna su una nuova riga:
POSTGRES_PASSWORD='password' POSTGRES_USER='postgres' APPLICATION_URL='example.com'
Quindi, passalo a docker run
con il --env-file
bandiera:
docker run --env-file ./envfile ...
Con Docker-Compose
Naturalmente, molte persone non avviano i container Docker direttamente con docker run
e scegli invece di utilizzare una docker-compose
file per gestire la configurazione di più contenitori che rappresentano tutti un'unica applicazione.
Per passare le variabili di ambiente a un contenitore avviato in questo modo, dovrai configurare il file di composizione in modo che passi le variabili della sessione al contenitore Docker. Questa configurazione qui passa il POSTGRES_USER
sia per l'ambiente di compilazione che per l'ambiente di runtime e imposta un valore predefinito se non esiste.
version: '3.1' services: my-service: build: context: . args: - POSTGRES_USER=${POSTGRES_USER:-default} environment: - POSTGRES_USER=${POSTGRES_USER:-default}
Dovrai impostare le variabili di ambiente prima di eseguire docker-compose up
, altrimenti non potrà accedervi. Potresti archiviarli nel file di composizione, ma di solito viene monitorato e sottoposto a versionamento, il che vanifica lo scopo delle variabili env.
Con Kubernetes
Kubernetes è un sistema di orchestrazione in grado di gestire l'esecuzione di centinaia di container su una rete. Utilizza ancora Docker, ma toccherai sempre e solo la configurazione, quindi il passaggio diretto delle variabili di ambiente non funzionerà.
Puoi invece definirli nella configurazione del Pod:
apiVersion: v1 kind: Pod metadata: name: example spec: containers: - ... env: - name: SERVICE_PORT value: "80" - name: SERVICE_IP value: "172.17.0.1"
Kubernetes è complicato e ci sono molti modi diversi per lavorare con le variabili d'ambiente. Per saperne di più, puoi leggere le loro guide sull'inserimento dei dati nei Pod.