Hello Stan,
the following configuration works for me (example env with caddy, keycloak and postgresql).
In my example I expose caddy / keycloak via the local domain id.acme.test, which I mapped to 127.0.0.1 in my /etc/hosts file.
I used mkcert to generate local the certificate and key: GitHub - FiloSottile/mkcert: A simple zero-config tool to make locally trusted development certificates with any names you'd like.
docker-compose.yml
services:
caddy-keycloak-db:
image: postgres:15
volumes:
- postgres_data_kc_caddy:/var/lib/postgresql/data
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password
ports:
- 5433:5432
healthcheck:
test: ["CMD-SHELL", "pg_isready -U keycloak"]
interval: 10s
timeout: 5s
retries: 5
caddy-keycloak:
image: quay.io/keycloak/keycloak:26.0.0
environment:
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
KC_DB: postgres
KC_DB_SCHEMA: public
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: password
KC_DB_URL: jdbc:postgresql://caddy-keycloak-db/keycloak
KC_HOSTNAME_STRICT: "false"
KC_HTTP_ENABLED: "true"
KC_HTTP_HOSTNAME: "https://id.acme.test:5443"
KC_PROXY_HEADERS: "xforwarded"
KC_LOG_LEVEL: "INFO,org.infinispan:INFO,org.jgroups:DEBUG"
KC_METRICS_ENABLED: "true"
KC_HEALTH_ENABLED: "true"
KC_FEATURES: preview
JAVA_OPTS_APPEND: "-Djgroups.thread_dumps_threshold=1"
ports:
- 8080:8080
- 9000:9000
- 8443:8443
command:
- "--verbose"
- "start"
- "--spi-events-listener-jboss-logging-success-level=info"
- "--spi-events-listener-jboss-logging-error-level=warn"
depends_on:
caddy-keycloak-db:
condition: service_healthy
caddy-lb:
image: caddy:2.8-alpine
volumes:
- ./caddy.json:/etc/caddy/caddy.json:z
- ./cert.pem:/etc/caddy/server.crt:z
- ./cert-key.pem:/etc/caddy/server.key:z
command: [ "caddy", "run", "--config", "/etc/caddy/caddy.json"]
ports:
- "5443:443"
depends_on:
- caddy-keycloak
volumes:
postgres_data_kc_caddy:
driver: local
caddy.json:
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"id.acme.test"
]
}
],
"handle": [
{
"handler": "reverse_proxy",
"transport": {
"protocol": "http"
},
"upstreams": [
{
"dial": "caddy-keycloak:8080"
}
],
"load_balancing": {
"selection_policy": {
"policy": "ip_hash"
},
"try_duration": "1s",
"try_interval": "250ms"
},
"health_checks": {
"active": {
"uri": "/health",
"port": 9000,
"interval": "3s",
"timeout": "2s",
"expect_status": 200
}
}
}
],
"terminal": true
}
]
}
}
},
"tls": {
"certificates": {
"load_files": [
{
"certificate": "/etc/caddy/server.crt",
"key": "/etc/caddy/server.key",
"tags": [
"selfsigned"
]
}
]
}
}
}
}
After you created the certificate and key you should be able to do
docker compose up
and access the environment via https://id.acme.test:5443/admin
Note, that if you want to use a custom context path like /auth you need to specify
the env variable: KC_HTTP_RELATIVE_PATH: "/auth" for the Keycloak container AND
adjust the health check uri in the proxy config: "uri": "/auth/health".
Cheers,
Thomas