Hola a tod@s,
En este post vamos a ver como desplegar keycloak con Docker, desplegaremos dos contenedores Docker para este servicio, uno de ellos será el de PostgreSQL para la base de datos que vamos a utilizar y el otro el propio de keycloak con la aplicación, este servicio irá desplegado, sobre la misma máquina dónde ya desplegamos un docker con Nginx Proxy Manager, que será el que utilicemos para los certificados SSL.
Keycloak es una solución de código abierto para la gestión de identidades y accesos (IAM), diseñada para asegurar aplicaciones y servicios modernos, permite añadir funciones de inicio de sesión único (SSO), autenticación, autorización y federación de usuarios (LDAP/AD, redes sociales) mediante estándares como OpenID Connect, OAuth 2.0 y SAML 2.0.
- Para empezar, vamos a ver que hemos preparado esta máquina virtual con Ubuntu Server 24.04 LTS, dónde tenemos dos discos, uno de sistema y otro de datos:
- Como podemos ver, el disco de datos lo hemos montado sobre /opt/docker que es dónde vamos a ubicar todos los contenedores Dockers y sus configuraciones:
- Nos creamos el registro DNS del tipo CNAME para keycloak apuntando a la máquina que tiene instalado el Docker con el Nginx Proxy Manager, ya que vamos a utilizar nuestro proxy inverso:
- Verificamos las versiones de Docker instaladas, docker –version, docker compose version:

- Ahora vamos a crear la estructura de directorios y permisos para los contenedores de postgreSQL y keycloak:
- sudo mkdir -p /opt/docker/keycloakdb/data
- sudo mkdir -p /opt/docker/keycloakapp/config
- sudo chmod -R 755 /opt/docker/keycloakdb
- sudo chmod -R 755 /opt/docker/keycloakapp
- Al directorio config de /opt/docker/keycloakapp le cambiamos el propietario con sudo chown -R 1000:1000 /opt/docker/keycloakapp/config, con esto le estamos diciendo al sistema, que esta carpeta ahora le pertenece al usuario 1000 (Keycloak), como el contenedor es el dueño, ya tiene permiso total por defecto para crear los archivos de transacciones para los logs:
- Ahora vamos a crearnos los ficheros .env para no dejar credenciales en texto plano en los ficheros docker-compose.yaml que crearemos posteriormente, utilizando para ello variables.
- Empezaremos con el fichero .env para el contenedor de postgreSQL, para ello, nos situamos en /opt/docker/ keycloakdb, y ejecutamos sudo nano .env:
- Y así definimos el fichero:
- POSTGRES_DB=keycloak
- POSTGRES_USER=keycloakuser
- POSTGRES_PASSWORD=clave_muy_segura_db
- Nos creamos el fichero docker-compose.yaml para el contenedor de postgreSQL en la misma ubicación, sudo nano docker-compose.yaml:
- Este sería el contenido del fichero:
services:
keycloak-db:
image: postgres:16.6
container_name: keycloak-db
restart: unless-stopped
env_file: .env
volumes:
– /opt/docker/keycloakdb/data:/var/lib/postgresql/data
networks:
– keycloak-net
networks:
keycloak-net:
name: keycloak-net
- Aquí vemos los ficheros creados:
- Seguimos con el fichero .env para el contenedor de keycloak-app, para ello, nos situamos en /opt/docker/keycloakapp, y ejecutamos sudo nano .env:
- Y así definimos el fichero:
- KC_DB=postgres
- KC_DB_URL=jdbc:postgresql://keycloak-db:5432/keycloak
- KC_DB_USERNAME=keycloakuser
- KC_DB_PASSWORD=clave_muy_segura_db
- KEYCLOAK_ADMIN=admkck
- KEYCLOAK_ADMIN_PASSWORD=clave_admin_keycloak
- Nos creamos el fichero docker-compose.yaml para el contenedor de keycloak-app en la misma ubicación, sudo nano docker-compose.yaml:
- Este sería el contenido del fichero:
services:
keycloak-app:
image: quay.io/keycloak/keycloak:26.1.3
container_name: keycloak-app
command:
– start-dev
– –proxy-headers=xforwarded
– –hostname=keycloak.ragasys.net
– –http-enabled=true
– –hostname-strict=false
restart: unless-stopped
env_file: .env
environment:
– KC_DB=${KC_DB}
– KC_DB_URL=${KC_DB_URL}
– KC_DB_USERNAME=${KC_DB_USERNAME}
– KC_DB_PASSWORD=${KC_DB_PASSWORD}
– KEYCLOAK_ADMIN=${KEYCLOAK_ADMIN}
– KEYCLOAK_ADMIN_PASSWORD=${KEYCLOAK_ADMIN_PASSWORD}
volumes:
– /opt/docker/keycloakapp/config:/opt/keycloak/data
networks:
– keycloak-net # Para comunicar con la DB
– internal-net # Para comunicar con Nginx Proxy Manager
networks:
keycloak-net:
external: true
internal-net:
external: true
- Aquí vemos los ficheros creados:
- Protegemos los archivos .env aplicando estos permisos:
- sudo chmod 600 /opt/docker/keycloakdb/.env
- sudo chmod 600 /opt/docker/ keycloakapp/.env
- Ahora, iniciamos primero el contenedor de postgreSQL, cd /opt/docker/keycloakdb/, sudo docker compose up -d:
- Iniciamos el contenedor de keycloak-app, cd /opt/docker/keycloakapp/, sudo docker compose up -d:
- Aquí vemos los contenedores levantados, sudo docker ps:
- Ahora accedemos a nuestro portal de Nginx Proxy Manager para crear el host para keycloak.
- Accedemos a Hosts > Hosts Proxy:
- Añadir Host Proxy:
- En la pestaña Detalles:
- Nombres de Dominio: ragasys.net
- Esquema: http
- Nombre de Host/IP de reenvío: keycloak-app
- Puerto: 8080
- Bloquear Exploits Comunes
- Soporte de Websockets
- En la pestaña SSL:
- Seleccionamos el Certificado SSL que nos interese
- Marcamos Forzar SSL
- Rueda configuración avanzada:
- 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 https;
- proxy_set_header X-Forwarded-Ssl on;
- # Esto es vital para que Keycloak no intente redirigir a http interno
- proxy_redirect http:// https://;
- Guardar
- Aquí vemos el host creado y conectado:
- Y como vemos ya tenemos acceso a nuestro keycloak a través de nuestro proxy inverso con Nginx Proxy Manager:
- Nos hemos creado un nuevo realm para nuestras aplicaciones:
- El rol del Realm master, el realm master es puramente para la administración del servidor de Keycloak.
- Se usa para crear otros Realms.
- Se usa para crear usuarios que sean administradores globales.
- Regla de oro, no registres tus aplicaciones (como phpIPAM, Nextcloud, etc.) ni a tus usuarios finales dentro de master.
- Por qué crear un Realm nuevo (Ragasys-Apps), al crear un realm específico para tus aplicaciones:
- Aislamiento, si te equivocas configurando algo en el realm de tus apps, el acceso de administración en master sigue funcionando.
- Seguridad, puedes tener políticas de contraseñas y 2FA distintas para los administradores en el master y para los usuarios en el nuevo realm.
- Orden, mantemos limpios los logs y la base de datos de usuarios.
- Sobre el real que hemos creado, accedemos a Authentication > Required actions > Configure OTP habilitamos Configure OTP y Set as default action, esto obligará a configurar el 2FA a todos los usuarios:
Saludos y espero que os sea de ayuda 😉






























