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:

IstruzioneA che servePuò essere sovrascritta con docker run … <cmd>?
CMDvalore / comando di default✅ sì
ENTRYPOINTprocesso 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 segnali SIGTERM/SIGINT quando 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?

  1. Docker lancia docker-entrypoint.sh (PID 1).
  2. Lo script prepara Laravel usando le variabili d’ambiente già presenti (quelle che hai definito con env_file:).
  3. Alla fine fa exec php-fpm -F. Da questo istante php-fpm diventa PID 1 e riceve correttamente i segnali di stop; lo script “scompare”.

3 — Cos’è php‑fpm e perché usarlo nel container

CaratteristicaSpiegazione
SignificatoPHP FastCGI Process Manager
RuoloMantiene 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_phpIn mod_php ogni processo Apache carica PHP → consumo RAM maggiore, meno flessibilità.
Perché -FObbliga 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

ProblemaCome lo risolve l’entrypoint
Devi generare la cache di configurazione dopo che le variabili d’ambiente sono presentiLo script è eseguito a runtime, quindi vede già tutte le variabili passate con env_file:.
Vuoi che il container termini pulito con docker stopexec "$@" 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 di CMD [...].
  • Nel tuo script usa set -e e exec "$@".
  • Avvia php-fpm in 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.