0005. Distribuzione come immagine container con CLI
- Stato: Accettata
- Data: 2026-06-03
- Decisori: Team BI/ETL
Contesto
Il servizio ETL deve essere distribuibile e, tipicamente, eseguito sull'infrastruttura del cliente (a volte gestita da noi, a volte dal cliente). Non è un'app always-on: è un carico batch/schedulato. Serve un'unità di distribuzione portabile e una configurazione che non leghi l'artefatto a un ambiente specifico.
Decisione
Distribuiamo il runner come immagine container (Dockerfile multi-stage) con entrypoint una CLI (etl run <pipeline> / etl list) basata su un registry di pipeline.
- Registry: l'immagine è pubblicata su un registry (punto di partenza ECR, come gli altri servizi noeva; per altri target cambia solo il registry).
- Config solo da env: nessun segreto nell'immagine; in produzione le variabili arrivano da un secret manager (AWS Secrets Manager / SSM). I loader supportano prefissi per ambiente.
- Batch, non daemon: un container = una run di pipeline, poi termina. Lo scheduling è esterno (cron / ECS Scheduled Task / EventBridge), reso sicuro dall'idempotenza dei sink.
- CLI come unico entrypoint: le pipeline si registrano in
src/pipelines/registry.ts; ognirun.tsespone unRunnablePipeline(wiring dei connettori), non si auto-esegue. - Tag immagine: ogni deploy pubblica sempre
latest+ un tag temporale immutabile (YYYYmmdd-HHMMSS); tag versione opzionale.deploy-ecr.shautomatizza build multi-arch e push.
Uso attuale (rivedibile)
Per ora l'immagine su ECR è pensata per essere scaricata ed eseguita in locale su Docker Desktop (docker pull + docker run). La build multi-arch garantisce esecuzione nativa su Apple Silicon. L'esecuzione gestita in cloud (ECS/Fargate, scheduling) non è ancora attivata: sarà valutata se/quando servirà.
Alternative considerate
- Solo pacchetto npm — utile per il riuso come libreria, ma non "esegue" il servizio; resta possibile in parallelo (publishConfig già su GitHub Packages).
- Servizio always-on + scheduler interno (PM2) — PM2 è un daemon manager, non adatto a job batch; complica retry/observability. Scartato.
- Orchestratore (Airflow/Dagster) — Python, fuori dallo stack TS; overkill ora. Rinviato (eventualmente Temporal TS).
Conseguenze
- Positive: un solo artefatto portabile (nostro ECS / ECS del cliente / Docker locale); config per-ambiente via env; scheduling libero grazie all'idempotenza; entrypoint uniforme.
- Costi/limiti:
- La creazione delle tabelle di destinazione resta una migration esterna (DDL versionata in
sql/), non fatta dalla pipeline. - Il container deve avere accesso di rete a sorgente e sink (anche su VPC diverse).
- La pubblicazione su ECR e lo scheduling (ECS/cron) sono passi successivi, specifici per cliente.
- La creazione delle tabelle di destinazione resta una migration esterna (DDL versionata in

