Spiegando l’uso delle variabili d’ambiente in Docker
L’utente chiede come configurare Laravel per usare le variabili d’ambiente direttamente dal container Docker, non dal file “.env” all’interno del codice. Quando definisci variabili d’ambiente nel Docker tramite env_file: .env, Docker carica quei valori nel container. Per Laravel, puoi usare $_ENV o getenv() per accedere a queste variabili. Docker gestisce l’invio delle variabili automaticamente all’interno del container, quindi Laravel riceverà quest’ultime senza bisogno di un file .env separato.
Spiegando l’ambiente in container con Laravel
Per Laravel in un container, possiamo passare variabili d’ambiente al container e Laravel le legge tramite getenv() o dal file .env. Se il file .env non è presente, Laravel cercherà le variabili d’ambiente dell’OS. Se usiamo Docker, possiamo passare le variabili dal file docker-compose.yml o dal parametro env_file. È importante che Dotenv di Laravel non sovrascriva le variabili già impostate nel container. Per evitare conflitti, possiamo evitare di usare un file .env all’interno del container.
Soluzione per l’uso delle variabili d’ambiente in container
Per utilizzare le variabili d’ambiente del container con Laravel, ti consiglio di montare il file .env nel container tramite docker-compose.yml, definendo le variabili nel file env_file. Puoi anche evitare di usare un .env all’interno del container e affidarti solo alle variabili d’ambiente, modificando la configurazione di Laravel per leggere direttamente da env() senza config. Docker caricherà le variabili al momento dell’avvio, e Dotenv non sovrascriverà le variabili già presenti.
Soluzione pratica — passare le variabili dal container a Laravel
-
Crea un file di variabili solo per il container (teniamolo fuori dalla cartella
srcper non committarlo):# ./larapuk.env (stesso livello di docker‑compose.yml) APP_ENV=production APP_KEY=base64:xxxxxxxxxxxxxxxxxxxxxxxxxxx APP_URL=https://larapuk.lpuk.it DB_CONNECTION=mysql DB_HOST=db DB_PORT=3306 DB_DATABASE=larapuk DB_USERNAME=larapuk DB_PASSWORD=super‑password CACHE_DRIVER=redis QUEUE_CONNECTION=redis REDIS_HOST=redis -
Collega quel file al servizio aggiungendo (o sostituendo) la sezione nel tuo
docker-compose.yml:services: larapuk: build: context: . dockerfile: Dockerfile image: larapuk container_name: larapuk restart: unless-stopped env_file: - ./larapuk.env # ← puntiamo al file appena creato networks: - proxy - core labels: - "traefik.enable=true" - "traefik.http.routers.larapuk.rule=Host(`larapuk.lpuk.it`)" - "traefik.http.routers.larapuk.entrypoints=websecure" - "traefik.http.routers.larapuk.tls=true" - "traefik.http.routers.larapuk.tls.certresolver=letsencrypt" - "traefik.http.services.larapuk.loadbalancer.server.port=80" expose: - "80" -
(Opzionale ma consigliato) rimuovi o rinomina il file
.envdentrosrcquando costruisci l’immagine di produzione, così eviti conflitti e non hai segreti nel repository.- In locale puoi continuare a usare
.env; basta non copiarlo nell’immagine (.dockerignore,COPYselettivo oRUN rm .envnel Dockerfile).
- In locale puoi continuare a usare
-
Ricostruisci e avvia di nuovo:
docker compose up -d --build -
Verifica dentro al container che le variabili ci siano:
docker exec -it larapuk printenv | grep APP_
Perché funziona — il percorso delle variabili in Docker + Laravel
| Momento | Dove viene impostata la variabile | Ha la precedenza su … |
|---|---|---|
docker run / docker‑compose environment: | riga di comando, variabili passate direttamente | tutto il resto |
env_file nel docker-compose.yml | file che hai appena creato (larapuk.env) | ENV definite nel Dockerfile |
istruzione ENV nel Dockerfile | variabili “di default” dell’immagine | nessuna (è il livello più basso) |
Nota:
ARGnel Dockerfile esiste solo in fase di build (serve a passare parametri alDockerfile), non sopravvive nel container.
Quando il container parte:
-
Il kernel prepara lo “environment” del processo PID 1 (nel tuo caso
php-fpmoartisan …) con tutte le variabili dei livelli mostrati sopra. -
Laravel bootstrap: prima carica eventualmente il file
.envcon vlucas/php‑dotenv; questa libreria per default non sovrascrive variabili già presenti. -
Ogni chiamata
env('FOO')in un file di configurazione legge prima dall’environment di sistema, poi dal.env, poi dal valore di default fornito nel codice.
Quindi, se nel container esiste DB_HOST=db, quel valore vince sullo stesso nome presente nel .env. Se elimini il .env dentro l’immagine, il passaggio (2) non fa nulla e avrai un’unica sorgente di verità: le variabili del container.
Attenzione a config:cache
Se nel Dockerfile esegui php artisan config:cache (ottimo per performance) ricorda che il comando deve avvenire dopo che le variabili sono già presenti. In pratica:
# (estratto)
COPY . /var/www/html
# NON copiare .env qui, se lo usi solo in locale
# qui le variabili da env_file NON esistono ancora
RUN composer install --no-dev --optimize-autoloader
# sposta config:cache in un entrypoint o script di startup
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]docker-entrypoint.sh (semplificato):
#!/bin/sh
php artisan config:cache
exec php-fpm # o supervisord, ecc.In questo modo la cache viene creata con i valori reali.
Riepilogo
-
env_filein compose → carica KEY=VALUE nel runtime del container. -
Laravel preferisce quei valori rispetto al
.envinterno. -
Evita di copiare
.envsensibili nella build e gestisci l’eventualeconfig:cachedopo che le variabili esistono.
Così hai una pipeline pulita: un’unica fonte di configurazione per produzione, nessun segreto nel repository e comportamento prevedibile.