Saltar a contenido

Stack Keycloak + MySQL + API/Web

Servidor: srv-app-01 (Ubuntu 24.04)
Ruta del stack: /opt/apps/stack
Datos persistentes: - MySQL: /srv/mysql/data - Keycloak: /srv/keycloak/data

Variables de entorno

Archivo: /etc/stack/stack.env (600)

# MySQL root
MYSQL_ROOT_PASSWORD=********

# Base Keycloak (creada por init si volumen vacío)
MYSQL_DATABASE=keycloak
MYSQL_USER=keycloak
MYSQL_PASSWORD=********

# Conexión que usa KC
KC_DB=mysql
KC_DB_URL_HOST=mysql
KC_DB_URL_PORT=3306
KC_DB_URL_DATABASE=keycloak
KC_DB_NAME=keycloak
KC_DB_USERNAME=keycloak
KC_DB_PASSWORD=********
KC_HTTP_ENABLED=true
KC_HOSTNAME=auth.erre.com
KC_HOSTNAME_STRICT=false
KC_PROXY=edge

# App fastfood
FF_DB_NAME=fastfood
FF_DB_USER=fastfood
FF_DB_PASSWORD=********

Servicios (Docker Compose)

Archivo:/opt/apps/stack/docker-compose.yml

Puertos locales:

KC → 127.0.0.1:8080

API → 127.0.0.1:8081

WEB → 127.0.0.1:8082

Operación

cd /opt/apps/stack
sudo docker compose up -d            
sudo docker compose ps
sudo docker logs -n 80 keycloak

Salud de MySQL

docker ps --format "table {{.Names}}\t{{.Status}}"
sudo docker logs -n 50 mysql

Init DB fastfood (si hace falta)

sudo docker compose run --rm db-init
sudo docker logs mysql-init

Backups

Script (ejemplo):

mysqldump -uroot -p$MYSQL_ROOT_PASSWORD --all-databases --single-transaction > /backups/mysql-$(date +%F).sql
docker run --rm -v /srv/keycloak/data:/data alpine:3 tar czf - /data > /backups/kc-data-$(date +%F).tgz

Seguridad

Exponer servicios solo detrás de Nginx (HTTPS).

Limitar sudo del usuario deploy (NOPASSWD solo para acciones necesarias).

UFW: permitir 22/tcp desde IPs confiables, 80/443 si se publica hacia fuera.

Fail2ban activo para sshd.

Pruebas rápidas

curl -sI https://auth.erre.com | head -n1
curl -sI https://api.erre.com  | head -n1
curl -sI https://app.erre.com  | head -n1