# Variante PRODUCTION : PostgreSQL + Keycloak (mode production) + app, # derrière Nginx Proxy Manager (TLS terminé par NPM). # # cp .env.prod.example .env.prod # puis renseigner les secrets # docker compose --env-file .env.prod -f docker-compose.prod.yml up -d --build # # NPM (2 Proxy Hosts, forward en http vers l'IP de l'hôte) : # auth.mkv2avi.maisongrondin.fr -> http://:8080 # mkv2avi.maisongrondin.fr -> http://:8090 # → SSL Let's Encrypt + Force SSL + Websockets Support activés sur les deux. name: mkv2avi services: db: image: postgres:16-alpine container_name: mkv2avi-db environment: POSTGRES_DB: keycloak POSTGRES_USER: keycloak POSTGRES_PASSWORD: ${KC_DB_PASSWORD:?KC_DB_PASSWORD manquant} volumes: - kc-db:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U keycloak -d keycloak"] interval: 5s timeout: 5s retries: 12 restart: unless-stopped keycloak: image: quay.io/keycloak/keycloak:26.0 container_name: mkv2avi-keycloak command: ["start", "--import-realm"] environment: KC_DB: postgres KC_DB_URL: jdbc:postgresql://db:5432/keycloak KC_DB_USERNAME: keycloak KC_DB_PASSWORD: ${KC_DB_PASSWORD:?KC_DB_PASSWORD manquant} KC_BOOTSTRAP_ADMIN_USERNAME: ${KC_ADMIN:-admin} KC_BOOTSTRAP_ADMIN_PASSWORD: ${KC_ADMIN_PASSWORD:?KC_ADMIN_PASSWORD manquant} # URL publique (issuer) — NPM termine le TLS, Keycloak sert en HTTP en interne KC_HOSTNAME: https://auth.mkv2avi.maisongrondin.fr KC_HTTP_ENABLED: "true" KC_PROXY_HEADERS: xforwarded KC_HEALTH_ENABLED: "true" volumes: - ./keycloak/realm-mkv2avi.json:/opt/keycloak/data/import/realm-mkv2avi.json:ro ports: - "${KC_HTTP_PORT:-8080}:8080" depends_on: db: condition: service_healthy healthcheck: test: ["CMD-SHELL", "exec 3<>/dev/tcp/127.0.0.1/9000 && echo -e 'GET /health/ready HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n' >&3 && cat <&3 | grep -q '200 OK'"] interval: 10s timeout: 5s retries: 30 start_period: 60s restart: unless-stopped mkv2avi: build: . image: mkv2avi:latest container_name: mkv2avi environment: - MAX_WORKERS=${MAX_WORKERS:-1} - OIDC_ISSUER=https://auth.mkv2avi.maisongrondin.fr/realms/mkv2avi - OIDC_CLIENT_ID=mkv2avi - OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET:?OIDC_CLIENT_SECRET manquant} - OIDC_REDIRECT_URI=https://mkv2avi.maisongrondin.fr/auth/callback - OIDC_POST_LOGOUT_REDIRECT_URI=https://mkv2avi.maisongrondin.fr/ - SESSION_SECRET=${SESSION_SECRET:?SESSION_SECRET manquant} - SESSION_HTTPS_ONLY=true volumes: - ${MEDIA_DIR:?MEDIA_DIR manquant}:/media:ro - ${OUTPUT_DIR:-./output}:/output ports: - "${APP_HTTP_PORT:-8090}:8000" depends_on: keycloak: condition: service_healthy # Repli si le conteneur ne résout pas le domaine public (hairpin NAT) : # décommente en remplaçant par l'IP de NPM/hôte. # extra_hosts: # - "auth.mkv2avi.maisongrondin.fr:192.168.1.200" restart: unless-stopped volumes: kc-db: