Guía de despliegue

Desplegar Keycloak para el SSO en su VPS

Desplegar en un VPS Cloud →

Tutorial

Desplegar Keycloak para el SSO en su VPS

Seguridad y monitorización10 min de lectura15 pasos

Keycloak es la referencia open source del SSO empresarial, respaldada por Red Hat y utilizada incluso en contextos altamente regulados. Con sus realms, su federación LDAP y su soporte completo de OIDC y SAML, cubre necesidades que pocos IdP alcanzan. Autoalojado en un VPS, le ofrece ese nivel de industrialización sin licencia ni dependencia de la nube.

Contenido· Por qué desplegar Keycloak en su VPS1/13
  1. 01Por qué desplegar Keycloak en su VPS
  2. 02Las ventajas de un Keycloak autoalojado
  3. 03Requisitos previos para este despliegue
  4. 04Desplegar Keycloak con PostgreSQL
  5. 05Imagen preoptimizada: separar el build del arranque
  6. 06Construir y ejecutar una imagen preoptimizada
  7. 07Keycloak o Authentik: ¿cuál elegir?
  8. 08Copias de seguridad y migración sin perder un realm
  9. 09Lista de comprobación de operación
  10. 10Solución de problemas: el arranque falla con un sistema de archivos de solo lectura
  11. 11Mensajes de error que conviene reconocer
  12. 12Solución notificada en Docker Compose
  13. 13Solo lectura: un endurecimiento que el fabricante no documenta

Por qué desplegar Keycloak en su VPS

Donde algunos IdP buscan la simplicidad, Keycloak busca la exhaustividad: aislamiento multi-tenant mediante los realms, federación de directorios LDAP/Active Directory, brokering hacia proveedores externos (Google, GitHub, otro OIDC), theming completo de las páginas de login y fine-grained authorization. Para una agencia que gestiona varios clientes o para un sistema de información con exigencias de conformidad, ese nivel de control es decisivo. El autoalojamiento en VPS le evita los costos por usuario de las ofertas IdP gestionadas y mantiene la totalidad de la base de identidades bajo su jurisdicción, un punto crítico para datos sensibles que no desea confiar a un tercero.

Las ventajas de un Keycloak autoalojado

  • Múltiples realms para aislar por completo varios clientes o entornos en una misma instancia.
  • Soporte nativo y completo de OpenID Connect, OAuth2 y SAML 2.0.
  • Federación LDAP / Active Directory para reutilizar un directorio existente sin migración.
  • Identity brokering: conexión mediante Google, GitHub o cualquier IdP externo en unos clics.
  • Páginas de login totalmente personalizables (temas, idiomas, branding por realm).
  • Políticas de autenticación detalladas: MFA condicional, duración de sesión, restricciones por rol.

Requisitos previos para este despliegue

Keycloak se ejecuta sobre la JVM (Quarkus desde la v17+) y sigue siendo más exigente que un IdP ligero. Prevea un VPS con 2 vCPU y 4 GB de RAM como mínimo, idealmente 6 GB si espera carga o varios realms activos. Una base PostgreSQL externa es muy recomendable en producción (no use nunca la base H2 integrada más allá de las pruebas). Docker y Docker Compose, un dominio dedicado (sso.midominio.com) y un reverse proxy que gestione el SSL completan los requisitos, ya que Keycloak necesita saber que se sirve detrás de un proxy HTTPS.

Desplegar Keycloak con PostgreSQL

  1. Definir Keycloak y PostgreSQL en Compose

    En su docker-compose.yml, declare el servicio postgres (imagen postgres:16) y el servicio keycloak (imagen quay.io/keycloak/keycloak). Conecte Keycloak a la base mediante KC_DB=postgres, KC_DB_URL, KC_DB_USERNAME y KC_DB_PASSWORD.

  2. Configurar el modo producción y el proxy

    Arranque con el comando start (y no start-dev). Indique KC_HOSTNAME=sso.midominio.com y KC_PROXY_HEADERS=xforwarded para que Keycloak genere URL correctas detrás del reverse proxy. Defina el administrador inicial mediante KC_BOOTSTRAP_ADMIN_USERNAME / KC_BOOTSTRAP_ADMIN_PASSWORD.

  3. Arrancar y finalizar el build

    Ejecute docker compose up -d. En el primer arranque, Keycloak realiza un build Quarkus optimizado y luego migra el esquema PostgreSQL. Siga docker compose logs -f keycloak hasta el mensaje que indica que el servidor está escuchando.

  4. Poner en marcha el reverse proxy SSL

    Enrute sso.midominio.com hacia el puerto 8080 del contenedor Keycloak mediante Caddy, Traefik o Nginx, con un certificado Let's Encrypt. Asegúrese de transmitir las cabeceras X-Forwarded-*, ya que de lo contrario las redirecciones de login se romperán.

  5. Crear un realm y un cliente

    Conéctese a la consola de administración, cree un realm dedicado (nunca el realm master para sus aplicaciones) y luego un cliente OIDC. Ajuste el Valid redirect URIs de su aplicación y recupere el Client ID y el secreto en la pestaña Credentials.

  6. Conectar una aplicación y probar el flujo

    Configure su aplicación con la URL de descubrimiento https://sso.midominio.com/realms/mi-realm/.well-known/openid-configuration. Cree un usuario de prueba en el realm, inicie un login y compruebe la emisión del token en las Sessions de la consola.

Imagen preoptimizada: separar el build del arranque

Por defecto, el comando start comprueba al arrancar si hace falta una fase de build de Quarkus y la ejecuta si es necesario: eso alarga el primer arranque y es lo que escribe en el árbol de la instalación. La documentación del fabricante recomienda lo contrario para un contenedor: ejecutar kc.sh build durante la construcción de la imagen y arrancar después con start --optimized. El parámetro --optimized indica a Keycloak que se ejecuta en una imagen ya optimizada y que puede omitir esa comprobación. Las opciones de build, como el tipo de base de datos (db) o la activación de las sondas (health-enabled), quedan fijadas en la imagen: si se repiten al arrancar con el mismo valor, se ignoran; con un valor distinto, provocan un error y exigen un nuevo build. Los secretos, contraseña de la base incluida, pertenecen a las opciones de configuración y se siguen suministrando en tiempo de ejecución.

Construir y ejecutar una imagen preoptimizada

  1. Escribir un Dockerfile en dos etapas

    La primera etapa parte de quay.io/keycloak/keycloak con el nombre builder, define ENV KC_DB=postgres y ENV KC_HEALTH_ENABLED=true y ejecuta RUN /opt/keycloak/bin/kc.sh build. Fije un número de versión concreto en lugar de latest, para que cada reconstrucción sea reproducible.

  2. Copiar el resultado a la imagen final

    La segunda etapa parte de la misma imagen y ejecuta COPY --from=builder /opt/keycloak/ /opt/keycloak/. Coloque sus temas y proveedores personalizados antes del build: así los tiene en cuenta la optimización. Si añade archivos con COPY, añada --chown=keycloak:keycloak para que Keycloak pueda escribir en las carpetas afectadas.

  3. Arrancar con la opción optimizada

    En Compose, sustituya el comando por start --optimized. Detrás de un reverse proxy que termina el TLS, añada KC_HTTP_ENABLED=true. Las variables KC_HOSTNAME y KC_PROXY_HEADERS y los accesos a la base siguen siendo configuración de ejecución.

  4. Conectar las sondas de salud

    Con KC_HEALTH_ENABLED=true definido en el build, los puntos /health/started, /health/live y /health/ready se sirven en el puerto de gestión 9000, distinto del 8080 de la aplicación. No publique este puerto en Internet: úselo solo para el healthcheck de Compose o su monitorización.

Keycloak o Authentik: ¿cuál elegir?

Desplace la tabla

CriterioKeycloakAuthentik
Caso de uso objetivoSSO empresarial, multi-tenant, conformidadSelf-hosting, homelab, agencias
ProtocolosOIDC, OAuth2, SAML, LDAPOIDC, OAuth2, SAML, LDAP, forward auth
Forward auth (proxy)No nativo (mediante extensiones)Nativo y central en la herramienta
Huella de recursosElevada (JVM, 4 GB+ de RAM)Moderada (2-4 GB de RAM)
Multi-realm / tenantsExcelente (realms aislados)Tenants soportados, menos avanzados
Personalización de los flujosTemas y SPI JavaFlujos visuales por etapas
Curva de aprendizajePronunciada, muy completaMás accesible
Federación de directoriosMadura (LDAP/AD)Buena (LDAP)

Copias de seguridad y migración sin perder un realm

El estado de Keycloak reside en dos sitios: la base PostgreSQL y sus archivos de configuración (temas, proveedores, archivos de importación). La copia de referencia es un pg_dump programado, copiado fuera del VPS; pruebe la restauración en una instancia desechable, porque una copia que nunca se ha restaurado sigue siendo una hipótesis. La exportación de realms completa este dispositivo sin sustituirlo: kc.sh export --dir <carpeta>, o --realm mi-realm para un solo realm, con la opción --users para elegir la estrategia de exportación de usuarios. La documentación precisa que el servidor no debe estar arrancado durante la exportación, que la coherencia solo está garantizada con todos los nodos detenidos y que los eventos, las sesiones persistentes y los tokens revocados no se exportan. A partir de 50 000 usuarios, exporte a un directorio y no a un único archivo. En la importación, start --import-realm lee los archivos .json de la carpeta /opt/keycloak/data/import e ignora un realm que ya existe.

Lista de comprobación de operación

  • Versión fijada — fije el número de versión de la imagen, lea las notas de versión antes de cambiar de rama mayor y reconstruya la imagen optimizada en cada actualización.
  • Base con copia — pg_dump programado, copia fuera del VPS, restauración probada en una instancia desechable.
  • Memoria acotada — fije siempre un límite de memoria al contenedor: la JVM calcula su heap a partir de él, con un 70 % como máximo y un 50 % inicial por defecto.
  • Sondas vigiladas — siga /health/ready en el puerto 9000, no publicado, desde su monitorización.
  • Cabeceras del proxy controladas — el reverse proxy debe sobrescribir las cabeceras X-Forwarded-* recibidas del cliente, no añadirse a ellas, y no debe eludirse nunca.
  • Eventos activados — registre los inicios de sesión y las acciones de administración en cada realm, para saber quién se conectó y quién modificó qué.

Solución de problemas: el arranque falla con un sistema de archivos de solo lectura

Endurecer un contenedor suele implicar read_only: true en Compose o readOnlyRootFilesystem: true en Kubernetes. Con Keycloak, el tema está abierto desde abril de 2022 en la issue keycloak/keycloak n.º 11286 ("Keycloak does not work with Docker read_only: true") y seguía activa a finales de octubre de 2026. Lo que está establecido por parte del proyecto: un colaborador de Keycloak reprodujo el fallo en la versión 19.0.2 en septiembre de 2022, la issue está clasificada como mejora con la etiqueta "help wanted" y se añadió a un tablero de proyecto del repositorio en septiembre de 2026. Lo que no: la documentación oficial no describe a día de hoy ningún modo de solo lectura (la página dedicada a los contenedores no lo menciona) y ningún mantenedor ha validado una solución alternativa. Las soluciones siguientes proceden de participantes en la discusión; les funcionaron a ellos, en sus versiones, sin garantía tras una actualización. El 26 de octubre de 2026, un colaborador se ofreció a escribir la documentación que falta tras verificar él mismo estas soluciones.

Mensajes de error que conviene reconocer

  • sed: couldn't open temporary file /opt/jboss/keycloak/bin/seduHoQM0: Read-only file system — mensaje del informe inicial, sobre la antigua imagen WildFly (versión 16.1.1 en la issue): un sed -i del script de arranque no puede crear su archivo temporal. En la distribución Quarkus los síntomas son distintos, véanse las líneas siguientes.
  • KC-SERVICES0075: Failed to get theme request: java.lang.RuntimeException: Temporary directory /opt/keycloak/bin/../data/tmp does not exist and it was not possible to create it. — notificado al actualizar a la 20.0.1: el servidor arranca y luego falla en la primera página que sirve un tema. Un participante indicó que un volumen escribible montado en /opt/keycloak/data/tmp resuelve este caso.
  • Arranque lento o fallo de escritura en /opt/keycloak/lib/quarkus — un participante comparó el contenedor antes y después del arranque con docker diff: cambian tres carpetas, /tmp, /opt/keycloak/data y /opt/keycloak/lib/quarkus. La última contiene el resultado del build, que start regenera salvo que la imagen esté preoptimizada.
  • Carpeta data de solo lectura tras un COPY — un participante señala que olvidar --chown=keycloak:keycloak al copiar un archivo de realm deja /opt/keycloak/data en manos de root y, por tanto, sin escritura para Keycloak.
  • Copia de /opt/keycloak a un volumen al arrancar — solución con contenedor de inicialización, notificada en Kubernetes: funciona, pero varios participantes temen tener que volver a probarla en cada actualización.

Solución notificada en Docker Compose

  1. Partir de la imagen preoptimizada

    Reutilice la imagen construida más arriba. kc.sh build se ejecuta durante la construcción: /opt/keycloak/lib/quarkus ya no se reescribe al arrancar, que se hace con start --optimized.

  2. Declarar el sistema de archivos de solo lectura

    Añada read_only: true al servicio keycloak del archivo Compose. Sin ningún otro cambio, el contenedor falla: es el comportamiento que describe la issue.

  3. Suministrar los directorios escribibles

    Monte un tmpfs en /tmp y un volumen temporal en /opt/keycloak/data. En el informe que se apoya en una imagen preoptimizada, esos dos directorios bastaron; con una imagen no optimizada, otros participantes añadieron /opt/keycloak/lib/quarkus.

  4. Reponer lo que había en data

    Un volumen temporal arranca vacío: lo que la imagen colocaba en esa carpeta, incluido data/import, deja de verse allí. Si importa realms con --import-realm, monte su carpeta por separado, en solo lectura.

  5. Comprobar abriendo una página de login

    Ejecute docker compose up -d y luego docker compose logs -f keycloak, y abra después la página de inicio de sesión: la primera petición de tema es la que hizo fallar algunos montajes. Termine con docker diff para listar lo que el contenedor ha escrito realmente.

Solo lectura: un endurecimiento que el fabricante no documenta

Reserve este modo para los entornos donde una política lo exige, como una auditoría de seguridad o una regla del clúster, y acepte el coste: una configuración no documentada, que hay que volver a probar en cada actualización, algo que temen varios participantes de la issue. En un VPS único, otras medidas dan una ganancia más clara con menos mantenimiento: capacidades de Linux retiradas (cap_drop: [ALL]), opción no-new-privileges, puertos de gestión sin publicar y base PostgreSQL en una red Docker interna.

En producción, no sirva nunca Keycloak con la base H2 integrada ni exponga el realm master al público: cree un realm dedicado por aplicación o por cliente y reserve master para la administración. Para endurecer la instancia, desactive el registro libre, active el brute force detection en Realm Settings > Security Defenses y aprovisione todo mediante ficheros de importación de realm (--import-realm), de modo que versione su configuración en lugar de hacer clic en la interfaz.

Instala Keycloak en tu VPS

Keycloak está disponible en el Marketplace de ServOrbit: imagen oficial, base de datos PostgreSQL, HTTPS y cuenta de administrador listos al instalar.

¿Necesita ayuda?

Consulte nuestro centro de ayuda y nuestra FAQ, o contacte con nuestro equipo: llamada, WhatsApp o correo electrónico. Soporte en francés, inglés y árabe.

Escribir por WhatsAppse abre en una pestaña nueva