SSD Nodes Learn 🎉 VPS $5.50/월부터
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-08-09

Keycloak vs authentik vs Zitadel: VPS SSO 서버 비교

소규모 VPS 환경에서 Keycloak, authentik, Zitadel의 실제 RAM 요구량과 운영 적합성을 비교합니다. SSO를 지원하지 않는 앱 연동 방법과 각 솔루션의 메모리 하한선을 분석하여 서버 사양에 맞는 최적의 인증 서버를 선택하는 기준을 제시합니다.

단일 VPS에 적합한 SSO 서버 선택

Keycloak, authentik, Zitadel은 서버 내 모든 애플리케이션의 통합 로그인을 구현하려는 경우 가장 먼저 언급되는 자가 호스팅 SSO 서버입니다. 하지만 소규모 VPS 환경에서 이들은 서로 완벽하게 대체할 수 없습니다. authentik은 자체 로그인 기능이 없는 애플리케이션 앞단에 로그인 화면을 배치할 수 있는 유일한 솔루션이므로, 3~4개의 서비스를 운영하는 서버에 가장 적합한 기본 선택지입니다. Keycloak은 보호하려는 모든 애플리케이션이 이미 표준 프로토콜을 지원하고, Java 가상 머신(JVM)을 구동할 메모리 여유가 충분할 때 적합합니다. Zitadel은 API를 통해 제품을 배포하는 개발자를 위해 설계되었으며, 4 GB 미만의 메모리 환경에서는 권장하지 않습니다.

먼저 선택한 후 설치를 진행하십시오. 선택을 마쳤다면 VPS에서의 authentik 실습 설치 가이드에서 단계별 설정 방법을 확인할 수 있습니다.

각 서비스는 실제로 얼마만큼의 RAM이 필요한가?

기능을 고려하기 전에 리소스 하한선부터 확인해야 합니다. 하한선이 후보군을 결정하기 때문입니다. 아래 수치는 2026년 8월 기준으로 각 프로젝트가 공식 발표한 자료입니다. 이는 벤더의 권장 사양이며, 부하 테스트를 통해 얻은 결과는 아닙니다.

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
  }
]

authentik의 Docker Compose 설치 페이지는 "최소 2개의 CPU 코어와 2 GB의 RAM을 갖춘 호스트"를 요구합니다. 이는 2048 MB에 해당하며, 공식 compose 파일은 3 개의 컨테이너(PostgreSQL, 서버, 워커)를 실행합니다.

Keycloak은 3 에 대해 가장 구체적인 수치를 제시합니다. 사이징 가이드에 따르면 "Realm 데이터 캐시와 10,000개의 세션을 포함한 Pod의 기본 메모리 사용량은 1250 MB"입니다. 이 1250 MB는 데이터베이스를 제외한 Java 프로세스 자체의 요구량입니다. 동일한 페이지에서 컨테이너 제한이 중요한 이유를 설명합니다. Keycloak은 메모리 제한의 70%를 힙(heap)으로 할당하고, 그 외에 약 300 MB의 비힙(non-heap) 메모리를 추가로 사용합니다. 컨테이너에 1 GB를 할당하면 약 717 MB의 힙이 계산되지만, 여전히 300 MB의 비힙 메모리가 필요하므로 세션 데이터가 캐시에 저장되기도 전에 제한 용량을 모두 소진하게 됩니다.

Zitadel의 compose 페이지 역시 2 GB, 즉 동일한 2048 MB를 요구하지만, 이는 초기 실행 기준입니다. 실제로는 프로덕션 페이지를 확인해야 합니다. Zitadel 프로세스 자체는 "약 512 MB의 RAM이 필요하며 1개 미만의 CPU 코어로도 동작 가능"합니다. 데이터베이스가 리소스를 많이 차지하는 부분으로, "초당 100건의 요청(req/s)당 약 1개의 CPU 코어와 코어당 4 GB의 RAM"이 필요합니다. 비밀번호 해싱 작업은 로그인 급증 시 CPU 스파이크를 유발하므로 "이 목적을 위해 4개의 CPU 코어"를 확보할 것을 권장합니다. 공식 v4 compose는 추가 구성 없이 4 개의 컨테이너(프록시인 Traefik, Zitadel API, 별도의 로그인 UI 컨테이너, PostgreSQL)를 실행합니다. Redis와 OpenTelemetry 수집기는 선택적 compose 프로파일 뒤에 배치됩니다.

결론적으로 Keycloak과 authentik은 4 GB VPS에서 보호 대상 애플리케이션을 위한 여유 공간을 확보하며 운영할 수 있습니다. Zitadel은 2 GB에서도 시작은 가능하지만, 로그인 시마다 메모리를 두고 자체 PostgreSQL과 경쟁하게 됩니다. 4 GB 미만 환경에서 Zitadel을 운영하는 것은 권장하지 않으며, 다른 애플리케이션을 함께 호스팅하는 서버라면 8 GB를 권장합니다.

각 서비스가 서버에서 실제로 실행되는 방식

authentik은 PostgreSQL과 동일한 이미지의 복사본 두 개(서버와 워커)로 구성됩니다. 서버는 HTTP 요청을 처리하며 내장된 아웃포스트(outpost)를 포함합니다. 워커는 디렉터리 동기화나 이메일 발송 같은 백그라운드 작업을 수행합니다. 공개된 설치 방식은 간결합니다.

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

서버는 9000번과 9443번 포트를 사용합니다. 9000번 포트에 처음 접속하면 초기 설정 흐름이 시작되며, 여기서 기본 akadmin 사용자의 비밀번호를 지정합니다. 해당 포트를 인터넷에 공개하기 전에 반드시 유효한 인증서를 적용한 리버스 프록시를 앞단에 배치하십시오.

Keycloak은 하나의 프로세스와 사용자가 직접 제공하는 데이터베이스로 구성됩니다. 퀵스타트 방식은 단일 컨테이너를 사용합니다.

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는 환경을 둘러보는 용도입니다. 로컬 개발용 데이터베이스를 사용하며 TLS(전송 계층 보안)를 적용하지 않으므로, 이런 방식으로 컨테이너를 실행했다가 삭제하면 설정한 렐름(realm)도 함께 사라집니다. 운영 환경에서는 start를 사용해야 하며, KC_DB을 통해 실제 PostgreSQL을 연결하고 KC_HOSTNAME을 통해 공인 호스트 이름을 설정해야 합니다. Keycloak 운영 가이드에 따르면 서버와 주고받는 모든 통신은 보안 채널을 거쳐야 하므로 HTTPS는 선택 사항이 아닌 필수입니다.

Zitadel은 앞서 설명한 4개의 컨테이너로 구성된 스택입니다.

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

첫 실행 전에 .env 파일에서 ZITADEL_MASTERKEY를 설정하십시오. 이는 Zitadel이 데이터베이스 내의 비밀 정보를 암호화할 때 사용하는 32자 길이의 키이므로, 분실 시 해당 정보에 접근할 수 없게 됩니다. 이러한 스택 운영이 처음이라면, VPS를 위한 Docker Compose 기초에서 ID 공급자가 재부팅 후에도 유지되도록 하는 볼륨 및 재시작 정책 설정 방법을 확인하십시오.

각 제품은 어떤 프로토콜을 지원합니까?

세 제품 모두 현대적인 애플리케이션이 사용하는 OAuth 2.0 기반의 로그인 계층인 OpenID Connect (OIDC)를 지원하며, 엔터프라이즈 소프트웨어에서 여전히 제공하는 구형 표준인 SAML 2.0 (security assertion markup language)도 지원합니다. 실질적인 차이는 LDAP (lightweight directory access protocol)에서 발생하는데, 이 용어 하나가 서로 반대되는 두 가지 작업을 모두 의미하기 때문입니다.

LDAP 읽기(Reading from LDAP)란 SSO 서버가 이미 운영 중인 디렉터리를 참조하여 비밀번호를 확인하는 것을 의미합니다. Keycloak은 사용자 페더레이션(user federation)을 통해 이를 수행합니다. Zitadel 역시 동일하며, 문서에서 "ZITADEL에 LDAP 서버를 ID 공급자로 연결하는 방법"을 설명하고 있습니다.

LDAP 제공(Serving LDAP)이란 LDAP만 지원하는 애플리케이션이 SSO 서버를 마치 디렉터리인 것처럼 바인딩(bind)할 수 있게 하는 것을 의미합니다. 이 기능은 authentik만 제공합니다. authentik의 LDAP 공급자는 전용 LDAP 아웃포스트(outpost)를 통해 "authentik 데이터베이스의 모든 사용자와 그룹을 LDAP 디렉터리를 통해 검색 가능"하게 만들며, 포트 636에서 LDAPS를 사용할 수 있습니다. 이 기능은 읽기 전용이므로 바인딩과 검색은 가능하지만 쓰기는 불가능합니다. password;123456과 같이 비밀번호 뒤에 세미콜론으로 구분하여 일회용 코드를 추가해야 하며, 바인딩 과정에서 SMS 인증기는 지원되지 않습니다.

목록에 있는 애플리케이션 중 하나가 LDAP만 지원한다면 비교는 여기서 끝납니다. Keycloak과 Zitadel은 해당 바인딩 요청에 응답할 수 없으므로, 별도의 디렉터리를 추가로 운영하며 두 사용자 목록을 동기화해야 합니다.

로그인 기능이 없는 애플리케이션은 어떻게 처리합니까?

Forward auth가 그 해답이며, 이는 자가 호스팅 서버에서 끊임없이 마주하는 상황입니다. 리버스 프록시는 요청을 업스트림으로 전달하기 전에 SSO 서버에 해당 요청이 허용되는지 확인합니다. 그 뒤에 있는 애플리케이션은 SSO에 대해 전혀 알지 못합니다. 프록시가 이미 검증을 마친 요청을 받으며, 보통 헤더에 사용자 이름이 포함됩니다.

authentik의 프록시 프로바이더는 문서화된 세 가지 모드로 이를 지원합니다. "Proxy" 모드는 authentik 아웃포스트가 트래픽을 업스트림 애플리케이션으로 직접 전달합니다. "Forward auth (single application)" 모드는 트래픽을 기존 리버스 프록시에 그대로 두고, authentik은 인증 확인 용도로만 사용합니다. "Forward auth (domain level)" 모드는 하나의 상위 도메인 아래에 있는 모든 애플리케이션을 단일 프로바이더로 보호합니다. 도메인 레벨 방식은 편리하지만 문서에 명시된 제한 사항이 있습니다. "보호되는 각 애플리케이션에 대해 서로 다른 애플리케이션 수준의 권한 부여 규칙을 적용할 수 없으므로", 해당 도메인 아래의 모든 애플리케이션은 하나의 정책 세트를 공유합니다.

Keycloak은 이러한 기능을 제공하지 않습니다. Keycloak의 동반 프록시였던 Keycloak Gatekeeper는 Louketo Proxy로 이름이 변경된 후 GitHub에서 아카이브되었으며, 마지막 커밋은 2023년 8월입니다. OIDC를 지원하지 않는 애플리케이션을 보호하려면 그 앞에 별도의 구성 요소(보통 oauth2-proxy)를 실행하고 이를 Keycloak 클라이언트를 가리키도록 설정해야 합니다. Zitadel 역시 자체적인 Forward auth 모드가 없으므로, 동일하게 별도의 구성 요소를 설치, 모니터링 및 업그레이드해야 합니다.

이 추가적인 단계에서 리버스 프록시 설정이 복잡해지기 시작하므로, 인증 미들웨어를 연결하기 전에 Traefik으로 여러 Docker Compose 애플리케이션을 전면에 배치하는 방법을 먼저 읽어보시기 바랍니다.

업그레이드 경로는 얼마나 까다로운가?

2026년 8월 기준 현재 릴리스는 Keycloak 26.7.1, authentik 2026.5.6, Zitadel v4.16.3입니다. 세 제품 모두 PostgreSQL을 대상으로 스키마 마이그레이션을 수행하므로 모든 업그레이드는 데이터베이스 변경을 동반합니다. 매번 반드시 데이터베이스를 백업하십시오. 이 습관 하나가 본 비교에서 다루는 어떤 기능보다 가치가 큽니다.

authentik은 가장 엄격한 규칙을 가지고 있으며 이를 명확히 밝히고 있습니다: "업그레이드는 메이저 릴리스 순서를 따라야 하며, 이전 메이저 버전에서 최신 버전으로 직접 건너뛰지 마십시오." 각 버전 내에서 최신 패치로 이동한 뒤 다음 버전으로 넘어가야 하며, "authentik은 다운그레이드를 지원하지 않습니다." 캘린더 버전 방식을 사용하는 프로젝트에서 1년이 뒤처지면, 한 번의 업그레이드가 각각 데이터베이스 마이그레이션이 필요한 일련의 업그레이드 과정으로 변하게 됩니다.

Keycloak의 업그레이드 가이드는 따라야 할 순서를 제시합니다: 이전 버전의 마이그레이션 변경 사항을 검토하고, 서버를 업그레이드한 뒤, 어댑터를 업그레이드하십시오. 데이터베이스 마이그레이션은 자동으로 실행되거나, 직접 내보내어 수동으로 적용할 수도 있습니다. 이는 변경 사항이 적용되기 전에 내용을 확인하고 싶을 때 유용합니다. Keycloak의 비용은 바로 그 읽기 작업에 있습니다. 릴리스 노트에는 간과하기 쉽지만 놓치면 치명적인 지원 중단(deprecation) 및 동작 변경 사항이 포함되어 있습니다.

Zitadel은 초기화 및 설정 단계를 실행 중인 서버와 분리하며, 프로덕션 가이드에서는 확장을 수행할 때 설정 작업이 반복되지 않도록 이들을 분리된 상태로 유지할 것을 권장합니다. 단일 VPS 환경에서는 API가 정상 상태(healthy)를 보고하기 전에 설정 단계가 완료되어야 함을 의미하며, 이것이 compose 파일에 헬스 체크가 포함되어 있고 시작 명령에 --wait를 사용하는 이유입니다.

각 프로젝트의 대상 사용자와 단점

Keycloak은 Red Hat의 ID 서버로, 렐름(realm), 그룹, 역할 매핑 및 기존 기업용 디렉터리를 사용하는 조직을 위해 설계되었습니다. 이 세 가지 솔루션 중 표준을 가장 완벽하게 구현했습니다. 하지만 4개의 자체 호스팅 앱을 운영하는 2 GB VPS 환경에서는 비효율적입니다. 그중 절반이 OIDC를 지원하지 않는다면 더욱 그렇습니다. JVM을 위해 1250 MB의 메모리를 할당해야 하고, 기업용으로 설계된 렐름 모델을 학습해야 하며, 정작 필요한 앱을 위해 별도로 oauth2-proxy까지 설치해야 합니다.

authentik은 자체 호스팅 사용자를 위해 설계되었으며, 기능 목록에서 이를 확인할 수 있습니다. Forward auth와 LDAP 프로바이더를 기본 제공하며, 시각적 편집기를 통해 로그인 흐름을 구성할 수 있습니다. 하지만 벤더 기술 지원 계약이 필요하거나 몇 주마다 릴리스가 쏟아지는 환경이 부담스러운 경우에는 적합하지 않습니다. 다운그레이드 경로가 없고 버전 건너뛰기가 불가능한 캘린더 버전 관리 방식은 운영상 큰 부담이 되며, 단순히 OIDC 클라이언트 하나를 연동하려는 목적이라면 흐름 편집기라는 새로운 모델을 학습하는 것 자체가 과도한 작업이 될 수 있습니다.

Zitadel은 제품 내부에 인증 기능을 구현하려는 개발자를 위해 설계되었으며, 강력한 API와 멀티 테넌시를 핵심 기능으로 제공합니다. 하지만 바로 이러한 점 때문에 소규모 환경에서는 단점이 드러납니다. 4개의 컨테이너, Forward auth 부재, 코어당 4 GB의 데이터베이스 용량 요구 사항은 비밀번호 관리자와 위키 하나를 운영하는 VPS 환경에는 맞지 않는 구성입니다.

하나의 VPS에서 운영할 서비스와 그 방법

3~4개의 자체 호스팅 애플리케이션을 운영하는 하나의 VPS라면 authentik을 실행하십시오. 세 가지 선택지 모두 로그인 화면을 제공하지만, 결정적인 차이는 일부 애플리케이션이 OIDC를 지원하지 않을 때 나타납니다. authentik은 별도의 구성 요소를 추가하는 대신 내장된 forward auth 기능을 통해 이 문제를 해결합니다.

가능하다면 4 GB RAM을 할당하고, 함께 운영하는 애플리케이션이 가볍다면 최소 2 GB를 할당하십시오. 9000번 포트는 공용 인터넷에 노출하지 말고 앞단의 리버스 프록시에서 TLS를 종료하십시오. 매일 밤 PostgreSQL 덤프를 생성하여 서버 외부로 저장하십시오. 백업이 없는 ID 공급자는 그 뒤에 있는 모든 애플리케이션의 단일 장애 지점이 되기 때문입니다. 스택은 root 계정이 아닌 전용 비권한 계정으로 실행하십시오. VPS에서 최소 권한 사용자 설정하기 문서에서 이 작업에 필요한 계정 및 파일 소유권 설정을 다룹니다.

보호하려는 모든 애플리케이션이 이미 OIDC나 SAML을 지원하거나, Keycloak의 realm 기능이 제공하는 세밀한 역할 모델이 필요한 경우에는 Keycloak을 선택하십시오. 다른 사용자가 가입할 수 있는 애플리케이션을 구축 중이며 해당 API와 테넌트 모델이 필요한 경우에는 Zitadel을 선택하십시오. 이 두 가지는 본 글에서 다루는 '한 대의 서버에 세 개의 앱을 운영하는 경우'와는 거리가 있습니다.

가장 먼저 마주하게 될 실패 유형

재시작 후 Keycloak에 데이터가 없습니다. start-dev을 사용하여 시작했을 경우, 이는 로컬 개발용 데이터베이스를 사용합니다. 볼륨이 설정되지 않은 컨테이너 환경에서는 컨테이너를 삭제하면 realm 데이터도 함께 삭제됩니다. KC_DB=postgres를 실제 데이터베이스로 지정하여 start로 전환하십시오.

소규모 서버에서 authentik worker 컨테이너가 사라집니다. worker와 server는 동일한 이미지를 사용하며 둘 다 Python 프로세스를 실행합니다. 이때 PostgreSQL이 2 GB 호스트 메모리의 상당 부분을 점유할 수 있습니다. docker compose ps을 실행하여 어떤 서비스가 종료되었는지 확인하고, 애플리케이션 버그를 찾기 전에 dmesg에서 메모리 부족(OOM)으로 인한 강제 종료가 있었는지 확인하십시오.

프록시 뒤에서 Zitadel Console이 작동하지 않습니다. Zitadel API는 gRPC를 사용하며, 이는 업스트림까지 HTTP/2 연결이 유지되어야 합니다. 요구 사항 페이지에서는 HTTP/2 업스트림 연결을 지원하는 리버스 프록시를 권장하며, 테스트가 완료된 버전으로 Traefik v3.x, NGINX v1.x, Caddy v2.x, Apache httpd 2.4.x를 명시하고 있습니다. 업스트림 연결을 HTTP/1.1로 강제하는 프록시를 사용하면 로그인 페이지는 로드되지만 Console은 작동하지 않습니다.

모든 앱이 로그인 화면으로 되돌려 보냅니다. SSO 서버의 공개 URL과 앱에 설정된 URL은 스킴과 포트를 포함하여 정확히 일치해야 합니다. Keycloak에서는 이를 hostname 설정이라 부르고, Zitadel에서는 외부 도메인(external domain)이라고 부릅니다. 두 설정이 일치하지 않으면 앱은 서버가 자신의 것으로 인식하지 못하는 로그인 페이지로 리다이렉트하며, 브라우저는 두 지점 사이를 계속 튕기게 됩니다.

FAQ

2 GB VPS에는 어떤 것이 적합합니까?

authentik과 Keycloak입니다. authentik의 명시된 최소 요구 사양은 CPU 2코어와 RAM 2 GB이며, Keycloak의 사이징 가이드는 데이터베이스를 제외한 서버 기본 메모리로 1250 MB를 제시합니다. 두 제품 모두 보호하려는 애플리케이션을 추가하면 2 GB 환경에서는 매우 빠듯하므로, 4 GB를 안정적인 최소 사양으로 고려하십시오. Zitadel은 초기 실행 시 2 GB를 제시하지만, 프로덕션 가이드에서는 비밀번호 해싱을 위해 CPU 4코어와 데이터베이스 코어당 4 GB의 RAM을 요구하므로 2 GB는 실제 운영 환경으로 적합하지 않습니다.

자체 로그인 기능이 없는 애플리케이션을 Keycloak이나 Zitadel로 보호할 수 있습니까?

단독으로는 불가능합니다. 두 제품 모두 포워드 인증(forward auth) 구성 요소를 제공하지 않습니다. Keycloak의 이전 보조 프록시인 Louketo Proxy는 GitHub에서 아카이브되었으며 마지막 커밋이 2023년 8월이므로, 이를 기반으로 시스템을 구축해서는 안 됩니다. 리버스 프록시와 애플리케이션 사이에 oauth2-proxy와 같은 구성 요소를 배치하고, SSO 서버의 OIDC 클라이언트를 가리키도록 설정해야 합니다. authentik은 "Forward auth (single application)" 또는 "Forward auth (domain level)" 모드의 프록시 공급자를 통해 이를 기본적으로 지원합니다.

LDAP만 지원하는 애플리케이션을 위해 LDAP 서버 역할을 할 수 있는 것은 무엇입니까?

authentik입니다. authentik의 LDAP 공급자는 아웃포스트(outpost)에서 실행되며, authentik의 사용자와 그룹을 LDAP을 통해 검색할 수 있게 합니다. 이때 포트 636에서 LDAPS를 사용할 수 있습니다. 이 기능은 읽기 전용이므로 바인드와 검색은 가능하지만 쓰기는 지원하지 않습니다. Keycloak과 Zitadel은 반대 방향으로 작동합니다. 두 제품 모두 기존 LDAP 디렉터리를 사용자 소스로 읽어올 뿐, 애플리케이션으로부터의 LDAP 바인드 요청에는 응답하지 않습니다.

authentik 업그레이드 시 버전을 건너뛸 수 있습니까?

아니요. 문서에 따르면 업그레이드는 메이저 릴리스 순서를 따라야 하며, 이전 메이저 버전에서 최신 버전으로 바로 건너뛰어서는 안 됩니다. 먼저 각 버전 내의 최신 패치 릴리스로 이동한 다음, 한 번에 한 버전씩 단계적으로 업그레이드하십시오. authentik은 다운그레이드를 지원하지 않으며 마이그레이션은 항상 앞으로만 진행되므로, 각 단계를 수행하기 전에 반드시 PostgreSQL을 백업하십시오.

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