# DFIRe 1.9.0 release bundle
# Select exactly one database overlay; see README.md.

services:
  redis:
    image: redis:8-alpine@sha256:becdda6c7f4b3fb42e42fd7f120bbf5c54c4caaaf16f26da24e4563d2c1f0576
    container_name: dfire_redis_prod
    command:
      - sh
      - -c
      - 'exec redis-server --appendonly yes $${REDIS_PASSWORD:+--requirepass "$$REDIS_PASSWORD"}'
    environment:
      REDIS_PASSWORD: ${REDIS_PASSWORD:-}
      REDISCLI_AUTH: ${REDIS_PASSWORD:-}
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped
    networks:
      - dfire_internal

  backend:
    image: dfireadmin/dfire-backend:1.9.0@sha256:ac8442bffa3117d9109091c74440f1a32eb98b3616563e7b7f367c5b829654fc
    container_name: dfire_backend_prod
    volumes:
      - media_data:/app/media
      - static_data:/app/staticfiles
    environment:
      DEBUG: ${DEBUG:-false}
      SECRET_KEY: ${SECRET_KEY:?SECRET_KEY is required}
      REDIS_HOST: ${REDIS_HOST:-redis}
      REDIS_PORT: ${REDIS_PORT:-6379}
      REDIS_PASSWORD: ${REDIS_PASSWORD:-}
      ALLOWED_HOSTS: ${ALLOWED_HOSTS:?ALLOWED_HOSTS is required}
      CORS_ALLOWED_ORIGINS: ${CORS_ALLOWED_ORIGINS:?CORS_ALLOWED_ORIGINS is required}
      CSRF_TRUSTED_ORIGINS: ${CSRF_TRUSTED_ORIGINS:?CSRF_TRUSTED_ORIGINS is required}
      TRUST_PROXY_HEADERS: ${TRUST_PROXY_HEADERS:-false}
      DFIRE_ENVIRONMENT: ${DFIRE_ENVIRONMENT:-production}
      CREDENTIAL_ENCRYPTION_KEY: ${CREDENTIAL_ENCRYPTION_KEY:?CREDENTIAL_ENCRYPTION_KEY is required}
      AUTH_COOKIE_SECURE: ${AUTH_COOKIE_SECURE:-True}
      GUNICORN_WORKERS: ${GUNICORN_WORKERS:-2}
      DJANGO_SUPERUSER_EMAIL: ${DJANGO_SUPERUSER_EMAIL:-}
      DJANGO_SUPERUSER_PASSWORD: ${DJANGO_SUPERUSER_PASSWORD:-}
      DJANGO_SUPERUSER_USERNAME: ${DJANGO_SUPERUSER_USERNAME:-}
    depends_on:
      redis:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/api/health/"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 300s
    restart: unless-stopped
    networks:
      - dfire_internal
      - dfire_external

  qcluster:
    image: dfireadmin/dfire-backend:1.9.0@sha256:ac8442bffa3117d9109091c74440f1a32eb98b3616563e7b7f367c5b829654fc
    container_name: dfire_qcluster_prod
    command: python manage.py qcluster
    volumes:
      - media_data:/app/media
    environment:
      DEBUG: ${DEBUG:-false}
      SECRET_KEY: ${SECRET_KEY:?SECRET_KEY is required}
      REDIS_HOST: ${REDIS_HOST:-redis}
      REDIS_PORT: ${REDIS_PORT:-6379}
      REDIS_PASSWORD: ${REDIS_PASSWORD:-}
      DFIRE_ENVIRONMENT: ${DFIRE_ENVIRONMENT:-production}
      CREDENTIAL_ENCRYPTION_KEY: ${CREDENTIAL_ENCRYPTION_KEY:?CREDENTIAL_ENCRYPTION_KEY is required}
      DFIRE_DB_STATEMENT_TIMEOUT_MS: "0"
    depends_on:
      backend:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - dfire_internal
      - dfire_external

  slack-socket:
    image: dfireadmin/dfire-backend:1.9.0@sha256:ac8442bffa3117d9109091c74440f1a32eb98b3616563e7b7f367c5b829654fc
    container_name: dfire_slack_socket_prod
    command: python manage.py run_slack_socket
    volumes:
      - media_data:/app/media
    environment:
      DEBUG: ${DEBUG:-false}
      SECRET_KEY: ${SECRET_KEY:?SECRET_KEY is required}
      REDIS_HOST: ${REDIS_HOST:-redis}
      REDIS_PORT: ${REDIS_PORT:-6379}
      REDIS_PASSWORD: ${REDIS_PASSWORD:-}
      DFIRE_ENVIRONMENT: ${DFIRE_ENVIRONMENT:-production}
      CREDENTIAL_ENCRYPTION_KEY: ${CREDENTIAL_ENCRYPTION_KEY:?CREDENTIAL_ENCRYPTION_KEY is required}
    depends_on:
      backend:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - dfire_internal
      - dfire_external

  frontend:
    image: dfireadmin/dfire-frontend:1.9.0@sha256:163a5ac73cbf54755c4a12e587dfbe208d944b7c50207fc36854e7e50b5bf9d7
    container_name: dfire_frontend_prod
    ports:
      - "${FRONTEND_BIND:-0.0.0.0:8080:80}"
    volumes:
      - static_data:/app/staticfiles:ro
    depends_on:
      backend:
        condition: service_healthy
    healthcheck:
      # 127.0.0.1, not localhost: nginx listens on IPv4 only, localhost resolves
      # to ::1 first inside the container, and busybox wget does not fall back
      # to IPv4 the way curl does.
      test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://127.0.0.1/health"]
      interval: 30s
      timeout: 3s
      retries: 3
    restart: unless-stopped
    networks:
      - dfire_internal
      - dfire_external

volumes:
  postgres_data:
  redis_data:
  media_data:
  static_data:

networks:
  dfire_internal:
    driver: bridge
    internal: true
  dfire_external:
    driver: bridge
