🏛️ Da VM a Container — Docker & CI/CD per l'Ente

Linee guida architetturali per i servizi containerizzati dell'Ente

Queste linee guida definiscono lo standard unico con cui ogni servizio dell'Ente —

sviluppato internamente o da fornitori — viene containerizzato, versionato, rilasciato

ed esercito. Sono il distillato di ciò che il corso costruisce sull'app Pratiche e

si applicano invariate a ogni altro servizio.

1. Principi

  1. Un servizio = un repository = una pipeline. Tutto ciò che serve a costruire,

testare e rilasciare il servizio vive nel suo repository. Niente build manuali.

  1. L'immagine è l'unità di rilascio. In staging e produzione gira esattamente

l'immagine costruita dalla pipeline, identificata da un tag immutabile. Mai latest

negli ambienti gestiti.

  1. Configurazione fuori dall'immagine. Stessa immagine in ogni ambiente; ciò che

cambia (URL, credenziali, feature flag) entra via variabili d'ambiente e secret.

  1. Lo stato vive nei volumi o in servizi dedicati. I container sono usa-e-getta:

dati su volumi nominati o su DB/storage gestiti, mai nel filesystem del container.

  1. Ogni servizio è osservabile. Log su stdout/stderr in formato strutturato,

endpoint /health, metriche esposte dove sensato.

  1. Tutto è riproducibile da zero. Un collega (o un fornitore) con accesso al

repository deve poter ricostruire e avviare il servizio con i comandi del README.

2. Struttura standard del repository (blueprint)

nome-servizio/
├── README.md                 # cos'è, come si avvia, come si rilascia
├── .gitlab-ci.yml            # pipeline completa (lint→test→build→scan→deploy)
├── .env.example              # tutte le variabili, con valori di esempio, MAI segreti
├── compose.yaml              # stack base (comune a tutti gli ambienti)
├── compose.override.yaml    # sviluppo locale (bind mount, porte, tool di debug)
├── compose.prod.yaml         # produzione/staging (restart policy, risorse, logging)
├── docs/
│   ├── runbook.md            # operazioni: avvio, stop, backup, rollback, incidenti
│   └── architettura.md       # schema dei componenti e dei flussi
└── <componente>/             # una cartella per immagine da costruire (es. api/, web/)
    ├── Dockerfile
    └── ...codice o config...

3. Immagini

(es. python:3.12-slim, mai python:latest). L'elenco delle base image approvate

è mantenuto dai sistemisti.

4. Naming e versionamento

(es. registry.ente.it/servizi-cittadino/pratiche/api).

in aggiunta il tag sha-<commit> per tracciabilità. latest è consentito solo come

comodità di sviluppo locale.

5. Pipeline standard (stage obbligatori)

StageContenutoBlocca la pipeline?
lintlint del codice + hadolint sui Dockerfile
testtest automatici del servizio
buildbuild immagini + push su registry (sha-*; su tag Git anche semver)
scanTrivy su ogni immagine (vulnerabilità CRITICAL/HIGH) + SBOM come artefattoCRITICAL: sì
deploy-stagingautomatico su main: compose pull && up -d + smoke test
deploy-prodmanuale, solo da tag: backup pre-deploy, deploy, smoke test
rollbackmanuale: ridispiega la versione precedente

6. Ambienti

Ogni merge su main arriva qui automaticamente.

Nessun accesso SSH "per sistemare al volo": ogni modifica passa dal repository.

7. Segreti e configurazione

in file .env con permessi 600, gestiti dai sistemisti, mai committati.

del servizio.

8. Dati, backup, log

(log-opts: max-size 10m, max-file 3); raccolta centralizzata se il servizio è critico.

9. Requisiti per i fornitori

Ogni fornitura software deve consegnare un repository conforme al blueprint (sez. 2) e:

  1. pipeline funzionante fino allo stage scan incluso, nel GitLab dell'Ente;
  2. immagini basate su base image approvate, non-root, con healthcheck;
  3. README.md e docs/runbook.md compilati;
  4. .env.example completo (contratto di configurazione);
  5. nessun segreto nel repository o nelle immagini.

La conformità a queste linee guida è requisito di collaudo. La matrice dei ruoli

(documento 03) definisce chi fa cosa dopo la consegna.