Cosa succede da git push
alla produzione.
Questo sito non è una vetrina statica: è costruito come una piattaforma reale, con CI/CD, quality gate, osservabilità e AI integrata. Ho scomposto tutto fase per fase — non per riempire, ma per mostrare cosa controllo davvero prima di considerare una release pronta.
Per un portfolio personale questa architettura è esagerata, e va benissimo così. Volevo una piattaforma vera, production-ready — il portfolio è la dimostrazione pratica di come costruisco i prodotti dei clienti.
Il flusso, fase per fase
Push su GitHub → trigger Actions
Un push su branch main avvia automaticamente la GitHub Action del repository coinvolto (frontend o backend). Nessun deploy fatto a mano: da qui in poi il processo è deterministico e tracciato.
Runner self-hosted sulla VPS
Il job viene preso in carico da un runner self-hosted installato direttamente sul server di produzione. Nessun costo di minuti CI, nessun trasferimento di rete tra runner e server: tutto gira già dove deve girare.
SonarQube analysis (solo backend)
Prima di toccare qualsiasi file sul server, il workflow backend esegue mvn clean package sonar:sonar: analisi statica del codice Java per code smell, vulnerabilità e duplicazioni. Il quality gate è configurato come asincrono — il risultato è tracciato ma non blocca il deploy.
rsync del sorgente sulla VPS
Il codice sorgente del repository viene copiato nella cartella di destinazione sul server via rsync, escludendo .git. Non vengono trasferiti artefatti compilati: la compilazione avviene dopo, dentro Docker.
docker compose build
Docker ricostruisce l'immagine dal Dockerfile locale presente nella cartella copiata. È qui che avviene la compilazione vera: il Dockerfile del frontend esegue ng build e copia il dist in Nginx; quello del backend esegue mvn package e incapsula il JAR. Le immagini finali non contengono sorgenti né tool di build.
docker compose up -d
Compose riavvia solo il container aggiornato (portfolio_frontend o portfolio_backend) senza toccare il resto della stack. Il vecchio container viene sostituito con quello nuovo appena l'immagine è pronta.
Nginx reverse proxy
Nginx è sempre in esecuzione e continua a rispondere durante il deploy. Gestisce TLS, header di sicurezza e routing: serve i file statici del frontend direttamente, passa le chiamate /api/* al container Spring Boot.
Osservabilità: Loki + Grafana
Loki raccoglie i log da tutti i container Docker e da Nginx. Grafana li espone con dashboard real-time. Se qualcosa si rompe, lo scopro io prima degli utenti.
Come sono collegati i pezzi
Due flussi principali: le richieste HTTP e il ciclo RAG per il chatbot AI.
Un deploy, in poche righe
L'intero rilascio sta in un file YAML. Leggibile, versionato, ripetibile: un push fa tutto il resto.
runs-on: self-hosted
steps:
- ./mvnw clean package sonar:sonar # quality gate asincrono
- rm -rf /home/ubuntu/portfolio/backend/*
- rsync -av --exclude='.git' ./ /home/ubuntu/portfolio/backend/
- docker compose build --no-cache portfolio_backend
- docker compose up -d portfolio_backend
# deploy-portfolio-frontend.yml
runs-on: self-hosted
steps:
- rm -rf /home/ubuntu/portfolio/frontend/*
- rsync -av --exclude='.git' ./ /home/ubuntu/portfolio/frontend/
- docker compose build --no-cache portfolio_frontend
- docker compose up -d portfolio_frontend
Ti serve qualcuno che pensi anche al «dopo il deploy»?
Architettura, sicurezza, delivery e osservabilità non sono un extra: sono il lavoro vero. Parliamone.
