# ──────────────────────────────────────────────────────────────────
# 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.
#   - ingress is layered on, NOT in this base file: caddy (docker-compose.caddy.yml,
#     LAN/air-gap, holds mcnet aliases) OR the host's nginx (docker-compose.nginx.yml
#     + Let's Encrypt, production)
#   - drasl handles auth (password login; NO Keycloak/OIDC in this stack)
#   - packwiz pack is served by the ingress at pack.${BASE_DOMAIN}
#   - minecraft installs mods via PACKWIZ_URL, authlib-injector -> auth.
# ──────────────────────────────────────────────────────────────────

services:
  # NOTE: the HTTP(S) ingress is NOT in this base file.
  #   - LAN / air-gap: caddy (docker-compose.caddy.yml) — added by build-stack.sh
  #   - production:    the HOST's nginx + Let's Encrypt (docker-compose.nginx.yml
  #                    publishes drasl to localhost; nginx/ulicraft.conf.tmpl)
  # Base alone (drasl + minecraft + mc-backup) is not a complete deployment —
  # always layer one ingress file on top.
  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 the ingress ──────────
      # http + caddy alias by default; the nginx override switches this to
      # https + host-gateway (extra_hosts) for the production path.
      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                      # ingress (caddy/nginx) is layered separately
    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
