name: ${COMPOSE_PROJECT_NAME:-claude-code-hub}
services:
  postgres:
    image: postgres:18
    restart: unless-stopped
    env_file:
      - ./.env
    environment:
      POSTGRES_USER: ${DB_USER:-postgres}
      POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
      POSTGRES_DB: ${DB_NAME:-claude_code_hub}
      PGDATA: /data/pgdata
      TZ: Asia/Shanghai
      PGTZ: Asia/Shanghai
    volumes:
      - ./data/postgres:/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres} -d ${DB_NAME:-claude_code_hub}"]
      interval: 5s
      timeout: 5s
      retries: 10
      start_period: 10s
    networks:
      - 1panel-network
  redis:
    image: redis:7-alpine
    restart: unless-stopped
    volumes:
      - ./data/redis:/data
    command: redis-server --appendonly yes
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5
      start_period: 5s
    networks:
      - 1panel-network
  app:
    container_name: ${CONTAINER_NAME}
    image: ghcr.io/ding113/claude-code-hub:latest
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    env_file:
      - ./.env
    environment:
      NODE_ENV: production
      DSN: postgresql://${DB_USER:-postgres}:${DB_PASSWORD:-postgres}@postgres:5432/${DB_NAME:-claude_code_hub}
      REDIS_URL: redis://redis:6379
      AUTO_MIGRATE: ${AUTO_MIGRATE:-true}
      ENABLE_RATE_LIMIT: ${ENABLE_RATE_LIMIT:-true}
      ENABLE_SECURE_COOKIES: ${ENABLE_SECURE_COOKIES:-false}
      SESSION_TTL: ${SESSION_TTL:-300}
      DB_POOL_IDLE_TIMEOUT: ${DB_POOL_IDLE_TIMEOUT:-20}
      DB_POOL_CONNECT_TIMEOUT: ${DB_POOL_CONNECT_TIMEOUT:-10}
      MAX_RETRY_ATTEMPTS_DEFAULT: ${MAX_RETRY_ATTEMPTS_DEFAULT:-2}
      LANGFUSE_SAMPLE_RATE: ${LANGFUSE_SAMPLE_RATE:-1.0}
      TZ: Asia/Shanghai
    ports:
      - "${PANEL_APP_PORT_HTTP}:3000"
    restart: unless-stopped
    healthcheck:
      test:
        [
          "CMD",
          "node",
          "-e",
          "fetch('http://' + (process.env.HOSTNAME || '127.0.0.1') + ':3000/api/actions/health').then((r)=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))",
        ]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 30s
    networks:
      - 1panel-network
    labels:
      createdBy: "Apps"
networks:
  1panel-network:
    external: true
