Ospitare la propria IA su un VPS Linux con Ollama e Open WebUI significa tenere le conversazioni sul proprio server e smettere di pagare a richiesta. Il problema: l'API di Ollama non ha alcuna autenticazione, quindi una porta 11434 aperta su Internet è IA gratuita per chiunque la trovi. Questa guida Le mostra un'installazione in cui solo Nginx, in HTTPS, è raggiungibile dall'esterno.
Perché un'istanza Ollama esposta è un problema
Ollama offre un'API REST molto comoda, ma senza password né chiave. Chiunque raggiunga la porta può elencare i Suoi modelli, scaricarne di nuovi fino a riempire il disco, cancellarli o avviare generazioni che tengono la CPU del VPS al massimo. I manutentori ritengono che l'autenticazione spetti a un reverse proxy: tocca quindi a Lei aggiungerla.
Il rischio è concreto. A febbraio 2026 il motore di ricerca di fughe di dati LeakIX contava oltre 12.000 istanze Ollama accessibili senza autenticazione. Nello stesso anno una falla di gravità elevata (CVE-2026-7482, soprannominata «Bleeding Llama») permetteva di leggere la memoria di un server Ollama raggiungibile, senza alcuna credenziale. Un'istanza che ascolta solo in locale è semplicemente fuori portata per questo tipo di attacco.
L'architettura che realizzeremo
- Ollama ascolta solo su
127.0.0.1:11434. - Open WebUI gira in Docker e ascolta solo su
127.0.0.1:3000. - Nginx è l'unico servizio pubblico: riceve il traffico HTTPS sulla porta 443 e lo inoltra a Open WebUI.
- Il firewall consente solo SSH, HTTP (per il certificato) e HTTPS.
- Open WebUI gestisce gli account: un amministratore, registrazioni chiuse.
La guida presuppone un VPS Linux con Ubuntu 24.04 o Debian 12, accesso sudo, Docker già installato e un sottodominio, per esempio ia.suo-dominio.it, che punti all'indirizzo IP del server.
Quale VPS scegliere: tabella RAM e CPU senza GPU
Su un VPS senza scheda grafica tutto dipende dalla RAM e dal numero di core. Il modello deve stare interamente in memoria, con un margine per il contesto della conversazione, per Open WebUI (calcoli circa 1 GB) e per il sistema. Le dimensioni qui sotto sono quelle delle versioni predefinite (quantizzate a 4 bit) pubblicate nella libreria di Ollama.
| VPS | Modelli realistici | Esempi (dimensione del download) | Uso |
|---|---|---|---|
| 4 GB di RAM, 2 vCPU | Da 1 a 3 miliardi di parametri | gemma3:1b (806 MB), qwen3:1.7b (1,4 GB), llama3.2:3b (2,0 GB) | Test, riassunti brevi, piccolo assistente |
| 8 GB di RAM, 3 vCPU | Fino a 4B comodamente, 8B possibile ma al limite | qwen3:4b (2,5 GB), gemma3:4b (3,4 GB), qwen3:8b (5,2 GB) | Uso personale quotidiano |
| 12 GB di RAM, 4 vCPU | 8B comodamente, 12-14B possibile ma al limite | qwen3:8b (5,2 GB), gemma3:12b (8,2 GB), qwen3:14b (9,3 GB) | Scrittura, codice, piccolo team |
| 32 GB di RAM o più (server dedicato) | Da 27 a 32B | gemma3:27b (17 GB), qwen3:32b (20 GB) | Qualità superiore, risposte lente senza GPU |
Da SoLinux questo corrisponde al VPS Linux 04G (4 GB, 2 core, 45 GB NVMe), al VPS Linux 08G (8 GB, 3 core, 50 GB NVMe) e al VPS Linux 12G (12 GB, 4 core, 70 GB NVMe), senza vincoli, a partire da 7 € al mese per il 04G, disponibili in Francia, Germania e a New York. Per un uso regolare il 08G è il miglior punto di partenza; il 12G conviene non appena desidera un modello 8B con margine o più utenti.
Sia realista sulla velocità: senza GPU un modello 7-8B scrive la risposta parola per parola, a poche parole al secondo, e la CPU resta al 100 % durante la generazione. I modelli da 3-4B sono spesso il miglior compromesso. Lo storage NVMe conta soprattutto per il caricamento iniziale del modello in memoria.
Passo 1: preparare il server e il firewall
Aggiorni prima il sistema, poi chiuda tutto ciò che non è indispensabile. Con UFW:
sudo apt update && sudo apt upgrade -y
sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
Se preferisce usare direttamente nftables (non insieme a UFW), ecco l'equivalente minimo per la catena di input, da inserire in /etc/nftables.conf:
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif "lo" accept
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
tcp dport { 22, 80, 443 } accept
}
}
sudo nft -c -f /etc/nftables.conf # verifica la sintassi
sudo systemctl enable --now nftables
Trappola classica: una porta pubblicata da Docker con -p 3000:8080 è aperta su tutte le interfacce e aggira le regole di UFW, perché Docker scrive le proprie regole di firewall. Per questo in questa guida non pubblichiamo nessuna porta Docker.
Passo 2: installare Ollama e tenerlo in locale
Ollama si installa su Linux con lo script ufficiale, che crea un utente ollama e un servizio systemd:
curl -fsSL https://ollama.com/install.sh | sh
Verifichi poi che il servizio sia attivo:
ollama --version
sudo systemctl enable --now ollama
sudo systemctl status ollama
Per impostazione predefinita Ollama ascolta su 127.0.0.1:11434. Molti tutorial fanno impostare OLLAMA_HOST su 0.0.0.0 perché Docker possa raggiungerlo: è proprio ciò che espone l'API. Fissi invece l'indirizzo locale in modo esplicito, con un override di systemd che sopravvive agli aggiornamenti:
sudo systemctl edit ollama
Aggiunga queste righe nella zona prevista:
[Service]
Environment="OLLAMA_HOST=127.0.0.1:11434"
Environment="OLLAMA_MAX_LOADED_MODELS=1"
Environment="OLLAMA_NUM_PARALLEL=1"
Le ultime due variabili limitano Ollama a un modello caricato e a una richiesta alla volta, così la RAM di un VPS senza GPU non si satura. Ricarichi e controlli l'ascolto:
sudo systemctl daemon-reload
sudo systemctl restart ollama
sudo ss -tlnp | grep 11434
# atteso: 127.0.0.1:11434, mai 0.0.0.0:11434 né [::]:11434
curl http://127.0.0.1:11434
# atteso: Ollama is running
Scarichi poi un modello adatto al Suo VPS e lo provi da riga di comando:
ollama pull qwen3:4b
ollama run qwen3:4b "Spiega in una frase che cos'è un reverse proxy."
ollama list
Passo 3: avviare Open WebUI con Docker, senza porta pubblica
Il comando di avvio rapido di Open WebUI pubblica la porta 3000 e raggiunge Ollama tramite host.docker.internal, costringendo Ollama ad ascoltare su tutte le interfacce. Noi procediamo diversamente: il container condivide lo stack di rete dell'host (--network=host), raggiunge Ollama su 127.0.0.1 e ascolta a sua volta solo su 127.0.0.1:3000 grazie alle variabili HOST e PORT.
# chiave segreta fissa: senza, le sessioni si perdono a ogni riavvio
sudo mkdir -p /etc/open-webui
openssl rand -hex 32 | sudo tee /etc/open-webui/secret > /dev/null
sudo chmod 600 /etc/open-webui/secret
DOMINIO=ia.suo-dominio.it # il Suo sottodominio
sudo docker run -d --name open-webui \
--network=host \
-e HOST=127.0.0.1 \
-e PORT=3000 \
-e OLLAMA_BASE_URL=http://127.0.0.1:11434 \
-e WEBUI_SECRET_KEY="$(sudo cat /etc/open-webui/secret)" \
-e CORS_ALLOW_ORIGIN="https://$DOMINIO" \
-v open-webui:/app/backend/data \
--restart always \
ghcr.io/open-webui/open-webui:main
Il volume open-webui conserva account, conversazioni e impostazioni. In produzione può sostituire il tag main con un numero di versione preciso, così decide Lei quando aggiornare. Controlli l'ascolto dopo un minuto (il primo avvio richiede un po' di tempo):
sudo ss -tlnp | grep 3000
# atteso: 127.0.0.1:3000
curl -I http://127.0.0.1:3000
Passo 4: creare l'account amministratore prima di esporre qualsiasi cosa
Il primo account creato su Open WebUI diventa amministratore. Non lasci quel posto a uno sconosciuto che trovi il Suo sottodominio prima di Lei: lo crei prima di configurare Nginx, tramite un tunnel SSH. Dal Suo computer:
ssh -L 3000:127.0.0.1:3000 utente@IP_DEL_VPS
Apra poi http://localhost:3000 nel browser del Suo computer e crei l'account amministratore con una password lunga e unica. Quindi, nelle impostazioni di amministrazione (sezione utenti o registrazioni, a seconda della versione):
- disattivi le nuove registrazioni;
- se deve lasciarle aperte per un po', mantenga il ruolo predefinito dei nuovi utenti su in attesa (pending), così approva Lei ogni account;
- crei personalmente gli account dei Suoi collaboratori dalla gestione utenti.
Non disattivi mai l'autenticazione (WEBUI_AUTH=False) su un'istanza raggiungibile da Internet.
Passo 5: Nginx in HTTPS davanti a Open WebUI
Installi Nginx e Certbot:
sudo apt install -y nginx certbot python3-certbot-nginx
Aggiunga un limite ai tentativi di accesso in /etc/nginx/conf.d/limiti.conf:
limit_req_zone $binary_remote_addr zone=owui_login:10m rate=5r/m;
Crei poi /etc/nginx/sites-available/open-webui. Open WebUI usa i WebSocket e trasmette le risposte in streaming: servono quindi HTTP/1.1, le intestazioni Upgrade e il buffering disattivato, altrimenti le risposte arrivano in un blocco unico o si interrompono.
server {
listen 80;
server_name ia.suo-dominio.it;
client_max_body_size 50M;
# limita i tentativi di password
location = /api/v1/auths/signin {
limit_req zone=owui_login burst=5 nodelay;
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 1800s;
proxy_send_timeout 1800s;
}
}
Attivi il sito, verifichi la configurazione e richieda il certificato. Certbot aggiunge da solo il blocco HTTPS sulla porta 443 e il reindirizzamento da HTTP:
sudo ln -s /etc/nginx/sites-available/open-webui /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d ia.suo-dominio.it --redirect
sudo certbot renew --dry-run
Per un piccolo team può aggiungere una seconda barriera con auth_basic nel blocco location /, oppure limitare l'accesso a pochi indirizzi IP con allow e deny. Queste protezioni si aggiungono all'account Open WebUI, non lo sostituiscono.
Verificare che nulla sia esposto
Sul server, elenchi le porte in ascolto: solo 22, 80 e 443 devono comparire su un indirizzo pubblico.
sudo ss -tlnp
Dal Suo computer, provi l'indirizzo IP del VPS: le porte 11434 e 3000 devono rifiutare la connessione o non rispondere. Solo il Suo sottodominio in HTTPS, aperto nel browser, deve mostrare la pagina di accesso.
nc -zv -w 3 IP_DEL_VPS 11434 # deve fallire
nc -zv -w 3 IP_DEL_VPS 3000 # deve fallire
Mantenere l'installazione aggiornata
- Ollama: riesegua lo script di installazione ufficiale. L'override di systemd viene mantenuto; controlli comunque l'ascolto con
ss -tlnpdopo ogni aggiornamento. La falla CVE-2026-7482 è corretta dalla versione 0.17.1: verifichi la Sua conollama --versione non lasci girare una versione vecchia. - Open WebUI:
docker pulldell'immagine, poidocker stop,docker rme lo stesso comandodocker run. Il volume conserva i Suoi dati. - Backup: salvi regolarmente il volume
open-webui(account e conversazioni); i modelli si possono riscaricare. - Log:
journalctl -u ollama,docker logs open-webuie/var/log/nginx/per individuare tentativi di accesso ripetuti.
Domande frequenti
Serve una GPU per usare Ollama su un VPS?
No. Ollama funziona anche solo con la CPU. Le risposte sono più lente che con una scheda grafica, ma un modello da 3 a 8 miliardi di parametri è del tutto utilizzabile su un VPS con 8-12 GB di RAM.
Come uso l'API di Ollama da un'altra macchina senza esporla?
Con un tunnel SSH: ssh -L 11434:127.0.0.1:11434 utente@IP_DEL_VPS, poi interroghi http://localhost:11434 dal Suo computer. Per un'applicazione di terze parti, Open WebUI può anche fornire chiavi API per utente, dietro il Suo Nginx in HTTPS.
Open WebUI non mostra nessun modello: cosa fare?
Verifichi che ollama list restituisca dei modelli, che curl http://127.0.0.1:11434 risponda e che il container sia stato avviato con --network=host e OLLAMA_BASE_URL=http://127.0.0.1:11434. La connessione si controlla anche nelle impostazioni di amministrazione, nella sezione delle connessioni.
Quante persone possono usarlo contemporaneamente?
Senza GPU conti una generazione alla volta: le altre richieste aspettano il proprio turno. Per due o tre utenti occasionali basta un VPS 12G con un modello 4B o 8B; oltre, serve un server dedicato con più core e più RAM.