# Journiv Production Docker Compose (PostgreSQL).
# Journiv recommends using PostgreSQL based deployment over SQLite.
#
# Usage:
#   docker compose up -d
#
# Required Environment Variables:
#   SECRET_KEY      - Generate with: python -c "import secrets; print(secrets.token_urlsafe(32))"
#   DOMAIN_NAME     - Needed when running in same-origin SPA mode (ENABLE_CORS=false).
#   POSTGRES_PASSWORD - Must be provided in .env file.

x-base-env: &base-env
  REDIS_URL: redis://valkey:6379/0
  CELERY_BROKER_URL: redis://valkey:6379/0
  CELERY_RESULT_BACKEND: redis://valkey:6379/0
  DB_DRIVER: sqlite
  #   POSTGRES_HOST: postgres

x-celery-common: &celery-common
  image: swalabtech/journiv-app:${APP_VERSION:-latest}
  env_file: .env
  volumes:
    - /home/soenke/docker-data/journiv/app_data:/data
  depends_on:
    postgres:
      condition: service_healthy
    valkey:
      condition: service_healthy
  networks:
    - backend
  restart: unless-stopped
  logging:
    driver: "json-file"
    options:
      max-size: "50m"
      max-file: "5"
  deploy:
    resources:
      limits:
        cpus: "1.0"
        memory: 1g
      reservations:
        memory: 256m

x-app-common: &app-common
  image: swalabtech/journiv-app:${APP_VERSION:-latest}
  env_file: .env
  volumes:
    - /home/soenke/docker-data/journiv/app_data:/data
  depends_on:
    postgres:
      condition: service_healthy
    valkey:
      condition: service_healthy
  networks:
    - backend
  restart: unless-stopped
  logging:
    driver: "json-file"
    options:
      max-size: "50m"
      max-file: "5"

x-celery-healthcheck: &celery-healthcheck
  interval: 30s
  timeout: 10s
  retries: 5
  start_period: 40s

services:
  postgres:
    image: postgres:18.1
    container_name: journiv-postgres-db
    environment:
      - POSTGRES_USER=${POSTGRES_USER:-journiv}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} # must provide a password in .env file
      - POSTGRES_DB=${POSTGRES_DB:-journiv_prod}
    volumes:
    - /home/soenke/docker-data/journiv/postgres_data:/var/lib/postgresql
    networks:
      - backend
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 1g
        reservations:
          memory: 256m
    logging:
      driver: "json-file"
      options:
        max-size: "50m"
        max-file: "5"
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "pg_isready -U ${POSTGRES_USER:-journiv} -d ${POSTGRES_DB:-journiv_prod}",
        ]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 10s

  valkey:
    # Journiv uses Valkey which is similar to Redis for cache.
    image: valkey/valkey:9.0-alpine
    container_name: journiv-valkey-cache
    restart: unless-stopped
    volumes:
      - /home/soenke/docker-data/journiv/valkey_data:/data
    networks:
      - backend
    healthcheck:
      test: ["CMD", "valkey-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 10s

  celery-worker:
    <<: *celery-common
    container_name: journiv-celery-worker
    command: celery -A app.core.celery_app worker --loglevel=info
    environment:
      <<: *base-env
      SERVICE_ROLE: celery-worker
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    healthcheck:
      <<: *celery-healthcheck

  celery-beat:
    <<: *celery-common
    container_name: journiv-celery-beat
    command: celery -A app.core.celery_app beat --loglevel=info --scheduler redbeat.RedBeatScheduler --pidfile=/tmp/celerybeat.pid
    environment:
      <<: *base-env
      SERVICE_ROLE: celery-beat
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      REDBEAT_REDIS_URL: redis://valkey:6379/2
    healthcheck:
      <<: *celery-healthcheck

  app:
    <<: *app-common
    container_name: journiv-postgres-app
    ports:
      - "${APP_PORT:-8000}:8000"
    environment:
      <<: *base-env
      SERVICE_ROLE: app
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      ENVIRONMENT: production
      RATE_LIMIT_STORAGE_URI: redis://valkey:6379/1
    networks:
      - backend
      - frontend
    healthcheck:
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    deploy:
      resources:
        limits:
          cpus: "2.0"
          memory: 2g
        reservations:
          memory: 512m
    labels:
      kuma.tools.tag.name: 'Tools'
      kuma.tools.tag.color: '#FF9900'
      kuma.journiv.tag.name: 'Work'
      kuma.journiv.tag.color: '#FF9955'
      kuma.organization.tag.name: 'Organization'
      kuma.organization.tag.color: '#FF99AA'
      kuma.journiv.http.name: 'journiv'
      kuma.journiv.http.url: 'https://journiv.domr.ovh'
      kuma.journiv.http.tag_names: '[{"name": "tools", "value": "" }, {"name": "homelab", "value": "" }]'

#volumes:
#  app_data:
#  postgres_data:
#  valkey_data:

networks:
  backend:
    driver: bridge
  frontend:
    driver: bridge
