services:
  db:
    image: mariadb:11
    restart: unless-stopped
    environment:
      MARIADB_DATABASE: ${DB_NAME}
      MARIADB_USER: ${DB_USER}
      MARIADB_PASSWORD: ${DB_PASSWORD}
      MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
    volumes:
      - dbdata:/var/lib/mysql
      - ./server/db/schema.sql:/docker-entrypoint-initdb.d/01-schema.sql:ro
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 10
    # No host port published by default — only the app needs the DB, over the
    # private compose network. Uncomment to inspect from the host:
    # ports:
    #   - "3306:3306"

  app:
    build: .
    restart: unless-stopped
    env_file: .env
    environment:
      DB_HOST: db
      UPLOAD_DIR: /app/uploads
      LOG_DIR: /app/logs
    depends_on:
      db:
        condition: service_healthy
    volumes:
      - uploads:/app/uploads
      # Bind-mount logs to the host so app.log is directly readable at ./logs/
      - ./logs:/app/logs
    # Only the PUBLIC API port (3000) is published. The internal server<->bot
    # port (INTERNAL_PORT, default 3001) is deliberately NOT listed here, so it
    # stays reachable only over the private compose network — Pangolin/the public
    # reverse proxy can never forward to it. See issue #33.
    # Binds 0.0.0.0 (no 127.0.0.1 prefix) so Pangolin can reach the container.
    ports:
      - "3000:3000"

  bot:
    build:
      context: .
      dockerfile: bot/Dockerfile
    restart: unless-stopped
    env_file: .env
    environment:
      DB_HOST: db
      # Internal config fetch goes to the app's UNPUBLISHED internal port (3001),
      # not the public 3000. Keep the port in sync with the app's INTERNAL_PORT.
      SITE_INTERNAL_URL: http://app:3001/internal/bot-config
      SITE_PUBLIC_URL: http://app:3000/api/v1/public
      LOG_DIR: /app/bot/logs
    depends_on:
      db:
        condition: service_healthy
      app:
        condition: service_started
    volumes:
      - ./bot/logs:/app/bot/logs
    # No published port — the bot's internal API (/internal/*) is reached only
    # by `app` over the private compose network, and must NEVER be exposed
    # through Pangolin/the public reverse proxy.

volumes:
  dbdata:
  uploads:
