# Default PiCloud stack. Runs the full system end-to-end behind a single
# Caddy entrypoint, suitable for local development and for verifying that
# the wiring still works after architectural changes.
#
# Caddy is exposed on host port ${PICLOUD_HOST_PORT:-8000} (defaults to
# 8000 because host port 80 commonly needs sudo on Linux and port 8080 is
# already in use on this dev machine).
#
# For real production deployment, layer the production overrides on top:
#   docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

name: picloud

services:
  postgres:
    image: postgres:16-alpine
    # The default ceiling of 100 is not enough to RUN THE TEST SUITE. libtest runs
    # ~nproc tests concurrently, and every `#[sqlx::test]` opens its own pool
    # against its own throwaway database — on a 16-core box that alone exceeds 100,
    # and Postgres answers with "sorry, too many clients already". The DB-backed
    # tests were all `#[ignore]`d and CI never passed `--include-ignored`, so this
    # ceiling was never actually exercised; it surfaced the moment CI started
    # running them. Serving the app needs nothing like this many.
    command: postgres -c max_connections=500
    environment:
      POSTGRES_DB: ${POSTGRES_DB:-picloud}
      POSTGRES_USER: ${POSTGRES_USER:-picloud}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-picloud}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      # Exposed in dev so you can poke at the DB with psql. Configurable
      # because the conventional 5432 is often already in use locally;
      # the prod overlay removes this mapping entirely.
      - "127.0.0.1:${PICLOUD_POSTGRES_HOST_PORT:-15432}:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-picloud} -d ${POSTGRES_DB:-picloud}"]
      interval: 5s
      timeout: 3s
      retries: 10

  picloud:
    build:
      context: .
      dockerfile: docker/orchestrator.Dockerfile
    environment:
      PICLOUD_BIND: 0.0.0.0:8080
      DATABASE_URL: postgres://${POSTGRES_USER:-picloud}:${POSTGRES_PASSWORD:-picloud}@postgres:5432/${POSTGRES_DB:-picloud}
      RUST_LOG: ${RUST_LOG:-info}
      PICLOUD_PUBLIC_BASE_URL: ${PICLOUD_PUBLIC_BASE_URL:-http://localhost:8000}
      # Bootstrap admin (Phase 3a). Read once on first start to seed the
      # admin_users table; ignored on subsequent boots if the table is
      # non-empty. No defaults on purpose — leaving these unset in prod
      # is a foot-gun. For dev, .env.example documents sensible values.
      PICLOUD_ADMIN_USERNAME: ${PICLOUD_ADMIN_USERNAME:?set PICLOUD_ADMIN_USERNAME (see .env.example)}
      PICLOUD_ADMIN_PASSWORD: ${PICLOUD_ADMIN_PASSWORD:?set PICLOUD_ADMIN_PASSWORD (see .env.example)}
    depends_on:
      postgres:
        condition: service_healthy
    expose:
      - "8080"

  dashboard:
    build:
      context: ./dashboard
      dockerfile: ../docker/dashboard.Dockerfile
    expose:
      - "80"

  caddy:
    image: caddy:2-alpine
    restart: unless-stopped
    ports:
      - "${PICLOUD_HOST_PORT:-8000}:80"
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
    depends_on:
      picloud:
        condition: service_started
      dashboard:
        condition: service_started

volumes:
  postgres_data:
  caddy_data:
  caddy_config:
