services: keycloak: image: quay.io/keycloak/keycloak:26.8 restart: unless-stopped command: start environment: KC_DB: postgres KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak KC_DB_USERNAME: keycloak KC_DB_PASSWORD: ${POSTGRES_PASSWORD} KC_HOSTNAME: ${URL} # The proxy serves HTTPS and passes requests on over HTTP, saying in X-Forwarded-* who sent # them and how. KC_HTTP_ENABLED: "true" KC_PROXY_HEADERS: xforwarded KC_HEALTH_ENABLED: "true" # The administrator of the master realm is made from these at the first start, before # Keycloak answers anyone; Keycloak calls it temporary until a permanent one replaces it. KC_BOOTSTRAP_ADMIN_USERNAME: ${ADMIN_USERNAME} KC_BOOTSTRAP_ADMIN_PASSWORD: ${ADMIN_PASSWORD} depends_on: postgres: condition: service_healthy # The port listens before Keycloak is ready: the deploy waits for its readiness, which its # management port answers. The image has no curl: bash asks it. healthcheck: test: ["CMD-SHELL", "exec 3<>/dev/tcp/127.0.0.1/9000 && printf 'GET /health/ready HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n' >&3 && grep -q '\"UP\"' <&3"] interval: 5s timeout: 5s retries: 5 start_period: 180s postgres: image: postgres:18-alpine restart: unless-stopped environment: POSTGRES_DB: keycloak POSTGRES_USER: keycloak POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - db:/var/lib/postgresql healthcheck: test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U keycloak -d keycloak"] interval: 5s timeout: 5s retries: 10 start_period: 30s volumes: db: