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
- Un servizio = un repository = una pipeline. Tutto ciò che serve a costruire,
testare e rilasciare il servizio vive nel suo repository. Niente build manuali.
- 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.
- Configurazione fuori dall'immagine. Stessa immagine in ogni ambiente; ciò che
cambia (URL, credenziali, feature flag) entra via variabili d'ambiente e secret.
- 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.
- Ogni servizio è osservabile. Log su stdout/stderr in formato strutturato,
endpoint /health, metriche esposte dove sensato.
- 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
- Base image: immagini ufficiali, variante slim; la versione è pinnata
(es. python:3.12-slim, mai python:latest). L'elenco delle base image approvate
è mantenuto dai sistemisti.
- Multi-stage obbligatorio quando esiste una fase di build (compilazione, npm build).
- Utente non-root obbligatorio (
USER app). HEALTHCHECKdefinito nel Dockerfile o nel compose..dockerignoresempre presente (esclude.git, segreti, dipendenze locali).- Dimensione: obiettivo < 300 MB per servizio applicativo; scostamenti motivati nel README.
4. Naming e versionamento
- Registry:
registry.ente.it/<area>/<servizio>/<componente>
(es. registry.ente.it/servizi-cittadino/pratiche/api).
- Tag: SemVer
MAJOR.MINOR.PATCHcreati dalla pipeline sul tag Git corrispondente;
in aggiunta il tag sha-<commit> per tracciabilità. latest è consentito solo come
comodità di sviluppo locale.
- Una release = un tag Git = un'immagine = una riga nel CHANGELOG.
5. Pipeline standard (stage obbligatori)
| Stage | Contenuto | Blocca la pipeline? |
|---|---|---|
lint | lint del codice + hadolint sui Dockerfile | Sì |
test | test automatici del servizio | Sì |
build | build immagini + push su registry (sha-*; su tag Git anche semver) | Sì |
scan | Trivy su ogni immagine (vulnerabilità CRITICAL/HIGH) + SBOM come artefatto | CRITICAL: sì |
deploy-staging | automatico su main: compose pull && up -d + smoke test | Sì |
deploy-prod | manuale, solo da tag: backup pre-deploy, deploy, smoke test | Sì |
rollback | manuale: ridispiega la versione precedente | — |
6. Ambienti
- Sviluppo: macchina del singolo,
docker compose upcon override di sviluppo. - Staging: identico a produzione (stesse immagini, stesso compose prod), dati di test.
Ogni merge su main arriva qui automaticamente.
- Produzione: solo immagini con tag semver, solo via pipeline con approvazione manuale.
Nessun accesso SSH "per sistemare al volo": ogni modifica passa dal repository.
7. Segreti e configurazione
- Segreti in CI/CD variables (mascherate/protette) o vault dell'Ente; sui server
in file .env con permessi 600, gestiti dai sistemisti, mai committati.
.env.exampleelenca tutte le variabili richieste: è il contratto di configurazione
del servizio.
8. Dati, backup, log
- Volumi nominati con prefisso del servizio (
pratiche_dbdata). - Backup: dump pre-deploy automatico in pipeline + backup schedulato definito nel runbook.
- Log: stdout/stderr, JSON dove possibile; rotazione configurata a livello di daemon
(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:
- pipeline funzionante fino allo stage
scanincluso, nel GitLab dell'Ente; - immagini basate su base image approvate, non-root, con healthcheck;
README.mdedocs/runbook.mdcompilati;.env.examplecompleto (contratto di configurazione);- 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.