Stack self-hosting per un VPS piccolo: cosa entra in 2 GB e 4 GB di RAM
Uno stack self-hosted iniziale realistico su un VPS piccolo: Docker Compose, Caddy, Vaultwarden, Uptime Kuma e Forgejo, un budget di RAM per servizio, backup e sicurezza di base.
In breve: un VPS da 2 GB fa girare senza problemi un nucleo self-hosted composto da Caddy (reverse proxy HTTPS), Vaultwarden (password), Uptime Kuma (monitoraggio) e Forgejo (git) con Docker Compose, usando circa da 0,6 a 1 GB di RAM. Se aggiungi Nextcloud ti servono 4 GB; scegli strumenti più leggeri come Syncthing o File Browser e 2 GB bastano ancora.
Questa guida fornisce un file Compose funzionante, un budget di RAM per servizio e le due cose che la maggior parte dei setup self-hosted trascura finché non è troppo tardi: backup fuori sede e una superficie di rete blindata. I comandi presuppongono Debian 12/13 o Ubuntu 24.04 con Docker Engine e il plugin Compose installati dal repository ufficiale di Docker.
Budget di RAM per servizio
I valori sono la memoria residente tipica, da inattività a uso leggero, per uno-cinque utenti con SQLite dove supportato. I picchi durante aggiornamenti, clonazioni git di repository grandi o anteprime di Nextcloud possono essere più alti, quindi lascia almeno il 20% di margine e aggiungi un file di swap da 1 a 2 GB.
| Servizio | Ruolo | RAM tipica | Note |
|---|---|---|---|
| OS + sshd + journald | Sistema di base | 150–250 MB | Debian o Ubuntu minimale |
| Docker Engine + containerd | Runtime dei container | 80–120 MB | Costo fisso dell'uso dei container |
| Caddy | Reverse proxy, HTTPS automatico | 20–50 MB | Binario unico, nessun database |
| Vaultwarden | Server di password compatibile con Bitwarden | 20–60 MB | Scritto in Rust, SQLite |
| Uptime Kuma | Monitoraggio di uptime e certificati | 100–200 MB | Node.js; cresce con il numero di monitor |
| Forgejo | Hosting git, issue, hook CI | 150–300 MB | Go, SQLite va bene per team piccoli |
| Nextcloud + MariaDB + Redis | File, calendario, contatti | 600 MB–1.2 GB | Dominano i worker PHP-FPM |
| Syncthing | Sincronizzazione file, senza suite web | 50–150 MB | Alternativa più leggera a Nextcloud |
| File Browser | File manager web | 20–40 MB | Carica e condividi file via HTTPS |
| Radicale | CalDAV e CardDAV | 30–50 MB | Calendario e contatti senza Nextcloud |
Scegliere la dimensione del VPS
Lo stack di base (Caddy, Vaultwarden, Uptime Kuma, Forgejo) più il sistema arriva a circa 0,6–1 GB, il che entra in un server da 2 vCPU / 2 GB con spazio per Syncthing e Radicale. Nextcloud con MariaDB e Redis porta il totale a circa 1,5–2,2 GB, quindi 4 GB è il minimo realistico se vuoi la suite completa più tutto il resto. Conta anche il disco: i repository di Forgejo e i file sincronizzati crescono, mentre i servizi in sé richiedono solo pochi GB.
Su NoctisNode il piano Pulse (2 vCPU, 2 GB di RAM, 40 GB NVMe, $10 ogni 28 giorni) ospita lo stack di base, e Umbra (4 vCPU, 4 GB, 60 GB NVMe, $15 ogni 28 giorni) ospita la base più Nextcloud. Entrambi sono KVM con root completo e un IPv4 dedicato, e si possono pagare in Monero o altre cripto. Nulla in questa guida dipende dal provider.
File Docker Compose
Solo Caddy pubblica porte web; le app sono raggiungibili esclusivamente tramite la rete interna di Compose. Forgejo pubblica anche la porta 2222 per git via SSH, così l'OpenSSH dell'host resta sulla sua porta. Imposta `FORGEJO_TAG` in un file `.env` sulla versione major attuale di Forgejo e sostituisci i domini di esempio con i tuoi record DNS.
# /srv/stack/compose.yaml
services:
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./caddy/data:/data
- ./caddy/config:/config
vaultwarden:
image: vaultwarden/server:latest
restart: unless-stopped
environment:
DOMAIN: "https://vault.example.com"
SIGNUPS_ALLOWED: "true" # set to "false" after creating your account
volumes:
- ./vaultwarden:/data
uptime-kuma:
image: louislam/uptime-kuma:2
restart: unless-stopped
volumes:
- ./uptime-kuma:/app/data
forgejo:
image: codeberg.org/forgejo/forgejo:${FORGEJO_TAG}
restart: unless-stopped
environment:
USER_UID: "1000"
USER_GID: "1000"
FORGEJO__service__DISABLE_REGISTRATION: "true"
volumes:
- ./forgejo:/data
ports:
- "2222:22"
# /srv/stack/Caddyfile
# vault.example.com {
# reverse_proxy vaultwarden:80
# }
# status.example.com {
# reverse_proxy uptime-kuma:3001
# }
# git.example.com {
# reverse_proxy forgejo:3000
# }Avvio
- 01.Punta i record A (e AAAA) per `vault`, `status` e `git` all'IP del server, così Caddy può ottenere i certificati al primo avvio.
- 02.Crea `/srv/stack`, mettici `compose.yaml`, `Caddyfile` e `.env` ed esegui `docker compose up -d`.
- 03.Apri l'URL di Forgejo e completa l'installer; il primo account che crei da lì diventa l'amministratore, dato che la registrazione pubblica è disattivata.
- 04.Crea il tuo account Vaultwarden, poi imposta `SIGNUPS_ALLOWED` su `"false"` ed esegui di nuovo `docker compose up -d`. Lascia disattivato il pannello admin a meno che tu non imposti un `ADMIN_TOKEN` con hash Argon2.
- 05.Crea l'utente admin di Uptime Kuma subito dopo l'avvio, perché la pagina di configurazione è aperta a chiunque finché non lo fai.
- 06.Aggiungi monitor per ogni servizio e per la scadenza dei certificati, idealmente da una seconda posizione, dato che un monitor sullo stesso server non può segnalare il proprio down.
Note · Caddy gestisce l'HTTPS automaticamente. Per header, rate limit e routing più complesso, vedi la guida al reverse proxy con Caddy.
Backup che si ripristinano davvero
Tutto ciò che vale la pena conservare sta sotto `/srv/stack`: database SQLite, repository di Forgejo, certificati di Caddy e la tua configurazione. Non contare sugli snapshot del provider; tieni una tua copia cifrata e fuori sede con restic, come descritto nella guida ai backup con restic.
I file SQLite copiati mentre un servizio sta scrivendo possono risultare incoerenti. L'approccio sicuro più semplice su un server piccolo è fermare lo stack per il minuto che richiede il backup. Se aggiungi Nextcloud con MariaDB, esegui il dump del database con `mariadb-dump` prima del run di restic. Prova un ripristino in una directory temporanea almeno una volta: un backup mai ripristinato è solo un'ipotesi.
#!/bin/sh
# /usr/local/sbin/stack-backup (run nightly from cron or a systemd timer)
# needs RESTIC_REPOSITORY and RESTIC_PASSWORD_FILE in the environment
cd /srv/stack || exit 1
docker compose stop
rc=0
restic backup /srv/stack --tag stack || rc=$?
docker compose start
[ "$rc" -eq 0 ] || exit "$rc"
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --pruneSicurezza di base
- ▹SSH: solo chiavi, nessun login root con password, eventualmente una porta non standard; vedi la [guida all'hardening SSH](/guides/ssh-hardening).
- ▹Attenzione al firewall: le porte pubblicate da Docker aggirano le regole di `ufw`, perché Docker scrive le proprie catene iptables/nftables. Pubblica solo ciò che deve essere pubblico (80, 443, 2222) e non pubblicare mai porte di database o di amministrazione.
- ▹Aggiornamenti: attiva `unattended-upgrades` per l'host ed esegui `docker compose pull && docker compose up -d` con una cadenza che rispetti davvero.
- ▹Registrazione: tieni disattivate le iscrizioni pubbliche in Vaultwarden e Forgejo; invita invece gli utenti.
- ▹Cifratura del disco: metti `/srv` su una [root cifrata](/guides/luks-encrypted-root) così un'immagine del disco copiata non rivela nulla; su un server remoto usa lo [sblocco remoto LUKS via SSH](/guides/luks-remote-unlock-ssh) e preferisci il formato LUKS2 spiegato in [LUKS2 vs LUKS1](/guides/luks2-vs-luks1).
- ▹Segreti: `.env` e la directory dati di Vaultwarden devono essere leggibili solo da root (`chmod 600`/`700`).
FAQ
QQuanta RAM serve per il self-hosting?
AUno stack self-hosted di base con Caddy, Vaultwarden, Uptime Kuma e Forgejo gira in circa 0,6–1 GB inclusi OS e Docker, quindi un VPS da 2 GB è sufficiente. Aggiungendo Nextcloud con MariaDB e Redis, 4 GB diventa il minimo pratico.
QPosso far girare Nextcloud su un VPS da 2 GB?
AGira, ma insieme ad altri servizi lascia poco margine e diventa lento durante le anteprime o i picchi di sincronizzazione. Su 2 GB, Syncthing più File Browser e Radicale coprono file, calendario e contatti con una frazione della memoria.
QVaultwarden è sicuro da ospitare in self-hosting?
AVaultwarden conserva solo dati del vault cifrati end-to-end, quindi una compromissione del server non espone direttamente le password in chiaro. Tieni disattivate le iscrizioni, lascia il pannello admin disattivato o protetto da un token con hash, aggiorna regolarmente e fai il backup della sua directory dati.
QQual è il miglior reverse proxy per uno stack Docker self-hosted?
ACaddy è il più semplice per i setup piccoli, perché ottiene e rinnova automaticamente i certificati HTTPS con poche righe di configurazione. Funzionano anche Nginx e Traefik, ma richiedono più configurazione.
Qufw protegge i container Docker?
ANon per impostazione predefinita. Le porte pubblicate con l'opzione `ports:` di Docker aggirano ufw perché Docker inserisce le proprie regole firewall, quindi pubblica solo le porte che devono essere pubbliche.