15 settembre 2026

Dal laptop alla produzione: guida pratica a deploy, sicurezza e automazione per web app full‑stack

Un percorso “hands-on” su Ubuntu: server, runtime, reverse proxy, HTTPS, backup e CI/CD per pubblicare applicazioni in modo affidabile.

Portare una web app dalla macchina locale a un ambiente pubblico e sicuro richiede competenze che vanno oltre il framework: Linux, rete, processi, certificati, reverse proxy, backup e automazione. In questo articolo raccolgo un approccio pratico e progressivo: prima si costruisce tutto a mano su un server Ubuntu (come una VPS), poi si automatizza con pipeline CI/CD. L’obiettivo è capire davvero cosa succede “dietro le quinte” e acquisire un metodo riutilizzabile con qualunque stack (FastAPI/Vue, Node, Ruby, ecc.).

Portare una web app dal tuo laptop a un ambiente di produzione pubblico, sicuro e manutenibile è uno di quei passaggi che separano il “funziona sul mio PC” da un prodotto davvero utilizzabile. È anche il punto in cui tanti frontend (e non solo) iniziano a toccare con mano concetti come: SSH, firewall, reverse proxy, certificati TLS, processi in background, log, backup e automazione.

Qui trovi un percorso tecnico ma lineare per arrivarci: prima si configura tutto manualmente su Ubuntu, poi si passa all’automazione con CI/CD. L’ordine non è un dettaglio: fare le cose “a mano” una volta ti dà consapevolezza, e rende più semplice scegliere in seguito soluzioni gestite (PaaS, hosting automatici, ecc.) senza usarle “alla cieca”.


Il problema reale: la tua app non è raggiungibile

In locale hai:

  • un frontend (Vue/React/SPA o SSR)
  • un backend (Python/Node/Ruby…)
  • magari un database o un servizio di ricerca

Finché gira sul tuo computer, gli utenti non possono accedervi. La soluzione è spostare codice e runtime in un ambiente di produzione (tipicamente una VPS), esporre solo ciò che serve e proteggere il tutto.

Sì, esistono piattaforme che collegano GitHub e fanno “deploy con un click”. Sono utilissime, ma iniziare da lì spesso significa non capire:

  • dove finiscono i processi
  • come passa il traffico
  • chi può entrare nel server
  • come ruotano i certificati
  • cosa fai quando qualcosa si rompe alle 3 di notte

Filosofia operativa: manuale prima, automatico dopo

Un buon percorso di apprendimento segue questa sequenza:

  1. Provisioning del server e accesso sicuro
  2. Installazione dei runtime e avvio dei servizi applicativi
  3. Gestione di dati/servizi di supporto (es. motore di ricerca)
  4. HTTPS, DNS, CDN e hardening
  5. CI/CD e quality gates
  6. Monitoraggio, log, performance e manutenzione

Il valore è nel metodo: cambiano i comandi e i package, ma la struttura resta la stessa per quasi qualsiasi stack.


1) Fondamenta: server Ubuntu e accesso sicuro

Un setup solido parte prima ancora di clonare il repo.

VPS e sistema operativo

Scegli una VPS (DigitalOcean, Linode, AWS, ecc.) e installa una versione LTS di Ubuntu (ad esempio Ubuntu 24.04 LTS). L’hardware può essere virtuale o fisico: ciò che conta è che tu abbia un sistema Linux accessibile via rete.

SSH key, niente password

La misura più importante “subito” è questa:

  • autenticazione via chiave SSH
  • disabilitare login con password

Riduci drasticamente brute force e credential stuffing, perché non c’è una password da indovinare.

No root login

Altro caposaldo:

  • creare un utente non-root
  • disabilitare il login diretto di root

Così anche in caso di compromissione riduci l’impatto e aumenti la tracciabilità.

Firewall: esporre solo ciò che serve

Appena il server è online, qualcuno lo scannerizza. Sempre. Configura un firewall (es. UFW) per consentire solo:

  • SSH (porta eventualmente non standard, ma non è “sicurezza” da sola)
  • HTTP/HTTPS quando serviranno
  • niente porte applicative aperte “per comodità”

2) Runtime applicativo: backend stabile e reverse proxy

A questo punto puoi portare il codice sul server (clone da Git o trasferimento). Poi serve farlo girare in modo ripetibile.

Python/Node e ambienti isolati

Se hai un backend Python:

  • installa Python e dipendenze di sistema
  • crea un virtualenv
  • installa requirements in modo deterministico

Attenzione alle VPS piccole: la swap

Su macchine con poca RAM potresti incontrare errori durante build/compilazioni di dipendenze. Una soluzione pragmatica è configurare swap usando spazio disco, così da evitare installazioni che falliscono per OOM (Out Of Memory).

Process manager e application server

Per un backend Python tipico (es. FastAPI) è comune combinare:

  • Uvicorn (ASGI server)
  • Gunicorn (process manager / multi-worker)
  • Supervisor o systemd per mantenere i processi attivi e riavviarli

L’obiettivo non è “quale tool è il migliore”, ma ottenere:

  • processi che ripartono dopo crash
  • log gestibili
  • avvio automatico al reboot

Nginx come reverse proxy (con Unix socket)

Il pattern più diffuso in produzione:

  • Nginx esposto su 80/443
  • backend non esposto direttamente a Internet
  • comunicazione interna via Unix socket (o loopback)

Vantaggi: migliore controllo su header, timeouts, buffering, rate limiting, compressione, e soprattutto superficie d’attacco ridotta.


3) Servizi di supporto: dati, ricerca e backup

Molte app “vere” non sono solo frontend+API. C’è spesso un pezzo in più: ricerca, job queue, cache, ecc.

Migrare dati dal locale al server

Serve un flusso chiaro per:

  • esportare/dumpare i dati in locale
  • trasferirli
  • ripristinarli sul server

Self-host di un motore di ricerca

Se ospiti un search engine (es. Meilisearch) sulla stessa VPS:

  • crea un utente dedicato (separazione privilegi)
  • configura un servizio systemd per esecuzione in background
  • evita di esporre porte pubbliche se non necessario

Backup automatici

Non basta “fare backup ogni tanto”. Serve:

  • script schedulati (cron/systemd timers)
  • rotazione e retention
  • test periodici di restore

Il backup che non hai mai provato a ripristinare è solo una speranza.

Dashboard in sicurezza: SSH tunneling

Per accedere a dashboard/strumenti interni senza aprire porte:

  • usa SSH tunneling

Ottieni accesso locale al servizio remoto senza esporlo su Internet.


4) DNS, HTTPS, CDN e hardening

Quando l’app è online, arrivano due esigenze immediate: un dominio e una connessione sicura.

Dominio e record DNS

Collega il dominio alla VPS configurando record DNS (A/AAAA, eventualmente CNAME). È un passaggio spesso sottovalutato, ma fondamentale per:

  • routing corretto
  • certificati TLS
  • CDN

HTTPS con Let’s Encrypt (e rinnovo automatico)

Let’s Encrypt rilascia certificati con durata limitata (tipicamente 90 giorni). Quindi serve:

  • emissione del certificato
  • rinnovo automatico
  • reload di Nginx al rinnovo

Se non automatizzi, prima o poi ti scade in un weekend.

CDN per asset statici

Gli asset frontend sono perfetti per una CDN:

  • riduci latenza globale
  • scarichi traffico dalla VPS
  • migliori performance percepite

Una strategia comune: backend sulla VPS, frontend statico servito via CDN, con caching aggressivo e invalidazione controllata.


5) Automazione: dal deploy manuale a CI/CD

Dopo aver fatto un deploy manuale completo, l’automazione ha finalmente senso: sai cosa stai automatizzando.

Protezione del branch principale

Regola pratica:

  • niente push diretti su main/master
  • passare da branch + PR
  • required checks prima del merge

pre-commit: qualità prima ancora della PR

pre-commit permette di applicare regole locali al commit:

  • formatting
  • lint
  • controlli banali ma costosi se scoperti tardi

Ti evita di “sporcare” la history con commit correttivi.

GitHub Actions: pipeline ripetibile

Una pipeline tipica:

  • lint/format
  • unit test
  • (poi) integration/E2E

E soprattutto: bloccare il merge se i check falliscono. È il modo più semplice per ridurre regressioni e deploy rotti.

Deploy con un click (o senza click)

Una volta che main è “verde”, puoi arrivare a:

  • deploy automatico
  • oppure deploy manuale ma tracciato

Il punto non è solo la comodità: è la riproducibilità.


6) Operazioni: log, monitoraggio, difesa dai bot e performance

Quando l’app è in produzione, il lavoro non è finito: è iniziato.

Log Nginx e analisi leggibile

I log grezzi sono utili, ma poco fruibili. Uno strumento come GoAccess può trasformarli in report e dashboard per capire:

  • endpoint più richiesti
  • errori
  • picchi di traffico
  • user agent sospetti

Monitorare risorse

Un tool come btop rende immediato vedere:

  • RAM/swap
  • CPU
  • I/O disco
  • processi che degradano le performance

Bloccare IP malevoli

Dai log emergono pattern non umani (hit enormi, scanning). Ha senso:

  • bloccare IP aggressivi
  • applicare rate limiting
  • ridurre sprechi di risorse

Load testing

Con una libreria come Locust puoi simulare utenti e stimare:

  • throughput sostenibile
  • latenza sotto carico
  • punto di rottura

È uno dei modi più concreti per capire “quanto regge” la tua architettura prima che lo scoprano gli utenti.


Sintesi: un metodo riutilizzabile per qualsiasi stack

Il valore di questo percorso non è legato a FastAPI o Vue, a un provider specifico o a un tool “di moda”. È un modello mentale:

  • metti in sicurezza l’accesso (SSH, utenti, firewall)
  • separa responsabilità (reverse proxy, servizi dedicati, systemd)
  • cura affidabilità (backup, rinnovi, restart)
  • automatizza dopo aver capito (pre-commit, CI, deploy)
  • osserva e difendi (log, monitoraggio, blocchi, test di carico)

Una volta che hai fatto almeno un deploy completo in questo modo, le piattaforme gestite diventano una scelta consapevole: saprai cosa stanno facendo al posto tuo, quali compromessi accetti e dove intervenire quando qualcosa non torna.