03a281d009
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
141 lines
5.6 KiB
YAML
141 lines
5.6 KiB
YAML
# Minecraft Java Edition module.
|
|
#
|
|
# Uses the itzg/minecraft-server community image — widely deployed, actively
|
|
# maintained, designed for panel/automation use. All configuration is driven
|
|
# by env vars (unlike 7DTD, which fights us). Boots in ~60-90s on first run
|
|
# (downloads the server jar) and ~10-15s on subsequent runs.
|
|
#
|
|
# RCON uses Source RCON (binary protocol), which our agent doesn't yet have
|
|
# an adapter for — so this module declares the RCON port/password for future
|
|
# use but leaves the `rcon:` section out for now. Adding a source_rcon adapter
|
|
# is ~200 lines in agent/internal/rcon/ when we get to it.
|
|
id: minecraft-java
|
|
name: "Minecraft Java Edition"
|
|
version: 0.1.0
|
|
authors:
|
|
- panel contributors
|
|
supported_modes:
|
|
- docker
|
|
runtime:
|
|
docker:
|
|
image: itzg/minecraft-server:latest
|
|
# Host networking -- container shares the host net namespace, so
|
|
# any port the game/mod binds is directly on the LAN. AMP-like
|
|
# model. Multi-instance safety comes from env-driven per-instance
|
|
# ports (panel allocator + env: mapping on each ports entry).
|
|
network_mode: host
|
|
env:
|
|
EULA: "TRUE"
|
|
TYPE: "VANILLA"
|
|
VERSION: "LATEST"
|
|
MEMORY: "2G"
|
|
ENABLE_RCON: "true"
|
|
RCON_PASSWORD: "panel_rcon" # default only — a generated per-instance secret overrides this at create
|
|
MOTD: "Running on panel"
|
|
ONLINE_MODE: "TRUE"
|
|
DIFFICULTY: "normal"
|
|
VIEW_DISTANCE: "10"
|
|
# Pre-declared so the agent's resolve.go filter lets allocator-derived
|
|
# ports flow through to the container env. itzg honors both SERVER_PORT
|
|
# and RCON_PORT — defaults match the manifest port defaults below.
|
|
SERVER_PORT: "25565"
|
|
RCON_PORT: "25575"
|
|
volumes:
|
|
# /data holds the whole server including worlds, mods, configs.
|
|
# Named volume for speed; survives instance recreation unless operator
|
|
# explicitly removes it.
|
|
- { type: volume, name: "panel-$INSTANCE_ID-mc", container: "/data" }
|
|
ports:
|
|
- { name: game, proto: tcp, default: 25565, required: true, env: SERVER_PORT }
|
|
- { name: rcon, proto: tcp, default: 25575, internal: true, env: RCON_PORT }
|
|
# Per-instance generated RCON secret — overrides the env default below
|
|
# at create so every instance gets a unique password.
|
|
secrets:
|
|
- name: RCON_PASSWORD
|
|
description: "Minecraft RCON password — generated per instance"
|
|
generated: true
|
|
rcon:
|
|
adapter: source_rcon
|
|
host_port: rcon
|
|
auth: source_rcon_login
|
|
password_secret: RCON_PASSWORD
|
|
# Legacy fallback only (pre-generated-secret instances). New instances
|
|
# always get the generated RCON_PASSWORD secret above.
|
|
password_literal: "panel_rcon"
|
|
commands:
|
|
list: "list"
|
|
say: "say {msg}"
|
|
kick: "kick {player} {reason}"
|
|
stop: "stop"
|
|
save: "save-all"
|
|
state_sources:
|
|
- type: rcon
|
|
command: "list"
|
|
every: 60s
|
|
parse:
|
|
kind: regex
|
|
pattern: 'There are (?P<players>\d+) of a max of (?P<max>\d+) players online'
|
|
fields:
|
|
players_online: players
|
|
players_max: max
|
|
resources:
|
|
min_ram_mb: 2048
|
|
recommended_ram_mb: 4096
|
|
|
|
# /data has world saves mixed with downloadable libraries/, mods/ cache,
|
|
# and the server jar. Back up the player-state stuff; libraries +
|
|
# server jar regenerate from itzg's image on next start.
|
|
backup:
|
|
include:
|
|
- "world" # default world dir (overworld)
|
|
- "world_nether" # nether
|
|
- "world_the_end" # end
|
|
- "*.properties" # server.properties + others
|
|
- "*.json" # whitelist, ops, banned-players, banned-ips, usercache
|
|
- "plugins" # bukkit/spigot plugins (config + state inside each)
|
|
- "mods" # Forge/Fabric mod jars (mod configs in plugins/)
|
|
- "config" # mod config files
|
|
exclude:
|
|
- "logs" # rotates infinitely
|
|
- "crash-reports" # never useful in restore
|
|
- "libraries" # auto-downloaded by itzg
|
|
- "cache" # JVM/itzg fluff
|
|
- "tmp"
|
|
notes: "World data + plugins + mods + configs (~50-500 MB typical). Server jar + libraries fetched fresh by itzg on next start."
|
|
# itzg/minecraft-server handles install + version pinning via the VERSION env
|
|
# var on first container start — there's no SteamCMD / GitHub / direct flow
|
|
# the panel needs to drive.
|
|
#
|
|
# But: the manifest validator REQUIRES at least one update_provider. So we
|
|
# keep a placeholder. Without `auto_update_on_create: false` the agent kicks
|
|
# off this provider on first boot and direct.go errors out on the missing
|
|
# target_path — observed 2026-04-29. The combination here (placeholder +
|
|
# auto-update opt-out) is the right shape for any image-managed module.
|
|
auto_update_on_create: false
|
|
update_providers:
|
|
- id: image-managed
|
|
kind: direct
|
|
url: "https://hub.docker.com/r/itzg/minecraft-server"
|
|
target_path: ".panel-image-managed-marker" # never written; auto-update is suppressed above
|
|
events:
|
|
join:
|
|
pattern: "(?P<name>[A-Za-z0-9_]+) joined the game"
|
|
kind: join
|
|
leave:
|
|
pattern: "(?P<name>[A-Za-z0-9_]+) left the game"
|
|
kind: leave
|
|
chat:
|
|
pattern: "<(?P<name>[A-Za-z0-9_]+)> (?P<msg>.*)"
|
|
kind: chat
|
|
|
|
# --- Manifest-driven UI metadata (WI-07) --------------------------
|
|
# Consumed by the CONTROLLER/dashboard only (the controller loads its
|
|
# own ./modules copy at startup); the agent ignores these at runtime.
|
|
# ready_pattern is a JavaScript regex (slash-delimited when it needs
|
|
# flags) moved verbatim from the dashboard's READY_PATTERNS map.
|
|
ready_pattern: 'Done \([\d.]+s\)! For help'
|
|
appearance:
|
|
emoji: "🧱"
|
|
grad: "linear-gradient(135deg,#4c8b32,#84ce5c)"
|
|
art: "/game-art/minecraft-java.png"
|