# ──────────────────────────────────────────────────────────────────
# Ulicraft LAN-party stack — Minecraft 1.21.1 NeoForge + Drasl auth
# ──────────────────────────────────────────────────────────────────
# Single source of config: BASE_DOMAIN + HOST_LAN_IP in .env.
# DNS is provided by YOUR party DNS server — see tooling/dns-records.sh for the
# records to add (online vs airgap). A turnkey dnsmasq is available as an
# optional layer: docker-compose.dnsmasq.yml.
#   - caddy is the only HTTP ingress; holds mcnet aliases so the stack
#     resolves auth.${BASE_DOMAIN} / packwiz.${BASE_DOMAIN} internally too
#   - drasl handles auth (password login; NO Keycloak/OIDC in this stack)
#   - packwiz pack is served by caddy at packwiz.${BASE_DOMAIN}
#   - minecraft installs mods via PACKWIZ_URL, authlib-injector -> auth.
# ──────────────────────────────────────────────────────────────────

services:
  # Core ingress. Static site + air-gap mirror are layered in via override
  # files (docker-compose.static.yml / .mirror.yml) — see build-stack.sh --up.
  caddy:
    image: caddy:alpine
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"
    environment:
      BASE_DOMAIN: ${BASE_DOMAIN}
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
      - ./caddy/conf.d/00-core.caddy:/etc/caddy/conf.d/00-core.caddy:ro
      - ./caddy/conf.d/10-static.caddy:/etc/caddy/conf.d/10-static.caddy:ro
      - ./www:/srv/www:ro
      - ./mirror/launcher:/srv/launcher:ro
      - ./caddy/caddy-root-ca.crt:/srv/ca-pub/ca.crt:ro
      - ./pack:/srv/pack:ro
      # Custom (locally-hosted) mod jars live OUTSIDE ./pack so packwiz refresh
      # doesn't index them as direct files — they're external download targets
      # referenced by pack/mods/*.pw.toml. Served at pack.${BASE_DOMAIN}/custom/.
      - ./custom:/srv/pack/custom:ro
    networks:
      mcnet:
        # Only the stack's own subdomains in the base. The upstream spoof-host
        # aliases live in docker-compose.mirror.yml — adding them here would
        # hijack maven.neoforged.net / libraries.minecraft.net for ALL mcnet
        # containers, breaking the ONLINE NeoForge install during pre-bake.
        aliases:
          - "auth.${BASE_DOMAIN}"
          - "pack.${BASE_DOMAIN}"
  drasl:
    image: unmojang/drasl:latest
    container_name: drasl
    restart: unless-stopped
    # Internal-only: no published host port. Reached via Caddy at
    # auth.${BASE_DOMAIN} (Caddy holds the network alias on mcnet).
    volumes:
      - ./drasl/config:/etc/drasl:ro
      - drasl_state:/var/lib/drasl
    networks:
      - mcnet
    # No env vars — config is the rendered ./drasl/config/config.toml
    # (from config.toml.tmpl via tooling/render-config.sh).

  minecraft:
    image: itzg/minecraft-server:java21
    container_name: minecraft
    restart: unless-stopped
    stdin_open: true
    tty: true
    ports:
      - "25565:25565"
      - "24454:24454/udp"      # Simple Voice Chat, if used
    environment:
      EULA: "TRUE"
      TYPE: "NEOFORGE"
      VERSION: "1.21.1"
      # Verify NEOFORGE_VERSION against projects.neoforged.net before deploy.
      NEOFORGE_VERSION: "21.1.209"   # pin a known-good build; update deliberately

      # ── Memory / performance ────────────────────────────────────
      INIT_MEMORY: "4G"
      MAX_MEMORY: "10G"               # 8 players + 100 mods comfortably
      USE_AIKAR_FLAGS: "TRUE"
      JVM_XX_OPTS: "-XX:+UseG1GC"

      # ── Auth: offline mode + authlib-injector pointing at Drasl ─
      ONLINE_MODE: "FALSE"
      # mount authlib-injector.jar at /extras/authlib-injector.jar
      JVM_OPTS: "-javaagent:/extras/authlib-injector.jar=http://auth.${BASE_DOMAIN}/authlib-injector"

      # ── Server config ───────────────────────────────────────────
      DIFFICULTY: "normal"
      MODE: "survival"
      MOTD: "Uli LAN party"
      MAX_PLAYERS: "10"
      VIEW_DISTANCE: "10"
      SIMULATION_DISTANCE: "8"
      ENFORCE_SECURE_PROFILE: "FALSE"  # required for authlib-injector on 1.21+
      ALLOW_FLIGHT: "TRUE"             # many tech mods need this

      # ── Mod source: packwiz pack served by caddy ────────────────
      PACKWIZ_URL: "http://pack.${BASE_DOMAIN}/pack.toml"

      # ── RCON for remote admin ───────────────────────────────────
      ENABLE_RCON: "TRUE"
      RCON_PASSWORD: ${RCON_PASSWORD}
      RCON_PORT: 25575

      TZ: "Europe/Madrid"
    volumes:
      - mc_data:/data
      - ./runtime:/extras:ro       # authlib-injector.jar lives here
    depends_on:
      - drasl
      - caddy                      # packwiz pack is served by caddy
    networks:
      - mcnet

  # Optional: backups
  mc-backup:
    image: itzg/mc-backup
    container_name: mc-backup
    restart: unless-stopped
    environment:
      BACKUP_INTERVAL: "6h"
      RCON_HOST: "minecraft"
      RCON_PASSWORD: ${RCON_PASSWORD}
      PRUNE_BACKUPS_DAYS: "14"
      TZ: "Europe/Madrid"
    volumes:
      - mc_data:/data:ro
      - ./backups:/backups
    depends_on:
      - minecraft
    networks:
      - mcnet

volumes:
  drasl_state:
  mc_data:

networks:
  mcnet:
    driver: bridge
