Keycloak, authentik hay Zitadel cho một VPS?
So sánh Keycloak, authentik và Zitadel trên một VPS: RAM tối thiểu thực tế, ứng dụng không có SSO, protocol hỗ trợ và điểm yếu từng lựa chọn.
SSO server nào phù hợp với một VPS
Keycloak, authentik và Zitadel là các SSO server tự host thường được nhắc đến khi cần dùng một tài khoản đăng nhập cho mọi ứng dụng trên server. Trên một VPS nhỏ, chúng không thể thay thế lẫn nhau. authentik là lựa chọn mặc định an toàn cho máy chủ chạy ba hoặc bốn ứng dụng tự host, vì đây là sản phẩm duy nhất trong ba sản phẩm có thể đặt màn hình đăng nhập trước một ứng dụng không có cơ chế đăng nhập riêng. Keycloak phù hợp khi mọi ứng dụng cần bảo vệ đều hỗ trợ một protocol tiêu chuẩn và bạn có đủ RAM cho một Java virtual machine (JVM). Zitadel được xây dựng cho developer phát hành sản phẩm thông qua API, và tôi không khuyến nghị triển khai nó với dưới 4 GB RAM.
Hãy chọn trước rồi mới cài đặt. Sau khi chọn xong, hướng dẫn cài đặt authentik thực tế trên VPS sẽ hướng dẫn từng bước thiết lập.
Mỗi hệ thống thực sự cần bao nhiêu RAM?
Hãy bắt đầu từ mức tài nguyên tối thiểu, vì yếu tố này quyết định danh sách lựa chọn trước khi xem xét bất kỳ tính năng nào. Các con số dưới đây là số liệu do chính từng dự án công bố, được kiểm tra vào tháng 8 năm 2026. Đây là khuyến nghị của nhà cung cấp, không phải kết quả kiểm thử tải.
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
}
]Trang cài đặt authentik bằng Docker Compose yêu cầu “một host có ít nhất 2 lõi CPU và 2 GB RAM”, tương đương 2048 MB. File compose được dự án công bố chạy 3 container: PostgreSQL, server và worker.
Keycloak công bố con số cụ thể nhất trong 3 dự án. Tài liệu sizing của dự án ghi rằng “mức sử dụng bộ nhớ cơ sở của một Pod, bao gồm cache dữ liệu Realm và 10.000 session được cache, là 1250 MB RAM”. 1250 MB này chỉ dành cho tiến trình Java, chưa bao gồm database. Trang đó cũng giải thích vì sao giới hạn bộ nhớ của container quan trọng: Keycloak dùng 70% giới hạn bộ nhớ làm heap và cần thêm khoảng 300 MB bộ nhớ non-heap. Nếu cấp cho container 1 GB, Keycloak tính heap khoảng 717 MB nhưng vẫn cần 300 MB bộ nhớ non-heap. Như vậy, giới hạn bộ nhớ đã gần như được dùng hết trước khi dữ liệu session được đưa vào cache.
Trang compose của Zitadel cũng yêu cầu 2 GB, cùng mức 2048 MB, nhưng con số này chỉ áp dụng cho lần chạy đầu tiên. Hãy đọc trang dành cho môi trường production. Bản thân tiến trình Zitadel cần “xấp xỉ 512MB RAM và có thể chạy với ít hơn một lõi CPU”. Database mới là phần tốn tài nguyên: “khoảng một lõi CPU cho mỗi 100 request mỗi giây (req/s) và 4GB RAM cho mỗi lõi”. Password hashing sau đó cần “4 lõi CPU khả dụng cho mục đích này”, vì một đợt login tăng đột biến sẽ tạo ra spike CPU. Compose v4 chính thức chạy 4 container trước khi bạn thêm thành phần khác: Traefik làm proxy, Zitadel API, một container Login UI riêng và PostgreSQL. Redis và OpenTelemetry collector nằm sau các compose profile tùy chọn.
Vì vậy, Keycloak và authentik có thể chạy trên VPS 4 GB, vẫn còn đủ tài nguyên cho các app mà bạn đang bảo vệ. Zitadel sẽ khởi động được trên 2 GB, nhưng sau đó sẽ tranh chấp bộ nhớ với PostgreSQL của chính nó trong mỗi lần login. Tôi không chạy Zitadel dưới 4 GB. Nếu máy còn host các app khác, tôi sẽ chọn 8 GB.
Thực tế mỗi thành phần chạy như thế nào trên máy chủ
authentik gồm PostgreSQL và 2 bản sao của cùng một image: một server và một worker. Server xử lý HTTP và chứa một outpost tích hợp sẵn. Worker chạy các tác vụ nền như đồng bộ directory và gửi email. Cấu hình cài đặt được phát hành khá ngắn gọn.
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 -dServer mở các cổng 9000 và 9443. Lần đầu truy cập cổng 9000 sẽ chạy quy trình thiết lập ban đầu, trong đó bạn đặt mật khẩu cho user akadmin mặc định. Hãy đặt một reverse proxy có certificate hợp lệ phía trước nó trước khi cổng đó có thể được truy cập từ Internet.
Keycloak gồm một process và một database do bạn cung cấp. Quickstart chỉ dùng một 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-devstart-dev dùng để xem thử. Nó chạy với database development cục bộ và không có TLS (bảo mật tầng truyền tải), nên container được khởi động theo cách này rồi bị xóa sẽ kéo theo cả realm của bạn. Môi trường production phải dùng start, kết nối đến PostgreSQL thực thông qua KC_DB và dùng hostname public thông qua KC_HOSTNAME. Tài liệu production của Keycloak cũng nêu rằng mọi kết nối đến và đi từ server đều phải dùng secure channel, nên HTTPS là bắt buộc.
Zitadel là stack gồm 4 container được mô tả ở trên.
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Đặt ZITADEL_MASTERKEY trong .env trước lần khởi động đầu tiên. Đây là key dài 32 ký tự mà Zitadel dùng để mã hóa secret trong database, nên nếu mất key này, bạn sẽ mất quyền truy cập vào các secret đó. Nếu bạn mới chạy các stack như vậy, phần hướng dẫn cơ bản về Docker Compose cho VPS giải thích các lựa chọn về volume và restart policy quyết định identity provider có tiếp tục hoạt động sau khi reboot hay không.
Mỗi sản phẩm hỗ trợ những giao thức nào?
Cả ba đều hỗ trợ OpenID Connect (OIDC), lớp đăng nhập xây dựng trên OAuth 2.0 mà các ứng dụng hiện đại sử dụng. Cả ba cũng hỗ trợ SAML 2.0 (security assertion markup language), tiêu chuẩn cũ hơn mà phần mềm doanh nghiệp vẫn phát hành. Điểm khác biệt thực sự là LDAP (lightweight directory access protocol), trong đó cùng một thuật ngữ chỉ hai chức năng đối lập.
Đọc từ LDAP nghĩa là SSO server kiểm tra mật khẩu với một directory mà bạn đã vận hành. Keycloak thực hiện việc này thông qua user federation. Zitadel cũng hỗ trợ: tài liệu của sản phẩm mô tả cách "kết nối một LDAP server làm identity provider trong ZITADEL".
Cung cấp LDAP nghĩa là một ứng dụng chỉ hỗ trợ LDAP vẫn có thể bind vào SSO server của bạn như thể đó là directory. Chỉ authentik hỗ trợ chức năng này. LDAP provider của sản phẩm cho phép "tìm kiếm tất cả user và group trong database của authentik thông qua LDAP directory" bằng một LDAP outpost riêng, với LDAPS khả dụng trên port 636. Chức năng này chỉ cho phép đọc, nên bind và search hoạt động nhưng write thì không. Bạn nối thêm one-time code vào cuối mật khẩu bằng dấu chấm phẩy, như trong password;123456, và SMS authenticator không được hỗ trợ khi bind.
Nếu một ứng dụng trong danh sách của bạn chỉ hỗ trợ LDAP, việc so sánh kết thúc ở đó. Keycloak và Zitadel không thể trả lời bind đó, nên bạn phải chạy thêm một directory bên cạnh chúng và đồng bộ hai danh sách user.
Còn những ứng dụng hoàn toàn không có chức năng đăng nhập thì sao?
Forward auth là cách giải quyết. Đây cũng là trường hợp mà một máy chủ self-hosted thường xuyên gặp phải. Reverse proxy hỏi SSO server xem request có được phép hay không trước khi chuyển tiếp lên upstream. Ứng dụng phía sau không biết gì về SSO. Nó nhận các request mà proxy đã kiểm tra, thường kèm username trong một header.
Proxy provider của authentik hỗ trợ việc này bằng 3 chế độ được tài liệu hóa. Chế độ "Proxy" để authentik outpost tự chuyển tiếp traffic đến ứng dụng upstream. Chế độ "Forward auth (single application)" giữ traffic tại reverse proxy hiện có và chỉ dùng authentik để kiểm tra xác thực. Chế độ "Forward auth (domain level)" bảo vệ mọi ứng dụng dưới cùng một parent domain bằng một provider duy nhất. Domain level là lựa chọn thuận tiện, nhưng có một giới hạn được nêu rõ trong tài liệu: chế độ này "không thể áp dụng các quy tắc phân quyền ở cấp ứng dụng khác nhau cho từng ứng dụng được bảo vệ", vì vậy mọi ứng dụng dưới domain đó dùng chung một bộ policy.
Keycloak không có tính năng tương đương. Proxy đi kèm của nó, Keycloak Gatekeeper, được đổi tên thành Louketo Proxy rồi bị lưu trữ trên GitHub; commit cuối cùng là vào tháng 8 năm 2023. Để bảo vệ một ứng dụng không hỗ trợ OIDC, bạn chạy một component riêng phía trước ứng dụng đó, thường là oauth2-proxy, trỏ đến một Keycloak client. Zitadel cũng không có chế độ forward auth riêng, nên cách xử lý tương tự là cài đặt, monitor và upgrade thêm một component.
Bước trung gian này khiến cấu hình reverse proxy không còn đơn giản, vì vậy hãy đọc cách Traefik đứng trước nhiều ứng dụng Docker Compose trước khi gắn auth middleware vào đó.
Đường nâng cấp phức tạp đến mức nào?
Tính đến tháng 8 năm 2026, các bản phát hành hiện tại là Keycloak 26.7.1, authentik 2026.5.6 và Zitadel v4.16.3. Cả ba đều chạy schema migration trên PostgreSQL. Điều đó có nghĩa là mọi lần nâng cấp đều thay đổi database. Luôn sao lưu database trước khi nâng cấp. Thói quen này có giá trị hơn bất kỳ tính năng nào trong phần so sánh này.
authentik có quy tắc nghiêm ngặt nhất và nêu rõ: "Upgrades must follow the sequence of major releases; do not skip directly from an older major version to the most recent version." Bạn phải nâng lên bản patch mới nhất trong từng version trước khi chuyển sang major version tiếp theo, và "authentik does not support downgrading". Nếu để một dự án dùng calendar version chậm một năm, một lần nâng cấp sẽ biến thành một chuỗi nâng cấp. Mỗi bước có database migration riêng.
Tài liệu nâng cấp của Keycloak đưa ra thứ tự cần thực hiện: xem lại các thay đổi migration từ version trước, nâng cấp server, rồi nâng cấp các adapter. Database migration chạy tự động. Bạn cũng có thể export migration rồi apply thủ công. Cách này hữu ích khi muốn đọc thay đổi trước khi áp dụng. Chi phí khi dùng Keycloak nằm ở việc đọc tài liệu. Release notes có các deprecation và thay đổi hành vi dễ bị bỏ qua nhưng khó xử lý nếu phát hiện quá muộn.
Zitadel tách các phase init và setup khỏi server đang chạy. Tài liệu production khuyến nghị giữ các phase này tách biệt để việc scale không lặp lại công đoạn setup. Trên một VPS đơn lẻ, điều đó chủ yếu có nghĩa là bước setup phải hoàn tất trước khi API báo healthy. Vì vậy compose file có health check và lệnh start sử dụng --wait.
Mỗi dự án phù hợp với ai và điểm yếu của từng dự án
Keycloak là identity server của Red Hat, được xây dựng cho các tổ chức có realm, group, ánh xạ role và corporate directory sẵn có. Đây là sản phẩm triển khai các chuẩn đầy đủ nhất trong ba lựa chọn. Nó không phù hợp với một VPS 2 GB chạy bốn ứng dụng self-hosted, trong đó một nửa không hỗ trợ OIDC. Bạn phải dành 1250 MB cho JVM, học một mô hình realm được thiết kế cho doanh nghiệp, rồi vẫn phải cài oauth2-proxy cho những ứng dụng bạn thực sự cần bảo vệ.
authentik được xây dựng cho nhóm người dùng self-hosting, và danh sách tính năng phản ánh rõ điều đó. Sản phẩm có forward auth và LDAP provider, đồng thời cho phép xây dựng login flow bằng trình chỉnh sửa trực quan. Nó không phù hợp khi bạn cần hợp đồng hỗ trợ từ vendor hoặc một release train không thay đổi vài tuần một lần. Việc versioning theo lịch mà không có đường lùi phiên bản và không cho phép bỏ qua phiên bản tạo ra nhiều công việc vận hành thực tế. Flow editor cũng là cả một mô hình cần học khi vấn đề thực tế của bạn chỉ là một OIDC client.
Zitadel được xây dựng cho các developer đưa authentication vào sản phẩm họ phát hành, với API mạnh và multi-tenancy là các tính năng cốt lõi. Nó không phù hợp chính xác với trường hợp này. Bốn container, không có forward auth và database được định cỡ ở mức 4 GB cho mỗi core là mô hình sai đối với một VPS chạy password manager và wiki phía sau nó.
Nên chạy gì trên một VPS và chạy như thế nào
Với một VPS có ba hoặc bốn app tự host, hãy chạy authentik. Cả ba đều cung cấp màn hình đăng nhập. Điểm quyết định là một số app của bạn sẽ không bao giờ hỗ trợ OIDC, còn authentik xử lý trường hợp này bằng forward auth tích hợp sẵn, thay vì cần thêm một component bên cạnh.
Nếu có thể, hãy cấp cho nó 4 GB RAM. Chỉ dùng 2 GB khi các app chạy cùng nó đều nhỏ. Không cho phép truy cập port 9000 từ Internet công cộng. Hãy terminate TLS tại reverse proxy ở phía trước. Tạo bản dump PostgreSQL mỗi đêm và lưu ở ngoài máy, vì một identity provider không có backup sẽ là single point of failure cho mọi app phía sau nó. Chạy stack bằng một account riêng không có đặc quyền thay vì root: thiết lập user theo nguyên tắc least privilege trên VPS trình bày cách tạo account và thiết lập quyền sở hữu file cần thiết.
Hãy chọn Keycloak khi mọi app bạn bảo vệ đã hỗ trợ OIDC hoặc SAML, hoặc khi bạn cần mô hình role chi tiết mà các realm của Keycloak cung cấp. Hãy chọn Zitadel khi bạn đang xây dựng một ứng dụng để người khác đăng ký tài khoản và cần API cùng tenant model của nó. Cả hai đều không phù hợp với trường hợp ba app trên một máy mà bài viết này đề cập.
Các lỗi thường gặp đầu tiên
Keycloak không còn dữ liệu sau khi restart. Bạn đã khởi động nó bằng start-dev, lệnh này sử dụng database cục bộ dành cho môi trường development. Trong container không có volume, xóa container sẽ xóa realm. Chuyển sang start và dùng KC_DB=postgres trỏ đến một database thực.
Container worker của authentik biến mất trên máy có cấu hình thấp. Worker và server sử dụng cùng một image, đồng thời cả hai đều chạy các tiến trình Python; PostgreSQL cũng cần phần tài nguyên của nó trên host 2 GB. Chạy docker compose ps để xác nhận service nào đã thoát, sau đó kiểm tra dmesg xem có bị kill do hết bộ nhớ hay không trước khi bắt đầu tìm lỗi trong app.
Console của Zitadel không hoạt động phía sau proxy. API của Zitadel sử dụng gRPC, nên kết nối đến upstream phải duy trì HTTP/2 trên toàn tuyến. Trang yêu cầu nêu rõ reverse proxy phải hỗ trợ kết nối HTTP/2 đến upstream, đồng thời liệt kê các phiên bản đã được kiểm thử của Traefik v3.x, NGINX v1.x, Caddy v2.x và Apache httpd 2.4.x. Proxy hạ kết nối đến upstream xuống HTTP/1.1 sẽ cho bạn một trang login tải được, nhưng Console sẽ không hoạt động.
Mọi app đều đưa bạn quay lại màn hình login. Public URL của SSO server và URL được cấu hình trong app phải khớp chính xác, bao gồm scheme và port. Keycloak gọi đây là hostname setting, còn Zitadel gọi là external domain. Khi hai giá trị không khớp, app redirect đến một trang login mà server không nhận là URL của chính nó, khiến trình duyệt chuyển qua lại giữa hai URL.
FAQ
Dịch vụ nào trong 3 lựa chọn phù hợp với VPS 2 GB?
authentik và Keycloak. Yêu cầu được authentik công bố là máy chủ có ít nhất 2 CPU core và 2 GB RAM, còn hướng dẫn sizing của Keycloak đặt mức bộ nhớ cơ bản cho server là 1250 MB, chưa tính database. Cả hai đều sẽ thiếu tài nguyên trên máy 2 GB khi bạn chạy thêm các app cần bảo vệ, nên hãy xem 4 GB là mức tối thiểu thoải mái. Zitadel công bố mức 2 GB cho lần chạy đầu tiên, nhưng hướng dẫn triển khai production yêu cầu 4 CPU core để hash password và 4 GB RAM cho mỗi database core, nên 2 GB không đủ cho một deployment thực tế.
Keycloak hoặc Zitadel có thể bảo vệ app không có chức năng đăng nhập riêng không?
Không thể tự làm việc đó. Cả hai đều không đi kèm component forward auth. Louketo Proxy, companion proxy cũ của Keycloak, đã được archive trên GitHub; commit cuối cùng là vào tháng 8 năm 2023, nên không nên dùng nó làm nền tảng. Bạn đặt oauth2-proxy hoặc một component tương tự giữa reverse proxy và app, rồi trỏ component đó đến một OIDC client trên SSO server. authentik hỗ trợ sẵn chức năng này bằng proxy provider ở chế độ "Forward auth (single application)" hoặc "Forward auth (domain level)".
Dịch vụ nào có thể đóng vai trò LDAP server cho app chỉ hỗ trợ LDAP?
authentik. LDAP provider của authentik chạy trên một outpost và cho phép tìm kiếm user, group trong authentik qua LDAP, với LDAPS khả dụng trên port 636. Provider này chỉ có quyền đọc, nên bind và search hoạt động, còn thao tác ghi thì không. Keycloak và Zitadel hoạt động theo hướng ngược lại: cả hai đều đọc từ một LDAP directory có sẵn làm user source, và không dịch vụ nào trả lời LDAP bind từ application.
Có thể bỏ qua phiên bản khi nâng cấp authentik không?
Không. Tài liệu nêu rõ quá trình nâng cấp phải đi theo thứ tự các major release và không được nâng cấp trực tiếp từ một major version cũ lên version mới nhất. Trước tiên, hãy chuyển lên patch release mới nhất trong từng version, sau đó nâng lần lượt từng version một. Hãy backup PostgreSQL trước mỗi bước, vì authentik không hỗ trợ downgrade và các migration chỉ chạy theo chiều tiến lên.