name: minecraft x-logging: &logging logging: driver: json-file options: max-size: "10m" max-file: "3" services: # ── Minecraft server (Fabric via itzg/minecraft-server) ───────────────── mc: image: itzg/minecraft-server:java25@sha256:783d2712019a3996b4168752517a08d3448ef8995879b200316c3888f98dc394 container_name: mc restart: unless-stopped <<: *logging stop_grace_period: 2m tty: false stdin_open: false environment: EULA: "TRUE" TYPE: ${SERVER_TYPE:-FABRIC} VERSION: ${MC_VERSION:-26.3} MEMORY: ${MC_MEMORY:-6G} FABRIC_LOADER_VERSION: "0.19.5" FABRIC_LAUNCHER_VERSION: "1.1.2" # Offline mode + whitelist as the approval gate (see docs/auth-flow.md). # enforce-secure-profile must be off or offline-launcher players are # rejected before EasyAuth can even prompt them (EasyAuth issue #68). ONLINE_MODE: "FALSE" ENFORCE_SECURE_PROFILE: "FALSE" ENABLE_WHITELIST: "TRUE" ENFORCE_WHITELIST: "TRUE" MOTD: ${MC_MOTD:-A cozy server for friends} DIFFICULTY: ${MC_DIFFICULTY:-normal} MAX_PLAYERS: ${MC_MAX_PLAYERS:-10} VIEW_DISTANCE: ${MC_VIEW_DISTANCE:-10} SIMULATION_DISTANCE: ${MC_SIMULATION_DISTANCE:-8} SEED: ${MC_SEED:-} SPAWN_PROTECTION: "0" # RCON is only reachable inside the compose network (never published) ENABLE_RCON: "true" RCON_PASSWORD: ${RCON_PASSWORD:?generate with scripts/setup.sh} # Reviewed exact Modrinth version IDs. Update these with Minecraft. MODRINTH_PROJECTS: ${MODRINTH_PROJECTS:-fabric-api:bNnaTiuM,easyauth:Qd0CWVQP,spark:e3hsPc1o,lithium:xS0Q8LSi,ferrite-core:d5ddUdiB} MODRINTH_DOWNLOAD_DEPENDENCIES: none # Modpack support (leave empty for lean Fabric; see docs/mods-and-modpacks.md) MODRINTH_MODPACK: ${MODRINTH_MODPACK:-} TZ: ${TZ:-UTC} ports: - "${MC_PORT:-25565}:25565" volumes: - ./data/mc:/data mem_limit: ${MC_CONTAINER_MEM_LIMIT:-7g} # ── Scheduled world backups (itzg/mc-backup) ───────────────────────────── backup: image: itzg/mc-backup:latest@sha256:5ddce05d917f7fb94c752e7be5aeb67ec043360615b0043d9b40a78809de0383 container_name: mc-backup restart: unless-stopped <<: *logging environment: BACKUP_INTERVAL: ${BACKUP_INTERVAL:-24h} INITIAL_DELAY: 10m PRUNE_BACKUPS_DAYS: ${BACKUP_RETENTION_DAYS:-7} BACKUP_NAME: world TAR_COMPRESS_METHOD: gzip PAUSE_IF_NO_PLAYERS: "false" RCON_HOST: mc RCON_PORT: "25575" RCON_PASSWORD: ${RCON_PASSWORD} EXCLUDES: "*.tmp,cache,logs" TZ: ${TZ:-UTC} volumes: - ./data/mc:/data:ro - ./data/backups:/backups depends_on: mc: condition: service_healthy # ── Web management dashboard ───────────────────────────────────────────── dashboard: build: ./dashboard image: minecraft-dashboard:local container_name: mc-dashboard restart: unless-stopped <<: *logging environment: PANEL_SESSION_SECRET: ${PANEL_SESSION_SECRET:?generate with scripts/setup.sh} PANEL_ADMIN_PASSWORD: ${PANEL_ADMIN_PASSWORD:-} RCON_HOST: mc RCON_PORT: "25575" RCON_PASSWORD: ${RCON_PASSWORD} MC_CONTAINER: mc BACKUP_CONTAINER: mc-backup MC_DATA_DIR: /server-data/mc RESTORE_WORK_DIR: /server-data/restore BACKUPS_DIR: /server-data/backups APP_DATA_DIR: /server-data/dashboard PROJECT_DIR: ${PROJECT_DIR:?Set PROJECT_DIR to the absolute host checkout path} REGISTRATION_WINDOW_MINUTES: ${REGISTRATION_WINDOW_MINUTES:-2} DISCORD_WEBHOOK_URL: ${DISCORD_WEBHOOK_URL:-} TZ: ${TZ:-UTC} ports: # LAN/VPN only — do not port-forward this on your router (docs/networking.md) - "${DASHBOARD_PORT:-8080}:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock - ./data:/server-data - ${PROJECT_DIR:?Set PROJECT_DIR}:${PROJECT_DIR} mem_limit: 512m depends_on: - mc