SSD Nodes Learn 🎉 VPS da $5.50/mese
Guide Matt ConnorDi Matt Connor · Aggiornato 2026-08-13

Keycloak, authentik o Zitadel su un solo VPS

Confronto tra tre server SSO self-hosted: RAM minima reale, supporto alle app senza SSO e limiti da considerare su un VPS di piccole dimensioni.

Quale server SSO scegliere per un VPS

Keycloak, authentik e Zitadel sono server self-hosted per il single sign-on (SSO). Vengono presi in considerazione quando si vuole usare un solo accesso per tutte le applicazioni del server. Su un VPS di piccole dimensioni non sono equivalenti. authentik è la scelta predefinita più sicura per un server che esegue tre o quattro applicazioni self-hosted, perché è l'unico dei tre che può visualizzare una schermata di accesso davanti a un'applicazione che non dispone di un proprio sistema di autenticazione. Keycloak è la scelta corretta quando tutte le applicazioni da proteggere supportano già un protocollo standard e si può destinare memoria sufficiente a una Java Virtual Machine (JVM). Zitadel è progettato per gli sviluppatori che distribuiscono un prodotto tramite un'API, ed è quello che non tenterei di eseguire con meno di 4 GB.

Scegli prima, quindi installa. Dopo la scelta, la guida pratica all'installazione di authentik su un VPS descrive la configurazione passo per passo.

Quanta RAM serve realmente a ciascuna soluzione?

Parti dal limite minimo di risorse, perché determina la rosa iniziale prima di qualsiasi funzionalità. I numeri riportati di seguito provengono dai valori pubblicati dai singoli progetti, consultati ad agosto 2026. Sono indicazioni dei vendor, non risultati di un test di carico.

ChartPublished minimum RAM and base container count, August 2026
The data behind this chart
[
  {
    "label": "authentik",
    "vendor_min_ram_mb": 2048,
    "base_containers": 3
  },
  {
    "label": "Keycloak",
    "vendor_min_ram_mb": 1250,
    "base_containers": 2
  },
  {
    "label": "Zitadel",
    "vendor_min_ram_mb": 2048,
    "base_containers": 4
  }
]

La pagina di installazione di authentik con Docker Compose richiede «un host con almeno 2 core CPU e 2 GB di RAM», cioè 2048 MB, e il file compose pubblicato avvia 3 container: PostgreSQL, il server e il worker.

Keycloak pubblica il dato più specifico dei 3. La guida al dimensionamento indica che «l'utilizzo di memoria di base per un Pod, inclusi le cache dei dati dei Realm e 10.000 sessioni memorizzate nella cache, è di 1250 MB di RAM». Questi 1250 MB coprono soltanto il processo Java, prima di considerare il database. La stessa pagina spiega perché il limite del container è così importante: Keycloak usa il 70% del limite di memoria come heap e richiede circa 300 MB di memoria non-heap aggiuntiva. Con un limite del container di 1 GB, calcola un heap di circa 717 MB e richiede comunque quei 300 MB di memoria non-heap. Il limite è quindi già esaurito prima che i dati delle sessioni vengano inseriti nella cache.

Anche la pagina compose di Zitadel richiede 2 GB, gli stessi 2048 MB, ma questo valore si riferisce alla prima esecuzione. Per la produzione bisogna consultare la pagina dedicata. Il processo Zitadel richiede «circa 512MB di RAM e può funzionare con meno di un core CPU». Il database è la componente più costosa: «circa un core CPU ogni 100 richieste al secondo (req/s) e 4GB di RAM per core». L'hashing delle password richiede inoltre «4 core CPU disponibili per questo scopo», perché un picco di accessi si traduce in un picco di utilizzo della CPU. Il compose ufficiale v4 avvia 4 container prima di aggiungere altri componenti: Traefik come proxy, l'API Zitadel, un container separato per la Login UI e PostgreSQL. Redis e un collector OpenTelemetry sono disponibili tramite profili compose opzionali.

Keycloak e authentik possono quindi funzionare su un VPS da 4 GB, lasciando memoria disponibile per le applicazioni protette. Zitadel si avvia con 2 GB, ma a ogni accesso deve competere con il proprio PostgreSQL per la memoria. Non eseguirei Zitadel con meno di 4 GB. Su un server che ospita anche le applicazioni, sceglierei 8 GB.

Cosa esegue realmente ciascuna soluzione sul server

authentik è composto da PostgreSQL e da due copie della stessa immagine: un server e un worker. Il server risponde alle richieste HTTP e include un outpost integrato. Il worker esegue attività in background, come la sincronizzazione delle directory e l'invio delle email. L'installazione pubblicata è breve.

wget https://docs.goauthentik.io/compose.yml
echo "PG_PASS=$(openssl rand -base64 36 | tr -d '\n')" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n')" >> .env
docker compose pull
docker compose up -d

Il server pubblica le porte 9000 e 9443. La prima visita alla porta 9000 avvia la procedura di configurazione iniziale, durante la quale si imposta la password per l'utente akadmin predefinito. Configura un reverse proxy con un certificato valido davanti al servizio prima che la porta sia raggiungibile da Internet.

Keycloak è costituito da un processo e da un database fornito dall'utente. La guida rapida usa un singolo container.

docker run -p 127.0.0.1:8080:8080 \
  -e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
  -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
  quay.io/keycloak/keycloak:26.7.1 start-dev

start-dev serve per esplorare il prodotto. Viene eseguito con un database locale di sviluppo e senza TLS (transport layer security); pertanto, se il container viene avviato in questo modo e poi rimosso, anche il realm viene eliminato. In produzione si usa invece start, con un PostgreSQL reale tramite KC_DB e un hostname pubblico tramite KC_HOSTNAME. La guida alla produzione di Keycloak specifica inoltre che tutte le comunicazioni da e verso il server richiedono un canale sicuro; HTTPS non è quindi opzionale.

Zitadel è lo stack composto dai quattro container descritti sopra.

mkdir zitadel-compose && cd zitadel-compose
curl -fsSLO https://raw.githubusercontent.com/zitadel/zitadel/main/deploy/compose/docker-compose.yml
curl -fsSLO https://raw.githubusercontent.com/zitadel/zitadel/main/deploy/compose/.env.example
cp .env.example .env
docker compose up -d --wait

Imposta ZITADEL_MASTERKEY in .env prima del primo avvio. È la chiave di 32 caratteri che Zitadel usa per cifrare i secret nel database; perderla significa perdere l'accesso a tali secret. Se non hai mai gestito stack di questo tipo, la guida di base a Docker Compose per un VPS illustra le scelte relative ai volumi e alle restart policy che determinano se l'identity provider sopravvive a un riavvio.

Quali protocolli supporta ciascuno?

Tutti e tre supportano OpenID Connect (OIDC), il livello di autenticazione basato su OAuth 2.0 usato dalle applicazioni moderne. Tutti e tre supportano anche SAML 2.0 (security assertion markup language), lo standard precedente ancora distribuito con molti software aziendali. La differenza principale riguarda LDAP (lightweight directory access protocol), che comprende due funzioni opposte.

La lettura da LDAP significa che il server SSO verifica le password in una directory già in uso. Keycloak lo gestisce tramite la federazione degli utenti. Anche Zitadel supporta questa funzione: la documentazione descrive come "collegare un server LDAP come identity provider in ZITADEL".

L'esposizione di LDAP significa che un'applicazione che supporta soltanto LDAP può eseguire il bind sul server SSO come se fosse una directory. Solo authentik supporta questa funzione. Il relativo provider LDAP rende "ricercabili tramite la directory LDAP tutti gli utenti e i gruppi presenti nel database di authentik" attraverso un LDAP outpost dedicato, con LDAPS disponibile sulla porta 636. Il servizio è in sola lettura: bind e ricerca funzionano, mentre le scritture no. Un codice monouso viene aggiunto alla password, separato da un punto e virgola, come in password;123456. Durante il bind, gli autenticatori SMS non sono supportati.

Se una delle applicazioni nell'elenco supporta soltanto LDAP, il confronto termina qui. Keycloak e Zitadel non possono rispondere a quel bind. Dovresti quindi eseguire una seconda directory accanto a uno dei due prodotti e mantenere sincronizzati due elenchi di utenti.

E le applicazioni che non prevedono alcun login?

La forward auth è la soluzione. È uno scenario molto comune sui server self-hosted. Prima di inoltrare la richiesta al servizio upstream, il reverse proxy chiede al server SSO se la richiesta è autorizzata. L'applicazione protetta non deve conoscere i dettagli dell'SSO. Riceve richieste che il proxy ha già verificato, di solito con il nome utente in un header.

Il proxy provider di authentik supporta questa configurazione in tre modalità documentate. Con "Proxy", l'outpost di authentik inoltra direttamente il traffico all'applicazione upstream. "Forward auth (single application)" lascia il traffico nel reverse proxy esistente e usa authentik soltanto per il controllo dell'autenticazione. "Forward auth (domain level)" protegge tutte le applicazioni appartenenti allo stesso dominio principale con un unico provider. La modalità a livello di dominio è quella più comoda, ma ha un limite documentato: "cannot enforce different application-level authorization rules for each protected application", quindi tutte le applicazioni sotto quel dominio condividono lo stesso insieme di policy.

Keycloak non offre nulla di equivalente. Il proxy associato, Keycloak Gatekeeper, è stato rinominato Louketo Proxy e poi archiviato su GitHub; l'ultimo commit risale ad agosto 2023. Per proteggere un'applicazione che non supporta OIDC, devi eseguire un componente separato davanti all'applicazione, in genere oauth2-proxy, configurato con un client Keycloak. Anche Zitadel non dispone di una propria modalità forward auth. Anche in questo caso devi installare, monitorare e aggiornare un componente aggiuntivo.

È proprio questo passaggio aggiuntivo che rende meno semplice la configurazione del reverse proxy. Prima di collegare un middleware di autenticazione, leggi come Traefik espone più applicazioni Docker Compose.

Quanto è complesso il percorso di aggiornamento?

Ad agosto 2026 le versioni attuali sono Keycloak 26.7.1, authentik 2026.5.6 e Zitadel v4.16.3. Tutti e tre eseguono migrazioni dello schema su PostgreSQL, quindi ogni aggiornamento modifica il database. Eseguire prima il backup del database, ogni volta. Questa abitudine vale più di qualsiasi funzionalità descritta in questo confronto.

authentik applica la regola più rigida e la dichiara esplicitamente: "Gli aggiornamenti devono seguire la sequenza delle versioni principali; non passare direttamente da una versione principale precedente alla versione più recente." Prima di passare alla versione principale successiva, occorre installare l'ultima patch disponibile all'interno della versione corrente; inoltre, "authentik non supporta il downgrade". In un progetto con versioni basate sull'anno, accumulare un anno di ritardo trasforma un aggiornamento in una catena di aggiornamenti, ognuno con la propria migrazione del database.

La guida agli aggiornamenti di Keycloak indica un ordine preciso: esaminare le modifiche alla migrazione dalla versione precedente, aggiornare il server e quindi aggiornare gli adapter. La migrazione del database viene eseguita automaticamente. In alternativa, è possibile esportarla e applicarla manualmente, utile quando si vuole esaminare la modifica prima che venga applicata. Con Keycloak, il costo principale è il tempo necessario per leggere. Le note di rilascio includono deprecazioni e modifiche al comportamento che è facile saltare e costoso non considerare.

Zitadel separa le fasi di init e setup dal server in esecuzione. La documentazione per gli ambienti di produzione raccomanda di mantenerle separate, in modo che lo scaling non ripeta le operazioni di setup. Su un singolo VPS questo significa soprattutto che il passaggio di setup deve terminare prima che l'API risulti in stato healthy. Per questo il file compose include health check e il comando di avvio usa --wait.

Per chi è pensato ogni progetto e dove mostra i suoi limiti

Keycloak è il server per la gestione delle identità di Red Hat, pensato per organizzazioni con realm, gruppi, mapping dei ruoli e una directory aziendale esistente. È l'implementazione degli standard più completa tra le tre. Mostra i suoi limiti su un VPS da 2 GB che esegue quattro applicazioni self-hosted, quando metà di queste non supporta OIDC. Si riservano 1250 MB per la JVM, si deve imparare un modello di realm progettato per un'azienda e si finisce comunque per installare oauth2-proxy per le applicazioni che interessavano davvero.

authentik è pensato per chi gestisce servizi self-hosted, come mostra l'elenco delle funzionalità. Include forward auth e un provider LDAP e consente di creare i flussi di accesso in un editor visuale. Mostra i suoi limiti quando servono un contratto di supporto del fornitore o un ciclo di rilascio che non cambi ogni poche settimane. Il versionamento basato sul calendario, senza un percorso di downgrade e senza la possibilità di saltare versioni, richiede un'attività operativa concreta. Inoltre, l'editor dei flussi introduce un intero modello da imparare quando il problema effettivo è un solo client OIDC.

Zitadel è pensato per gli sviluppatori che integrano l'autenticazione in un prodotto che distribuiscono, con un'API solida e il multi-tenancy come funzionalità di base. Mostra i suoi limiti proprio in questo scenario. Quattro container, l'assenza di forward auth e un database dimensionato a 4 GB per core non sono adatti a un singolo VPS che ospita un password manager e una wiki.

Cosa eseguire su un VPS e come farlo

Su un VPS con tre o quattro applicazioni self-hosted, esegui authentik. Tutte e tre le soluzioni mostrano una schermata di accesso. Il fattore decisivo è che alcune applicazioni non supporteranno mai OIDC: authentik gestisce questo caso con il forward auth integrato, senza richiedere un altro componente aggiuntivo.

Assegna 4 GB, se possibile, e usa 2 GB soltanto se le applicazioni che eseguono sul VPS hanno dimensioni ridotte. Mantieni la porta 9000 non esposta a Internet e termina TLS su un reverse proxy configurato davanti ad authentik. Esegui ogni notte il dump di PostgreSQL e salvalo fuori dal server, perché un identity provider senza backup rappresenta un single point of failure per tutte le applicazioni che dipendono da esso. Esegui lo stack con un account dedicato senza privilegi, non con root: configurare utenti con privilegi minimi su un VPS descrive la configurazione dell'account e della proprietà dei file necessaria in questo caso.

Scegli Keycloak se tutte le applicazioni che vuoi proteggere supportano già OIDC o SAML oppure se ti serve il modello granulare dei ruoli fornito dai realm di Keycloak. Scegli Zitadel se stai sviluppando un'applicazione alla quale altre persone devono potersi registrare e ti servono la relativa API e il relativo modello multi-tenant. Nessuna delle due soluzioni è adatta allo scenario con tre applicazioni su un unico server descritto in questo articolo.

I primi problemi che incontrerai

Keycloak non contiene dati dopo un riavvio. Lo hai avviato con start-dev, che usa un database locale per lo sviluppo. In un container senza un volume, la rimozione del container elimina il realm. Passa a start usando KC_DB=postgres configurato per puntare a un database reale.

Il container worker di authentik scompare su un host di dimensioni ridotte. Il worker e il server usano la stessa immagine ed eseguono entrambi processi Python. Inoltre, PostgreSQL richiede la propria quota dei 2 GB disponibili sull'host. Esegui docker compose ps per verificare quale servizio è terminato, quindi controlla dmesg per individuare un'eventuale terminazione dovuta a esaurimento della memoria, prima di cercare un problema nell'applicazione.

La Console di Zitadel non funziona dietro il proxy. L'API di Zitadel usa gRPC, che richiede HTTP/2 per l'intero percorso fino all'upstream. La pagina dei requisiti richiede un reverse proxy che supporti le connessioni HTTP/2 verso l'upstream e indica versioni testate di Traefik v3.x, NGINX v1.x, Caddy v2.x e Apache httpd 2.4.x. Un proxy che riduce la connessione verso l'upstream a HTTP/1.1 produce una pagina di login che viene caricata, ma una Console che non funziona.

Ogni applicazione ti riporta alla schermata di login. L'URL pubblico del server SSO e l'URL configurato nell'applicazione devono corrispondere esattamente, incluso lo schema e la porta. Keycloak chiama questa impostazione hostname; Zitadel la chiama external domain. Quando non corrispondono, l'applicazione reindirizza a un login che il server non riconosce come proprio e il browser passa continuamente dall'uno all'altro.

FAQ

Quale dei tre è adatto a un VPS da 2 GB?

authentik e Keycloak. authentik richiede almeno 2 core CPU e 2 GB di RAM per l'host, mentre la guida al dimensionamento di Keycloak indica 1250 MB di memoria di base per il server, escluso il database. Su un VPS da 2 GB lo spazio è limitato non appena si aggiungono le applicazioni da proteggere, quindi 4 GB sono il minimo consigliato per lavorare senza vincoli. Zitadel indica 2 GB per una prima esecuzione, ma per la produzione raccomanda 4 core CPU per l'hashing delle password e 4 GB di RAM per core del database. Per questo, 2 GB non sono sufficienti per una distribuzione reale.

Keycloak o Zitadel possono proteggere un'applicazione che non dispone di un proprio login?

Non autonomamente. Nessuno dei due include un componente di forward auth. Il vecchio proxy complementare di Keycloak, Louketo Proxy, è archiviato su GitHub e l'ultimo commit risale ad agosto 2023. Non è quindi una base adatta per una nuova implementazione. Inserisci oauth2-proxy o un componente simile tra il reverse proxy e l'applicazione, quindi configuralo usando un client OIDC sul server SSO. authentik gestisce questo scenario nativamente con il proxy provider, in modalità "Forward auth (single application)" o "Forward auth (domain level)".

Quale dei tre può funzionare come server LDAP per un'applicazione che supporta soltanto LDAP?

authentik. Il suo LDAP provider viene eseguito su un outpost e rende ricercabili tramite LDAP gli utenti e i gruppi presenti in authentik. LDAPS è disponibile sulla porta 636. Il provider è di sola lettura: bind e ricerche funzionano, mentre le operazioni di scrittura no. Keycloak e Zitadel funzionano nella direzione opposta: entrambi leggono i dati da una directory LDAP esistente usata come origine degli utenti, ma nessuno dei due risponde a una richiesta LDAP bind proveniente da un'applicazione.

Posso saltare versioni durante l'aggiornamento di authentik?

No. La documentazione specifica che gli aggiornamenti devono seguire la sequenza delle release principali e che non bisogna passare direttamente da una versione principale obsoleta a quella più recente. Prima aggiorna alla patch release più recente all'interno della versione corrente, quindi passa alla versione successiva, una alla volta. Esegui il backup di PostgreSQL prima di ogni passaggio, perché authentik non supporta il downgrade e le migrazioni vengono eseguite soltanto in avanti.

#sso#authentik#keycloak#zitadel#self-hosted#identity