Minecraft Java Deploy Role¶
Deploy a Minecraft Java Edition server with RCON support, automated backups, and systemd service management.
This role supports two runtime modes:
vanilla(default)forge(for modded servers)
Requirements¶
Ubuntu/Debian target system
ansible-core 2.20+
community.generalcollection (UFW module)Outbound internet on target host for Forge installer mode (Mojang + Maven mirrors)
Mode Matrix¶
Capability |
|
|
|---|---|---|
Runtime entrypoint |
|
Managed wrapper |
Required artifact config |
|
|
Mods management |
No |
Yes ( |
Backup archive extras |
World + base files |
World + base files + |
Default startup timeout |
60s |
300s |
Required Variables¶
Always required:
minecraft_java_eula_agreed: "true"
minecraft_java_rcon_password: "..."
Required in vanilla mode:
minecraft_java_loader_mode: vanilla
minecraft_java_server_jar_url: "https://..."
minecraft_java_server_jar_sha256: "..."
Required in forge mode:
minecraft_java_loader_mode: forge
minecraft_java_forge_version: "1.20.1-47.4.0"
minecraft_java_forge_installer_url: "https://..."
minecraft_java_forge_installer_sha256: "..." # preferred
# or fallback:
# minecraft_java_forge_installer_sha1: "..."
Key Variables¶
Core mode/safety:
minecraft_java_loader_mode:vanillaorforgeminecraft_java_allow_mode_switch_same_world: defaultfalseminecraft_java_startup_timeout: defaults to60(vanilla) or300(forge)
Forge runtime:
minecraft_java_forge_installer_pathminecraft_java_forge_unix_args_pathminecraft_java_forge_user_jvm_args_pathminecraft_java_forge_wrapper_script_pathminecraft_java_forge_version_marker_pathminecraft_java_forge_checksum_marker_path
Mods:
minecraft_java_mods_enabled: defaultfalseminecraft_java_mods_prune_unmanaged: defaultfalseminecraft_java_mods: list of mod definitions
Mod entry schema:
minecraft_java_mods:
- name: "example-mod"
version: "1.2.3" # optional metadata
url: "https://example.org/mod.jar"
sha256: "..."
filename: "example-mod.jar" # optional override
enabled: true # optional, default true
enabled: false means the jar is removed from mods/ so it cannot load.
Mode Switch Guardrail¶
The role tracks loader mode in {{ minecraft_java_server_dir }}/.loader_mode.
Missing marker is treated as
vanillafor backward compatibility.If loader mode changes and world name stays the same, deployment fails by default.
Override only when intentional:
minecraft_java_allow_mode_switch_same_world: true
This is to prevent accidental world downgrade/corruption when switching versions/loaders.
JVM Args in Forge Mode¶
In forge mode, JVM args are managed in user_jvm_args.txt:
-Xms{{ minecraft_java_memory_min }}-Xmx{{ minecraft_java_memory_max }}minecraft_java_extra_args
The service uses a managed wrapper script that performs exec java ... directly with Forge unix_args.txt, so systemd tracks the Java PID cleanly.
Backup Behavior¶
Tier 1 cron backup:
Uses
systemctl is-activeto verify service state (mode-agnostic)Uses RCON
save-off/save-all/save-onvanilla: archives world + core server filesforge: archives world + core files +mods/+config/
Tier 2 backup/restore roles continue to work unchanged.
Migration Guide¶
Vanilla -> Forge:
Create a backup first.
Set
minecraft_java_loader_mode: forge.Set Forge installer/version/checksum variables.
Prefer a new
minecraft_java_world_namefor safety.Optionally enable and configure
minecraft_java_mods*.Deploy and verify startup logs and RCON.
Forge -> Vanilla:
Create a backup.
Set
minecraft_java_loader_mode: vanilla.Set
minecraft_java_server_jar_url+minecraft_java_server_jar_sha256.Deploy and verify startup.
Rollback note: switching Forge -> vanilla does not automatically delete Forge artifacts (mods/, config/, Forge libraries/run files). This is expected; clean up manually if desired.
World Version Warning¶
Do not reuse a higher-version world when switching to an older Minecraft/Forge stack.
If current world was opened on a newer version, use a fresh world name or a compatible restore point.
Example Playbook Snippets¶
Vanilla:
- role: local.ops_library.minecraft_java_deploy
vars:
minecraft_java_loader_mode: vanilla
minecraft_java_eula_agreed: "true"
minecraft_java_server_jar_url: "{{ minecraft_secrets.server_jar_url }}"
minecraft_java_server_jar_sha256: "{{ minecraft_secrets.server_jar_sha256 }}"
minecraft_java_rcon_password: "{{ minecraft_secrets.rcon_password }}"
Forge:
- role: local.ops_library.minecraft_java_deploy
vars:
minecraft_java_loader_mode: forge
minecraft_java_eula_agreed: "true"
minecraft_java_forge_version: "{{ minecraft_secrets.forge_version }}"
minecraft_java_forge_installer_url: "{{ minecraft_secrets.forge_installer_url }}"
minecraft_java_forge_installer_sha256: "{{ minecraft_secrets.forge_installer_sha256 }}"
minecraft_java_rcon_password: "{{ minecraft_secrets.rcon_password }}"
minecraft_java_mods_enabled: true
minecraft_java_mods: "{{ minecraft_secrets.mods }}"
Service Operations¶
systemctl status minecraft-java
journalctl -u minecraft-java -f
mcrcon -H 127.0.0.1 -P 25575 -p "PASSWORD" -t
Security Notes¶
RCON port (25575) is blocked externally via UFW
Game port (25565) allowed only from configured networks
Service runs as dedicated
minecraftuserSystemd hardening enabled (
NoNewPrivileges,PrivateTmp,ProtectSystem)
License¶
MIT