services:
    caddy:
        # Use the latest official Caddy image
        image: caddy:latest
        # Docker Compose automatically generates container names: <folder>_<service>_<index>
        container_name: caddy # Fixed name used by Docker engine
        # Automatically restart unless manually stopped
        restart: unless-stopped
        ports:
            # Expose HTTP (ACME + redirect)
            - "80:80"
            # Expose HTTPS/WSS (frontend, backend, LiveKit)
            - "443:443"
        volumes:
            # Mount the Caddy config file read-only
            - ./Caddyfile:/etc/caddy/Caddyfile:ro 
            # Caddy TLS certs (persistent Docker volume)
            - caddy_data:/data
            # Internal Caddy state/config
            - caddy_config:/config
        networks:
            # Attach to the shared "proxy" network
            - proxy

    gitea:
        # Official Gitea image with built-in Actions
        image: gitea/gitea:latest
        container_name: gitea # Fixed name used by Docker engine
        # Auto-restart service
        restart: unless-stopped
        environment:
            # Run Gitea as host user 1000 (prevents permission issues)
            - USER_UID=1000
            # Same for group
            - USER_GID=1000
            # Use SQLite (stored inside /data)
            - GITEA__database__DB_TYPE=sqlite3
            # Location of the SQLite DB
            - GITEA__database__PATH=/data/gitea/gitea.db
            # Custom config directory
            - GITEA_CUSTOM=/data/gitea
        volumes:
            # Bind mount instead of Docker volume because:
            # - We want repos, configs, SSH keys, and SQLite DB **visible and editable** on host
            # - Easy backups (just copy `./gitea-data`)
            # - Easy migration
            # - Avoids losing data if Docker volumes are pruned
            - ./gitea-data:/data
        networks:
            - proxy
        ports:
            # SSH for Git operations mapped to host 2222
            - "2222:22"

    gitea-runner:
        # Official Gitea Actions Runner
        image: gitea/act_runner:latest
        container_name: gitea-runner # Fixed name used by Docker engine
        restart: unless-stopped
        depends_on:
            # Runner requires Gitea to be available
            - gitea
        volumes:
            # Runner uses host Docker daemon to spin up job containers (Docker-out-of-Docker)
            - /var/run/docker.sock:/var/run/docker.sock
            # Bind mount instead of volume because:
            # - Runner identity is stored in /data/.runner
            # - Must persist across container recreations
            # - Prevents duplicated runner registrations in Gitea
            # - Easy to inspect/reset via `./gitea-runner-data/.runner`
            - ./gitea-runner-data:/data
        environment:
            # Base URL of your Gitea instance
            - GITEA_INSTANCE_URL=${GITEA_INSTANCE_URL}
            # One-time registration token
            - GITEA_RUNNER_REGISTRATION_TOKEN=${GITEA_RUNNER_REGISTRATION_TOKEN}
            # Human-readable name for the runner
            - GITEA_RUNNER_NAME=${GITEA_RUNNER_NAME}
            # Runner labels (e.g., ubuntu-latest)
            - GITEA_RUNNER_LABELS=${GITEA_RUNNER_LABELS}
            # Set container timezone to UTC for consistent logs
            - TZ=Etc/UTC
        networks:
            - proxy
        # Start runner using persisted config
        command: ["act_runner", "daemon", "--config", "/data/.runner"]

networks:
    proxy:
        # Shared network for Caddy + Gitea (+ later app stack)
        name: proxy
        # Default Docker bridge network
        driver: bridge

volumes:
    # Docker volume for Caddy TLS data (safe to keep inside Docker)
    caddy_data:
            name: caddy_data
    # Docker volume for internal Caddy configs/state
    caddy_config:
            name: caddy_config
            