Spiegando l’utilizzo di docker-entrypoint e php-fpm
L’entrypoint in Docker è lo script principale che viene eseguito quando un container viene avviato, gestendo la configurazione dell’ambiente. La differenza tra CMD ed ENTRYPOINT è che l’ENTRYPOINT è più rigido e definisce il processo principale, mentre CMD fornisce variabili o comandi aggiuntivi. In un contesto Laravel, php-fpm è usato al posto del CLI o Apache per eseguire PHP in modalità ottimizzata, specialmente con Nginx. Questo include l’avvio di processi come cron e i queue worker in un container.
Spiegando Docker entrypoint e php-fpm
L’ENTRYPOINT in Docker definisce il primo processo (PID 1) da eseguire al momento dell’avvio del container. Viene usato per configurare variabili, eseguire migrazioni, cache e quindi avviare il servizio principale. La differenza tra ENTRYPOINT e CMD è che ENTRYPOINT è il comando principale, mentre CMD fornisce argomenti. In un contesto Laravel, possiamo usare l’entrypoint per eseguire comandi come php artisan migrate. Ecco un esempio di script docker-entrypoint.sh che preparare l’ambiente prima di avviare php-fpm.
1 — Che cos’è un ENTRYPOINT in Docker
Quando avvii un container, Docker esegue un solo processo “PID 1”.
Nel Dockerfile hai due istruzioni possibili per dirgli cosa far partire:
| Istruzione | A che serve | Può essere sovrascritta con docker run … <cmd>? |
|---|---|---|
CMD | valore / comando di default | ✅ sì |
ENTRYPOINT | processo obbligatorio (o script) che il container deve sempre lanciare | ❌ no (puoi solo aggiungere argomenti) |
Perché spesso si usa uno script come entrypoint?
Perché prima di far partire il servizio principale puoi:
- preparare l’ambiente (cache, permessi, migrazioni DB…)
- fare
exec "$@"alla fine, così il vero processo (es.php-fpm) eredita il PID 1 e riceve correttamente i segnaliSIGTERM/SIGINTquando spegni il container.
2 — Esempio pratico per Laravel
Dockerfile (estratto)
# Copiamo il codice dell’app
COPY . /var/www/html
# Installiamo dipendenze, ma niente .env di produzione
RUN composer install --no-dev --optimize-autoloader
# Copiamo lo script di entrypoint
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
# Impostiamo ENTRYPOINT e il comando di default
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["php-fpm", "-F"] # -F = foreground (necessario in container)docker-entrypoint.sh
#!/usr/bin/env sh
set -e # fail fast se un comando esce con errore
# Esempio: esegui attività di "bootstrap" solo se stai avviando php-fpm
if [ "$1" = "php-fpm" ]; then
echo "Preparazione cache configurazione Laravel…"
php artisan config:cache
php artisan route:cache
# Eventuale migrate --force, queue:restart, ecc.
fi
# Con exec sostituiamo lo script col vero processo
exec "$@"Cosa succede all’avvio?
- Docker lancia
docker-entrypoint.sh(PID 1). - Lo script prepara Laravel usando le variabili d’ambiente già presenti (quelle che hai definito con
env_file:). - Alla fine fa
exec php-fpm -F. Da questo istantephp-fpmdiventa PID 1 e riceve correttamente i segnali di stop; lo script “scompare”.
3 — Cos’è php‑fpm e perché usarlo nel container
| Caratteristica | Spiegazione |
|---|---|
| Significato | PHP FastCGI Process Manager |
| Ruolo | Mantiene un “pool” di processi PHP in ascolto su una unix‑socket (/run/php/php-fpm.sock) o su una porta (9000/80 nel tuo compose) pronto a gestire richieste FastCGI provenienti da un web‑server (Nginx, Traefik, Caddy) o direttamente dal reverse‑proxy di Docker. |
| Vantaggi | - Separi il runtime PHP dal web‑server (principio Unix “one process, one job”). - Gestione efficiente di concorrenza e memoria (pool dinamico). - Puoi riavviare PHP senza toccare Nginx/Traefik. |
| Differenze con Apache mod_php | In mod_php ogni processo Apache carica PHP → consumo RAM maggiore, meno flessibilità. |
Perché -F | Obbliga php‑fpm a restare in foreground: serve in container, perché se il processo principale termina il container si spegne. |
4 — Perché la coppia entrypoint + php‑fpm risolve i tuoi problemi
| Problema | Come lo risolve l’entrypoint |
|---|---|
| Devi generare la cache di configurazione dopo che le variabili d’ambiente sono presenti | Lo script è eseguito a runtime, quindi vede già tutte le variabili passate con env_file:. |
Vuoi che il container termini pulito con docker stop | exec "$@" fa sì che php‑fpm sia PID 1 e riceva i segnali (SIGTERM) direttamente, chiudendo le connessioni e scrivendo i log. |
| Vuoi un unico punto dove aggiungere step futuri (migrations, storage:link, ecc.) | Aggiungi i comandi in docker-entrypoint.sh prima dell’exec. |
5 — Schema visivo del flusso
docker-compose up
│
▼
docker ==> ENTRYPOINT (docker-entrypoint.sh) # PID 1
│
├─ prepara Laravel (cache, migrate, ecc.)
▼
exec
▼
php-fpm -F # nuovo PID 1
│
├─ worker php #1
├─ worker php #2
└─ …
6 — Checklist rapida
- Metti
ENTRYPOINT ["docker-entrypoint.sh"]prima diCMD [...]. - Nel tuo script usa
set -eeexec "$@". - Avvia
php-fpmin foreground (-F) o come unico servizio. - Aggiungi solo le operazioni indispensabili allo startup; per processi lunghi (queue, scheduler) usa container separati o supervisord.
Così hai un container idempotente, facile da riavviare, che sfrutta correttamente le variabili d’ambiente e fa girare Laravel in modo performante con php‑fpm.