Progettato Per Essere Semplice in Produzione
Una delle cose che ho imparato attraverso molti progetti è che la complessità del deployment uccide la manutenzione. Se mettere una nuova versione in live richiede a qualcuno di ricordare una sequenza di passaggi, connettersi a più server, o avere la toolchain di build installata in produzione — le cose prima o poi andranno male.
La configurazione Docker di RAD-System è costruita attorno a un principio: i server di produzione dovrebbero essere il più stupidi possibile. Eseguono container. Non compilano codice. Il codice è su GitHub.
1. Lo Stack Containerizzato
L'intero sistema è orchestrato da un singolo docker-compose.yml. Ogni servizio viene eseguito in isolamento su una rete interna dedicata rad_network — il database non è mai esposto a internet pubblico. Solo le porte di cui l'applicazione ha bisogno vengono aperte.
La persistenza dei dati è gestita tramite montaggi di volume espliciti:
./Volumes/postgres— i dati del database sopravvivono ai riavvii del container e alle ricostruzioni./Config/backend/.env— le variabili di ambiente vengono iniettate al runtime, mai incorporate nell'immagine
2. PostgreSQL: Auto-Inizializzazione e Configurazione Personalizzata
Al primo avvio, il container PostgreSQL esegue qualsiasi script SQL o shell trovato in ./Config/postgres/init/, montato su /docker-entrypoint-initdb.d/. Questo crea utenti, database e installa estensioni automaticamente — nessun intervento manuale dopo il primo docker compose up.
File personalizzati postgresql.conf e pg_hba.conf sovrascrivono i default per corrispondere ai requisiti di performance e sicurezza specifici del sistema.
3. Hot Reload in Sviluppo, Configurazione Runtime in Produzione
Durante lo sviluppo, il codice sorgente del backend viene montato direttamente nel container tramite ./Volumes/backend/app. I cambiamenti al codice nel host attivano hot-reload dentro il container — il ciclo di sviluppo è veloce senza alcun tooling speciale.
Il frontend viene servito da Nginx. Il file app-config.json viene montato al runtime, non compilato nell'immagine. Cambiare l'URL dell'API in produzione significa modificare un file JSON e riavviare il container del frontend — nessuna ricostruzione.
4. Deployment Basato su Artifact: La Strategia Che Ha Eliminato Il Mio Build Server
Questa è la parte del sistema di cui sono più soddisfatto operativamente. I pipeline tradizionali CI/CD ricostruiscono le immagini Docker per ogni release. Questo richiede Node.js, npm e build tools sul server CI o dentro l'immagine. È lento, è complesso, e lega il tuo deployment all'infrastruttura di build.
RAD-System usa una strategia diversa: le immagini Docker sono runtimes statici. Il codice dell'applicazione è un artifact — un tarball versionato — iniettato tramite volumi.
Come funziona una release:
- Costruisci localmente —
build-be.shebuild-fe.shcompilano il codice e producono un tarball versionato (es.rad-backend-1.0.2.tgz) - Carica l'artifact sul server di produzione
- Deploy:
docker compose stop backend
tar -xzf rad-backend-1.0.2.tgz -C ./Volumes/backend/app
docker compose up -d backend
Cosa significa questo in pratica:
- Nessun build tool in produzione — il server esegue container, nient'altro
- Rollback istantaneo — estrai il tarball precedente, riavvia il container
- Immagini pulite — le immagini Docker cambiano solo quando il runtime (versione Node, config Nginx) cambia, non ad ogni cambio di codice
- Deploy veloce — estrarre un tarball è questione di secondi, non minuti
Ho usato questo pattern per anni. Funziona in modo affidabile, è facile automatizzarlo con un semplice script shell se necessario, ed è facile capire quando qualcosa va male.