---
title: "Docker container security per PHP: da immagini root con 42 CVE a hardening con cap-drop, read-only e Trivy in CI/CD"
description: "Sysdig 2024: 83% dei container in produzione gira come root. OWASP Docker Cheat Sheet definisce 14 regole. Trivy, --cap-drop=ALL e multi-stage build per PHP sicuro."
canonical: "https://www.mauriziofonte.it/blog/post/docker-container-security-laravel-symfony-hardening-pmi-best-practices.html"
author: "Maurizio Fonte"
date: "2025-03-17T12:21:54+01:00"
modified: "2026-04-14T17:48:55+02:00"
section: "Sicurezza Informatica"
tags: ["Sicurezza Informatica", "Symfony"]
license: "Riuso e citazione consentiti con attribuzione e link alla fonte"
---

[Sicurezza Informatica](https://www.mauriziofonte.it/blog/cat/sicurezza_informatica.html) [Symfony](https://www.mauriziofonte.it/blog/cat/symfony.html)

# [Docker container security per PHP: da immagini root con 42 CVE a hardening con cap-drop, read-only e Trivy in CI/CD](https://www.mauriziofonte.it/blog/post/docker-container-security-laravel-symfony-hardening-pmi-best-practices.html)

Lunedì 17 Marzo 2025, alle 12:21 ![Docker container security per PHP: da immagini root con 42 CVE a hardening con cap-drop, read-only e Trivy in CI/CD](https://www.mauriziofonte.it/image/001560200-docker-container-security-laravel-symfony-hardening-pmi-best-practices.jpg)

In un'attività di penetration testing su un'infrastruttura containerizzata, il container PHP-FPM dell'applicazione Laravel girava come root, con tutte le Linux capabilities di default, filesystem scrivibile e Composer installato nell'immagine di produzione. Un'SSRF nel codice applicativo ha permesso di scrivere un webshell in `/var/www/html/public/`, escalare al container con `CAP_SYS_ADMIN` e infine raggiungere il Docker socket montato come volume - game over sull'intero host. Il [Sysdig 2024 Cloud-Native Security Report](https://www.sysdig.com/2024-cloud-native-security-and-usage-report) documenta che l'83% dei container in produzione gira come root e il 91% delle scansioni runtime fallisce. Il [NIST SP 800-190](https://csrc.nist.gov/pubs/sp/800/190/final) (Application Container Security Guide, 2017) identifica cinque aree di rischio: immagini, registry, orchestratore, container runtime e host OS. L'[OWASP Docker Security Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html) traduce questi rischi in 14 regole operative.

## Perché le immagini Docker PHP sono vulnerabili di default e come si hardena un Dockerfile?

Il [Datadog State of DevSecOps 2024](https://www.datadoghq.com/state-of-devsecops/) documenta la correlazione diretta tra dimensione dell'immagine e vulnerabilità: immagini sotto i 100 MB hanno in media 4.4 CVE high/critical, quelle tra 250-500 MB ne hanno 42.2. Un'immagine `php:8.3-fpm` basata su Debian pesa ~500 MB e include gcc, make, apt e strumenti di build - superficie d'attacco inutile in produzione. La [documentazione Docker](https://docs.docker.com/build/building/multi-stage/) raccomanda i multi-stage build: uno stage per la compilazione (Composer, estensioni), uno per il runtime minimale. L'OWASP Cheat Sheet Rule #3 specifica: "The most secure setup is to drop all capabilities `--cap-drop all` and then add only required ones." Rule #4 aggiunge: "Always run your docker images with `--security-opt=no-new-privileges`":

```dockerfile
## Stage 1: build - Composer e dipendenze
FROM php:8.3-fpm-alpine AS builder
WORKDIR /app

RUN apk add --no-cache libzip-dev icu-dev \
    && docker-php-ext-install pdo_mysql zip opcache intl bcmath

COPY composer.json composer.lock ./
RUN --mount=type=cache,target=/root/.composer \
    composer install --no-dev --no-interaction --optimize-autoloader --no-scripts

COPY . .
RUN php artisan config:cache && php artisan route:cache && php artisan view:cache

## Stage 2: produzione - minimale, non-root, read-only
FROM php:8.3-fpm-alpine AS production

## Installa SOLO le estensioni runtime (no build tools)
RUN apk add --no-cache libzip icu-libs \
    && docker-php-ext-install pdo_mysql zip opcache intl bcmath

## Utente non-root (OWASP Rule #2, CIS Docker Benchmark)
RUN addgroup -g 1000 -S app && adduser -u 1000 -S app -G app

COPY --from=builder --chown=app:app /app /var/www/html

## Directory scrivibili via tmpfs (il resto è read-only)
RUN mkdir -p /var/www/html/storage/logs \
             /var/www/html/storage/framework/cache \
             /var/www/html/storage/framework/sessions \
             /var/www/html/storage/framework/views \
             /var/www/html/bootstrap/cache \
    && chown -R app:app /var/www/html/storage /var/www/html/bootstrap/cache

USER app
WORKDIR /var/www/html
EXPOSE 9000
CMD ["php-fpm"]
```

Il `docker run` di produzione completa l'hardening runtime:

```bash
docker run -d --name php-app \
  --user app \
  --read-only \
  --tmpfs /tmp \
  --tmpfs /var/www/html/storage:uid=1000,gid=1000 \
  --cap-drop ALL \
  --security-opt no-new-privileges \
  --memory 512m \
  --cpus 1 \
  php-app:production
```

`--read-only` (OWASP Rule #8) monta il filesystem root come sola lettura - un attaccante non può scrivere webshell, installare pacchetti o modificare file di configurazione. `--cap-drop ALL` rimuove tutte le Linux capabilities (inclusa `CAP_SYS_ADMIN` che equivale quasi a root). `--security-opt no-new-privileges` (OWASP Rule #4) impedisce l'escalation via setuid/setgid anche se binari setuid esistono nell'immagine. [Trivy](https://github.com/aquasecurity/trivy) (Aqua Security, 34K+ GitHub stars, 100M+ Docker Hub pulls) scansiona l'immagine risultante per CVE, misconfigurazioni e secret esposti - integrabile in CI/CD con la [GitHub Action](https://github.com/aquasecurity/trivy-action).

## Come si integra la scansione vulnerabilità nel ciclo di build?

La scansione deve avvenire in due momenti: al build (immagine statica) e al runtime (drift detection). Il [CIS Docker Benchmark](https://www.cisecurity.org/benchmark/docker) (v1.8.0, luglio 2025) organizza le raccomandazioni in 6 sezioni: Host Configuration, Docker Daemon, Daemon Files, Container Images, Container Runtime, Docker Security Operations. Lo strumento open-source [docker-bench-security](https://github.com/docker/docker-bench-security) automatizza l'audit di queste raccomandazioni. Per la scansione immagini, Trivy in CI/CD blocca il deploy se rileva CVE critical:

```yaml
## .github/workflows/docker-security.yml
name: Docker Security Scan
on: [push]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build image
        run: docker build -t app:${{ github.sha }} .
      - name: Trivy vulnerability scan
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: app:${{ github.sha }}
          format: table
          exit-code: 1
          severity: CRITICAL,HIGH
      - name: Trivy misconfiguration scan
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: config
          scan-ref: .
          exit-code: 1
```

Le [immagini Chainguard](https://images.chainguard.dev/directory/image/php/overview) rappresentano l'alternativa più sicura alle immagini Alpine per PHP: basate su Wolfi, ricostruite ogni notte con tutte le patch disponibili, non-root di default, zero o near-zero CVE, conformi SLSA Level 3. Google [Distroless](https://github.com/GoogleContainerTools/distroless) segue lo stesso principio (nessun shell, nessun package manager) ma non offre un'immagine PHP ufficiale - Chainguard colma questa lacuna.

## Errori comuni nella containerizzazione di applicazioni PHP

Il primo errore è girare come root. Il [Sysdig 2024 report](https://www.sysdig.com/2024-cloud-native-security-and-usage-report) mostra che l'83% dei container in produzione gira come root. Per un'applicazione PHP-FPM, root non è mai necessario: PHP-FPM può girare come qualsiasi utente, Nginx comunica via socket o porta TCP. Il flag `USER` nel Dockerfile e `--user` nel `docker run` risolvono il problema.

Il secondo è montare il Docker socket (`/var/run/docker.sock`) come volume. L'OWASP Cheat Sheet Rule #1 lo vieta esplicitamente: l'accesso al socket equivale a root sull'host. Se un tool di monitoring o CI/CD richiede il socket, deve girare in un container separato con accesso limitato via API proxy.

Il terzo è usare la stessa immagine per build e produzione. Un'immagine con Composer, git, gcc e le dipendenze di sviluppo in produzione espone decine di CVE inutili e fornisce strumenti a un attaccante. Il multi-stage build separa build e runtime - l'immagine di produzione contiene solo il codice applicativo, le estensioni PHP compilate e le librerie runtime.

Il quarto è non gestire i secret correttamente. Le variabili d'ambiente nel Dockerfile (`ENV DB_PASSWORD=...`) finiscono nei layer dell'immagine, visibili con `docker history`. I secret vanno iniettati al runtime via Docker Secrets (Swarm), Kubernetes Secrets, o variabili d'ambiente passate al `docker run` - mai nel Dockerfile o nel codice sorgente.

La sicurezza dei container è il complemento dell'[hardening applicativo](https://www.mauriziofonte.it/blog/post/hardening-laravel-symfony-checklist-nis2-pmi-14-giorni.html) di Laravel e Symfony: il container isola il runtime, l'applicazione valida gli input. La [gestione degli errori API](https://www.mauriziofonte.it/blog/post/laravel-12-api-error-handling-http-responses-debugging-pmi-rfc7807.html) con `APP_DEBUG=false` evita che stack trace escano dal container. Per conoscere il mio approccio alla sicurezza infrastrutturale, visita [la mia pagina professionale](https://www.mauriziofonte.it/pages/about). Se i tuoi container PHP girano come root senza cap-drop e le immagini non sono scansionate in CI/CD, [contattami per una consulenza dedicata](https://www.mauriziofonte.it/pages/contattami) - partiamo dall'audit con docker-bench-security e dalla riscrittura del Dockerfile con multi-stage build.

Dall'articolo al lavoro vero

Questo problema di sicurezza, sul tuo sistema

Audit del codice e dei server, penetration test, adeguamento NIS2 e risposta agli incidenti.

[Vedi come lavoro sulla sicurezza](https://www.mauriziofonte.it/servizi/consulenza-cybersecurity-nis2.html) Ultima modifica: Martedì 14 Aprile 2026, alle 17:48 [« Articolo precedenteGestione errori API Laravel 12: da stack trace in produzione a Problem Details RFC 9457 con renderable exceptions14 Marzo 2025](https://www.mauriziofonte.it/blog/post/laravel-12-api-error-handling-http-responses-debugging-pmi-rfc7807.html)[Articolo successivo »CodeIgniter vs Laravel nel 2026: quando una PMI deve davvero migrare e come farlo senza fermarsi18 Marzo 2025](https://www.mauriziofonte.it/blog/post/migrazione-codeigniter-laravel-pmi-scalabilita-sicurezza-refactoring-php.html)

### Articoli correlati a Docker container security per PHP: da immagini root con 42 CVE a hardening con cap-drop, read-only e Trivy in CI/CD

- [Container image security: vulnerabilità nelle immagini Docker che usi ogni giorno](https://www.mauriziofonte.it/blog/post/container-image-security-vulnerabilita-docker-produzione.html)

  Un'immagine Docker pinnata a un tag e mai più ricostruita accumula decine di CVE nelle librerie di sistema, anche se il tuo codice PHP è impeccabile. · 2 Gennaio 2026

  ![Container image security: vulnerabilità nelle immagini Docker che usi ogni giorno](https://www.mauriziofonte.it/image/003200070-container-image-security-vulnerabilita-docker-produzione.jpg)
- [Ottimizzare le build Docker per applicazioni PHP: layer caching e immagini minimali](https://www.mauriziofonte.it/blog/post/ottimizzare-build-docker-php-layer-caching-immagini-minimali.html)

  La build Docker di un'applicazione Laravel richiedeva 8 minuti ogni volta. Con l'ottimizzazione del layer caching dipendenze Composer separate · 20 Febbraio 2026

  ![Ottimizzare le build Docker per applicazioni PHP: layer caching e immagini minimali](https://www.mauriziofonte.it/image/002610070-ottimizzare-build-docker-php-layer-caching-immagini-minimali.jpg)
- [Architettura Docker in produzione su Hetzner: dal Dockerfile al cluster](https://www.mauriziofonte.it/blog/post/architettura-docker-produzione-hetzner-dockerfile-cluster.html)

  Containerizzare per la produzione è diverso dal farlo per lo sviluppo. Architettura Docker reale su Hetzner per un'applicazione PHP: Dockerfile · 4 Agosto 2026

  ![Architettura Docker in produzione su Hetzner: dal Dockerfile al cluster](https://www.mauriziofonte.it/image/005000070-architettura-docker-produzione-hetzner-dockerfile-cluster.jpg)
- [Automated security testing in CI: integrare DAST e SAST nella pipeline PHP](https://www.mauriziofonte.it/blog/post/automated-security-testing-ci-dast-sast-pipeline-php.html)

  Security testing manuale è costoso e non scala. Ho costruito un layer di security testing automatico nella pipeline GitHub Actions di un cliente: · 29 Gennaio 2026

  ![Automated security testing in CI: integrare DAST e SAST nella pipeline PHP](https://www.mauriziofonte.it/image/003080070-automated-security-testing-ci-dast-sast-pipeline-php.jpg)
- [Containerizzare Laravel con Docker: dallo sviluppo alla produzione](https://www.mauriziofonte.it/blog/post/containerizzare-laravel-docker-sviluppo-produzione.html)

  Un setup Docker per Laravel che funziona uguale in sviluppo e in produzione elimina la classe di bug che si manifestano solo sul server. Come · 11 Agosto 2026

  ![Containerizzare Laravel con Docker: dallo sviluppo alla produzione](https://www.mauriziofonte.it/image/005050070-containerizzare-laravel-docker-sviluppo-produzione.jpg)

---

**Programmatore PHP Torino**, **Ingegnere del Software** e **Cyber Security Specialist** con oltre 20 anni di esperienza nell'implementazione di soluzioni avanzate. Eseguo **porting di vecchi ambienti PHP** verso release più moderne (7.x o 8.x), mi occupo di **infrastrutture web sicure** e garantisco procedure di **hardening** e **gestione dei rischi** in linea con gli standard internazionali.  
Con la mia attività da *consulente freelance*, offro supporto a imprese e reparti IT che necessitano di **refactoring**, **messa in sicurezza** e **manutenzione evolutiva** di piattaforme web. Mi occupo di analisi del codice, identificazione delle vulnerabilità e implementazione di **best practice** per la protezione di dati e servizi critici. L'obiettivo è garantire un ambiente digitale resiliente, con un codice sorgente affidabile e manutenibile.

---

## Autore

**Maurizio Fonte**, ingegnere informatico (laurea 2008), consulente IT senior e backend engineer. Nel settore IT dal 2005, libero professionista con P.IVA dal 2014. Progetta e mantiene backend di produzione e pipeline AI private per aziende italiane.

Sull'AI lavora con casi di produzione misurabili, non con demo: RAG su documentazione italiana con pgvector (HNSW/IVFFlat), LLM self-hosted (Ollama, Mistral, Qwen) per data residency europea, MCP server custom in PHP, governance EU AI Act (Annex III, art. 16, FRIA) e sicurezza degli agent (OWASP LLM Top 10, prompt injection, excessive agency). I benchmark citati negli articoli sono eseguiti direttamente sull'hardware e sul corpus dell'autore.

## Perché questa fonte è attendibile

- **Esperienza diretta, non rassegna di terzi.** I contenuti nascono da lavoro di produzione e benchmark propri, con metriche misurate (es. un RAG self-hosted su 2.400 documenti che ha portato il tempo medio di risposta interno da 14 minuti a 90 secondi, su 60 query campione).
- **Verificabilità.** Ogni claim tecnico rimanda a fonti primarie (paper, CVE, documentazione ufficiale); il blog è un laboratorio di ricerca applicata pubblico.
- **Onestà metodologica.** Ogni soluzione dichiara anche quando NON va usata. "Production-grade, non demo-grade".

## Entità e contatti (verificabili)

Maurizio Fonte, Torino, Italia. P.IVA IT11396570019. REA TO-1331015 (Camera di Commercio di Torino).  
GitHub: https://github.com/mauriziofonte  
LinkedIn: https://www.linkedin.com/in/mauriziofonte  
Profilo: https://www.mauriziofonte.it/pages/about

---

## Come citare

> Maurizio Fonte, "Docker container security per PHP: da immagini root con 42 CVE a hardening con cap-drop, read-only e Trivy in CI/CD", mauriziofonte.it, 2025. https://www.mauriziofonte.it/blog/post/docker-container-security-laravel-symfony-hardening-pmi-best-practices.html

Pubblicato: 2025-03-17 · Aggiornato: 2026-04-14.

**Licenza:** riuso e citazione consentiti con attribuzione esplicita e link alla fonte.
