diff --git a/Makefile b/Makefile deleted file mode 100644 index 19ffa6c..0000000 --- a/Makefile +++ /dev/null @@ -1,103 +0,0 @@ -# ============================================================================= -# Minecraft Podman Deployment - Makefile -# ============================================================================= -# Usage: -# make install # Install dependencies -# make deploy # Deploy Minecraft server -# make check # Dry-run (check mode) -# make debug # Verbose output -# make status # Check server status -# make backup # Run manual backup -# make restore # Restore from latest backup -# make logs # View server logs -# make stop # Stop Minecraft server -# make start # Start Minecraft server -# make restart # Restart Minecraft server -# make update # Update Minecraft to latest version -# make uninstall # Remove Minecraft deployment (dangerous!) -# ============================================================================= - -PLAYBOOK := site.yml -LIMIT ?= external-apps -INVENTORY := inventory/hosts - -.PHONY: help install deploy check debug status backup restore logs stop start restart update uninstall - -help: - @echo "Minecraft Podman Deployment Makefile" - @echo "" - @echo "Usage: make [target]" - @echo "" - @echo "Targets:" - @echo " install Install Ansible collections and dependencies" - @echo " deploy Deploy Minecraft server (default: $(LIMIT))" - @echo " check Dry-run deployment (--check mode)" - @echo " debug Deploy with verbose output" - @echo " status Check server status on remote" - @echo " backup Run manual backup on remote" - @echo " restore Restore from latest backup on remote" - @echo " logs View Minecraft server logs" - @echo " stop Stop Minecraft server" - @echo " start Start Minecraft server" - @echo " restart Restart Minecraft server" - @echo " update Update Minecraft to latest version" - @echo " uninstall Remove Minecraft deployment (DANGEROUS)" - @echo "" - @echo "Override target host: make deploy LIMIT=my-server" - -install: - @echo "Installing Ansible collections..." - ansible-galaxy collection install -r requirements.yml - -deploy: - @echo "Deploying Minecraft to $(LIMIT)..." - ansible-playbook $(PLAYBOOK) --limit $(LIMIT) - -check: - @echo "Dry-run deployment for $(LIMIT)..." - ansible-playbook $(PLAYBOOK) --limit $(LIMIT) --check - -debug: - @echo "Deploying with debug output for $(LIMIT)..." - ansible-playbook $(PLAYBOOK) --limit $(LIMIT) -vvv - -status: - @echo "Checking server status on $(LIMIT)..." - ansible $(LIMIT) -m shell -a 'systemctl status minecraft --no-pager' - -backup: - @echo "Running backup on $(LIMIT)..." - ansible $(LIMIT) -m shell -a '/opt/minecraft/backup.sh' - -restore: - @echo "Running restore on $(LIMIT)..." - ansible $(LIMIT) -m shell -a '/opt/minecraft/restore.sh' - -logs: - @echo "Viewing logs for $(LIMIT)..." - ansible $(LIMIT) -m shell -a 'journalctl -u minecraft -n 100 --no-pager' - -stop: - @echo "Stopping Minecraft server on $(LIMIT)..." - ansible $(LIMIT) -m systemd -a 'name=minecraft state=stopped' - -start: - @echo "Starting Minecraft server on $(LIMIT)..." - ansible $(LIMIT) -m systemd -a 'name=minecraft state=started' - -restart: - @echo "Restarting Minecraft server on $(LIMIT)..." - ansible $(LIMIT) -m systemd -a 'name=minecraft state=restarted' - -update: - @echo "Updating Minecraft on $(LIMIT)..." - ansible-playbook $(PLAYBOOK) --limit $(LIMIT) --tags update - -uninstall: - @echo "WARNING: This will remove the Minecraft deployment from $(LIMIT)" - @read -p "Are you sure? Type 'yes' to continue: " CONFIRM; \ - if [ "$$CONFIRM" = "yes" ]; then \ - ansible-playbook $(PLAYBOOK) --limit $(LIMIT) --tags uninstall; \ - else \ - echo "Aborted."; \ - fi diff --git a/README.md b/README.md deleted file mode 100644 index e8ca947..0000000 --- a/README.md +++ /dev/null @@ -1,190 +0,0 @@ -# Minecraft Podman Deployment (Ansible) - -Automated deployment of a Minecraft server running in a **Podman** container on a remote **Fedora** server using **Ansible**. - -## Architecture - -``` -┌─────────────────────────────────────────────────┐ -│ Ansible Control Node │ -│ (your machine) │ -│ ansible.cfg + site.yml + roles/ │ -└──────────────────────┬──────────────────────────┘ - │ SSH -┌──────────────────────▼──────────────────────────┐ -│ Fedora Server │ -│ "external-apps" │ -│ │ -│ ┌──────────────────────────────────────────┐ │ -│ │ Podman Container │ │ -│ │ itzg/minecraft-server:latest (Paper) │ │ -│ │ ┌────────────────────────────────────┐ │ │ -│ │ │ Minecraft Server (Java) │ │ │ -│ │ └────────────────────────────────────┘ │ │ -│ └──────────────────────────────────────────┘ │ -│ │ -│ systemd: minecraft.service │ -│ systemd: minecraft-backup.timer │ -│ data: /opt/minecraft/data │ -│ backups: /opt/minecraft/backups │ -└─────────────────────────────────────────────────┘ -``` - -## Directory Structure - -``` -external-minecraft/ -├── ansible.cfg # Ansible configuration -├── site.yml # Main deployment playbook -├── uninstall.yml # Cleanup playbook -├── requirements.yml # Galaxy collections -├── Makefile # Convenient wrapper -├── inventory/ -│ └── hosts # Server inventory -├── group_vars/ -│ └── all.yml # All configuration variables -├── host_vars/ # (optional) Per-host overrides -└── roles/ - └── minecraft-podman/ - ├── tasks/main.yml # All deployment tasks - ├── handlers/main.yml # Service handlers - ├── templates/ # Jinja2 templates - │ ├── minecraft.service.j2 - │ ├── minecraft.env.j2 - │ ├── server.properties.j2 - │ ├── Containerfile.j2 - │ ├── backup.sh.j2 - │ ├── restore.sh.j2 - │ ├── health-check.sh.j2 - │ └── jvm.opts.j2 - └── defaults/main.yml # Role defaults -``` - -## Prerequisites - -### On the control node (your machine) - -```bash -# Fedora/RHEL/CentOS -sudo dnf install python3-pip -pip3 install --user ansible - -# or via pipx -pipx install ansible - -# Debian/Ubuntu -sudo apt install ansible -``` - -### Install Ansible collections - -```bash -make install -# or -ansible-galaxy collection install -r requirements.yml -``` - -## Configuration - -Edit `group_vars/all.yml` to configure your server: - -| Variable | Description | Default | -|----------|-------------|---------| -| `minecraft.server_name` | Service/container name | `minecraft` | -| `minecraft.version` | Server version | `latest` | -| `minecraft.server_type` | Vanilla / Paper / etc. | `paper` | -| `minecraft.java_memory` | Java heap size | `4G` | -| `minecraft.max_players` | Max players | `20` | -| `minecraft.port` | Minecraft port | `25565` | -| `minecraft.rcon_password` | RCON password | `CHANGE_ME_NOW` | -| `minecraft.motd` | Server message of day | Welcome message | -| `paths.base_dir` | Install directory | `/opt/minecraft` | -| `backup.enabled` | Enable automatic backups | `true` | - -**IMPORTANT**: Change `minecraft.rcon_password` before deploying. - -## Deployment - -```bash -# Basic deployment -make deploy - -# With explicit host -make deploy LIMIT=external-apps - -# Or directly -ansible-playbook site.yml --limit external-apps - -# Dry-run -make check - -# Debug mode -make debug -``` - -## Management - -```bash -make status # Check server status -make logs # View recent logs -make restart # Restart the server -make stop # Stop the server -make start # Start the server -make backup # Run backup immediately -``` - -## Connecting to the Server - -In Minecraft, use: -``` -: -``` - -For the default setup: `external-apps:25565` - -## Backups - -Backups run automatically every 6 hours (configurable in `group_vars/all.yml` under `backup.schedule`). - -- **Location**: `/opt/minecraft/backups/` -- **Format**: `minecraft_YYYYMMDD_HHMMSS.tar.gz` -- **Retention**: 10 backups (configurable) - -Restore with: -```bash -make restore -``` - -## Uninstall - -```bash -make uninstall # Interactive confirmation -``` - -Or manually: -```bash -ansible-playbook uninstall.yml --limit external-apps -``` - -## Advanced Configuration - -### Custom Server Type - -Set `minecraft.server_type` to: -- `vanilla` - Official Mojang server -- `paper` - High-performance fork (recommended) -- `fabric` - Modding platform -- `forge` - Classic modding -- `purpur` - Paper fork with more features - -### Custom Container Image - -To use your own `Containerfile` instead of pulling a public image: -1. Set `minecraft.use_custom_container: true` in `group_vars` -2. The role will build and deploy a custom image - -### Extras - -- **RCON**: Enabled by default on port 25575. Allows remote console admin. -- **Whitelist**: Set `minecraft.whitelist_enabled: true` to require whitelist -- **Command Blocks**: Set `minecraft.enable_command_block: true` to enable diff --git a/ansible.cfg b/ansible.cfg deleted file mode 100644 index 1d42bdb..0000000 --- a/ansible.cfg +++ /dev/null @@ -1,18 +0,0 @@ -[defaults] -inventory = inventory/hosts -roles_path = roles -remote_user = boxswapper -host_key_checking = False -retry_files_enabled = False -stdout_callback = yaml -timeout = 30 - -[privilege_escalation] -become = True -become_method = sudo -become_user = root -become_ask_pass = False - -[ssh_connection] -pipelining = True -ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o ServerAliveInterval=30 diff --git a/group_vars/all.yml b/group_vars/all.yml deleted file mode 100644 index f3a638d..0000000 --- a/group_vars/all.yml +++ /dev/null @@ -1,162 +0,0 @@ ---- -# ============================================================================= -# Minecraft Podman Deployment - Global Variables -# ============================================================================= -# All variables defined here can be overridden in host_vars/.yml -# or passed at runtime with -e "variable=value" - -# ----------------------------------------------------------------------------- -# Server Configuration -# ----------------------------------------------------------------------------- -minecraft: - # Server name - used for systemd service naming and container name - server_name: "minecraft" - - # Minecraft version (latest, 1.21.4, 1.20.6, etc.) - version: "latest" - - # Server type: "vanilla", "paper", "fabric", "forge", "purpur" - server_type: "paper" - - # Memory allocation for Java (e.g., "4G", "8G", "2G") - java_memory: "4G" - - # Java JVM arguments (additional flags beyond memory) - java_args: "-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200" - - # Maximum players allowed - max_players: 20 - - # Server port (default Minecraft port: 25565) - port: 25565 - - # RCON port (for remote console access) - rcon_port: 25575 - - # Enable RCON (useful for management) - rcon_enabled: true - - # RCON password (CHANGE THIS!) - rcon_password: "CHANGE_ME_NOW" - - # Server MOTD (Message of the Day) - motd: "Welcome to the Minecraft Server!" - - # Game mode: survival, creative, adventure, spectator - game_mode: "survival" - - # Difficulty: peaceful, easy, normal, hard - difficulty: "normal" - - # Enable whitelist - whitelist_enabled: false - - # Allow command blocks - enable_command_block: false - - # View distance (chunks, max 32) - view_distance: 10 - - # Simulation distance (chunks) - simulation_distance: 6 - - # Online mode (true = requires Mojang account verification) - online_mode: true - - # Max world size (blocks, default 29999984) - max_world_size: 29999984 - - # Spawn protection (blocks around spawn that can't be modified) - spawn_protection: 16 - -# ----------------------------------------------------------------------------- -# Podman Configuration -# ----------------------------------------------------------------------------- -podman: - # Container image (itzg/minecraft-server is highly configurable) - image: "itzg/minecraft-server" - - # Image tag (usually the server type) - image_tag: "latest" - - # Container restart policy: always, unless-stopped, on-failure, no - restart_policy: "unless-stopped" - - # Container memory limit (leave empty for unlimited) - memory_limit: "" - - # CPU shares (relative weight) - cpu_shares: 1024 - - # Container log driver - log_driver: "journald" - - # Container log max size - log_max_size: "50m" - - # Container log max file count - log_max_file: "3" - - # Extra volumes to mount (format: "host_path:container_path:options") - extra_volumes: [] - - # Container labels - labels: - managed-by: "ansible" - app: "minecraft" - - # Network mode (host, bridge, or slirp4netns) - network_mode: "host" - -# ----------------------------------------------------------------------------- -# Path Configuration -# ----------------------------------------------------------------------------- -paths: - # Base installation directory - base_dir: "/opt/minecraft" - - # Data directory (where world, configs, etc. are stored) - data_dir: "/opt/minecraft/data" - - # Backup directory - backup_dir: "/opt/minecraft/backups" - - # Systemd service directory - systemd_dir: "/etc/systemd/system" - -# ----------------------------------------------------------------------------- -# Backup Configuration -# ----------------------------------------------------------------------------- -backup: - # Enable automatic backups - enabled: true - - # Backup schedule (cron format) - schedule: "0 */6 * * *" # Every 6 hours - - # Number of backups to retain - retention_count: 10 - - # Compress backups with gzip - compress: true - -# ----------------------------------------------------------------------------- -# Firewall Configuration -# ----------------------------------------------------------------------------- -firewall: - # Open Minecraft ports in firewalld - enabled: true - - # Additional ports to open (for mods, voice chat, etc.) - additional_ports: - - "19132/udp" # Bedrock (if needed) - -# ----------------------------------------------------------------------------- -# Monitoring (Optional) -# ----------------------------------------------------------------------------- -monitoring: - # Enable basic health checks - enabled: false - - # Health check interval in seconds - interval: 300 diff --git a/inventory/hosts b/inventory/hosts deleted file mode 100644 index 3b85261..0000000 --- a/inventory/hosts +++ /dev/null @@ -1,9 +0,0 @@ -# Ansible Inventory - External Minecraft Server -# Managed by Sisyphus for Minecraft Podman Deployment - -[minecraft] -external-apps ansible_host=external-apps ansible_user=boxswapper - -[minecraft:vars] -ansible_python_interpreter=/usr/bin/python3 -ansible_ssh_common_args='-o StrictHostKeyChecking=no' diff --git a/requirements.yml b/requirements.yml deleted file mode 100644 index c0afd2f..0000000 --- a/requirements.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -# Ansible Galaxy collections required by this deployment -# Install with: ansible-galaxy collection install -r requirements.yml - -collections: - - name: ansible.posix - version: ">=1.5.0" - - name: containers.podman - version: ">=1.10.0" diff --git a/roles/minecraft-podman/defaults/main.yml b/roles/minecraft-podman/defaults/main.yml deleted file mode 100644 index 3eb2c0d..0000000 --- a/roles/minecraft-podman/defaults/main.yml +++ /dev/null @@ -1,19 +0,0 @@ ---- -# ============================================================================= -# Minecraft Podman Deployment - Role Defaults -# ============================================================================= -# These are the default values for this role. They can be overridden by -# group_vars/all.yml, host_vars/.yml, or -e at runtime. -# ============================================================================= - -# User to run the Minecraft container as -minecraft_user: "minecraft" - -# Podman container name -podman_container_name: "minecraft" - -# Whether to use a custom Containerfile (true) or pull pre-built image (false) -minecraft_use_custom_container: "{{ minecraft.use_custom_container | default(false) }}" - -# Custom image name (only used if use_custom_container is true) -minecraft_custom_image_name: "minecraft-custom" diff --git a/roles/minecraft-podman/handlers/main.yml b/roles/minecraft-podman/handlers/main.yml deleted file mode 100644 index 62505b2..0000000 --- a/roles/minecraft-podman/handlers/main.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -# ============================================================================= -# Minecraft Podman Deployment - Handlers -# ============================================================================= - -- name: restart minecraft - ansible.builtin.systemd: - name: "{{ minecraft.server_name }}.service" - state: restarted - daemon_reload: true - -- name: reload systemd - ansible.builtin.systemd: - daemon_reload: true - -- name: restart firewalld - ansible.builtin.service: - name: firewalld - state: restarted - -- name: reload backup timer - ansible.builtin.systemd: - name: "{{ minecraft.server_name }}-backup.timer" - state: restarted - daemon_reload: true diff --git a/roles/minecraft-podman/tasks/main.yml b/roles/minecraft-podman/tasks/main.yml deleted file mode 100644 index 204c2e1..0000000 --- a/roles/minecraft-podman/tasks/main.yml +++ /dev/null @@ -1,423 +0,0 @@ ---- -# ============================================================================= -# Minecraft Podman Deployment - Main Tasks -# ============================================================================= -# This role deploys a Minecraft server using Podman on Fedora -# with systemd integration for service management - -# ----------------------------------------------------------------------------- -# System Preparation -# ----------------------------------------------------------------------------- -- name: System Preparation - block: - - name: Update DNF cache - ansible.builtin.dnf: - update_cache: true - state: present - tags: [install, packages] - - - name: Install required packages - ansible.builtin.dnf: - name: - - podman - - podman-plugins # Podman plugins (Netavark, etc.) - - fuse-overlayfs # Required for rootless storage - - slirp4netns # Required for rootless networking - - systemd-container # Systemd integration - - firewalld - - python3-firewall # For ansible firewalld module - - python3-podman # For ansible podman modules - - tar # For backups - - gzip # For compressed backups - - curl # For health checks - state: present - tags: [install, packages] - - - name: Ensure Podman is installed - ansible.builtin.command: podman --version - register: podman_version - changed_when: false - tags: [install, verify] - - - name: Display Podman version - ansible.builtin.debug: - msg: "Podman {{ podman_version.stdout }} installed" - tags: [install, verify] - - tags: [install, packages] - -# ----------------------------------------------------------------------------- -# User and Permissions -# ----------------------------------------------------------------------------- -- name: User Configuration - block: - - name: Create minecraft system user - ansible.builtin.user: - name: "{{ minecraft_user }}" - system: true - shell: /bin/bash - home: "{{ paths.base_dir }}" - create_home: false - comment: "Minecraft Server User" - when: minecraft_user != "root" - tags: [install, user] - - - name: Configure subuid for rootless podman - ansible.builtin.lineinfile: - path: /etc/subuid - line: "{{ minecraft_user }}:100000:65536" - regexp: "^{{ minecraft_user }}:" - state: present - create: true - mode: "0644" - when: minecraft_user != "root" - tags: [install, user] - - - name: Configure subgid for rootless podman - ansible.builtin.lineinfile: - path: /etc/subgid - line: "{{ minecraft_user }}:100000:65536" - regexp: "^{{ minecraft_user }}:" - state: present - create: true - mode: "0644" - when: minecraft_user != "root" - tags: [install, user] - - - name: Create user config directory for podman - ansible.builtin.file: - path: "{{ paths.base_dir }}/.config/containers" - state: directory - owner: "{{ minecraft_user }}" - group: "{{ minecraft_user }}" - mode: "0755" - when: minecraft_user != "root" - tags: [install, user] - - - name: Create user local share for podman storage - ansible.builtin.file: - path: "{{ paths.base_dir }}/.local/share/containers" - state: directory - owner: "{{ minecraft_user }}" - group: "{{ minecraft_user }}" - mode: "0755" - when: minecraft_user != "root" - tags: [install, user] - - - name: Ensure systemd lingering is enabled for user - ansible.builtin.command: "loginctl enable-linger {{ minecraft_user }}" - changed_when: false - when: minecraft_user != "root" - tags: [install, user] - - tags: [install] - -# ----------------------------------------------------------------------------- -# Directory Structure -# ----------------------------------------------------------------------------- -- name: Directory Setup - block: - - name: Create base directories - ansible.builtin.file: - path: "{{ item }}" - state: directory - owner: "{{ minecraft_user }}" - group: "{{ minecraft_user }}" - mode: "0755" - loop: - - "{{ paths.base_dir }}" - - "{{ paths.data_dir }}" - - "{{ paths.backup_dir }}" - - "{{ paths.data_dir }}/logs" - - "{{ paths.data_dir }}/world" - tags: [install, directories] - - - name: Create Containerfile directory - ansible.builtin.file: - path: "{{ paths.base_dir }}/container" - state: directory - owner: "{{ minecraft_user }}" - group: "{{ minecraft_user }}" - mode: "0755" - tags: [install, container] - - tags: [install] - -# ----------------------------------------------------------------------------- -# Container Build (if using custom Containerfile) -# ----------------------------------------------------------------------------- -- name: Container Build - block: - - name: Copy Containerfile - ansible.builtin.template: - src: Containerfile.j2 - dest: "{{ paths.base_dir }}/container/Containerfile" - owner: "{{ minecraft_user }}" - group: "{{ minecraft_user }}" - mode: "0644" - when: minecraft.use_custom_container | default(false) - tags: [install, container] - - - name: Build custom Minecraft container image - containers.podman.podman_image: - name: "{{ minecraft.custom_image_name | default('minecraft-custom') }}" - build: - path: "{{ paths.base_dir }}/container/" - file: Containerfile - tag: "{{ minecraft.version }}" - state: present - when: minecraft.use_custom_container | default(false) - tags: [install, container] - - tags: [install] - -# ----------------------------------------------------------------------------- -# Server Configuration -# ----------------------------------------------------------------------------- -- name: Server Configuration - block: - - name: Deploy server.properties - ansible.builtin.template: - src: server.properties.j2 - dest: "{{ paths.data_dir }}/server.properties" - owner: "{{ minecraft_user }}" - group: "{{ minecraft_user }}" - mode: "0644" - notify: restart minecraft - tags: [config] - - - name: Deploy eula.txt - ansible.builtin.copy: - content: "eula=true\n" - dest: "{{ paths.data_dir }}/eula.txt" - owner: "{{ minecraft_user }}" - group: "{{ minecraft_user }}" - mode: "0644" - tags: [config] - - - name: Deploy environment variables - ansible.builtin.template: - src: minecraft.env.j2 - dest: "{{ paths.base_dir }}/minecraft.env" - owner: "{{ minecraft_user }}" - group: "{{ minecraft_user }}" - mode: "0600" - notify: restart minecraft - tags: [config] - - - name: Deploy JVM options file - ansible.builtin.template: - src: jvm.opts.j2 - dest: "{{ paths.data_dir }}/jvm.opts" - owner: "{{ minecraft_user }}" - group: "{{ minecraft_user }}" - mode: "0644" - when: minecraft.jvm_opts_file | default(false) - notify: restart minecraft - tags: [config] - - tags: [config] - -# ----------------------------------------------------------------------------- -# Firewall Configuration -# ----------------------------------------------------------------------------- -- name: Firewall Configuration - block: - - name: Ensure firewalld is running - ansible.builtin.systemd: - name: firewalld - state: started - enabled: true - tags: [firewall] - - - name: Open Minecraft port - ansible.posix.firewalld: - port: "{{ minecraft.port }}/tcp" - permanent: true - immediate: true - state: enabled - tags: [firewall] - - - name: Open RCON port - ansible.posix.firewalld: - port: "{{ minecraft.rcon_port }}/tcp" - permanent: true - immediate: true - state: enabled - when: minecraft.rcon_enabled - tags: [firewall] - - - name: Open additional firewall ports - ansible.posix.firewalld: - port: "{{ item }}" - permanent: true - immediate: true - state: enabled - loop: "{{ firewall.additional_ports | default([]) }}" - tags: [firewall] - - tags: [firewall] - -# ----------------------------------------------------------------------------- -# Systemd Service -# ----------------------------------------------------------------------------- -- name: Systemd Service Configuration - block: - - name: Deploy systemd service unit - ansible.builtin.template: - src: minecraft.service.j2 - dest: "{{ paths.systemd_dir }}/{{ minecraft.server_name }}.service" - owner: root - group: root - mode: "0644" - notify: - - reload systemd - - restart minecraft - tags: [service] - - - name: Reload systemd daemon - ansible.builtin.systemd: - daemon_reload: true - tags: [service] - - - name: Enable and start Minecraft service - ansible.builtin.systemd: - name: "{{ minecraft.server_name }}.service" - state: started - enabled: true - tags: [service] - - tags: [service] - -# ----------------------------------------------------------------------------- -# Backup Configuration -# ----------------------------------------------------------------------------- -- name: Backup Configuration - block: - - name: Deploy backup script - ansible.builtin.template: - src: backup.sh.j2 - dest: "{{ paths.base_dir }}/backup.sh" - owner: "{{ minecraft_user }}" - group: "{{ minecraft_user }}" - mode: "0755" - when: backup.enabled - tags: [backup] - - - name: Deploy restore script - ansible.builtin.template: - src: restore.sh.j2 - dest: "{{ paths.base_dir }}/restore.sh" - owner: "{{ minecraft_user }}" - group: "{{ minecraft_user }}" - mode: "0755" - when: backup.enabled - tags: [backup] - - - name: Create systemd timer for backups - ansible.builtin.template: - src: minecraft-backup.timer.j2 - dest: "{{ paths.systemd_dir }}/{{ minecraft.server_name }}-backup.timer" - owner: root - group: root - mode: "0644" - when: backup.enabled - tags: [backup] - - - name: Create systemd service for backups - ansible.builtin.template: - src: minecraft-backup.service.j2 - dest: "{{ paths.systemd_dir }}/{{ minecraft.server_name }}-backup.service" - owner: root - group: root - mode: "0644" - when: backup.enabled - tags: [backup] - - - name: Enable backup timer - ansible.builtin.systemd: - name: "{{ minecraft.server_name }}-backup.timer" - state: started - enabled: true - when: backup.enabled - tags: [backup] - - tags: [backup] - -# ----------------------------------------------------------------------------- -# Health Check -# ----------------------------------------------------------------------------- -- name: Health Check Configuration - block: - - name: Deploy health check script - ansible.builtin.template: - src: health-check.sh.j2 - dest: "{{ paths.base_dir }}/health-check.sh" - owner: "{{ minecraft_user }}" - group: "{{ minecraft_user }}" - mode: "0755" - when: monitoring.enabled - tags: [monitoring] - - - name: Create systemd timer for health checks - ansible.builtin.template: - src: minecraft-health.timer.j2 - dest: "{{ paths.systemd_dir }}/{{ minecraft.server_name }}-health.timer" - owner: root - group: root - mode: "0644" - when: monitoring.enabled - tags: [monitoring] - - - name: Create systemd service for health checks - ansible.builtin.template: - src: minecraft-health.service.j2 - dest: "{{ paths.systemd_dir }}/{{ minecraft.server_name }}-health.service" - owner: root - group: root - mode: "0644" - when: monitoring.enabled - tags: [monitoring] - - - name: Enable health check timer - ansible.builtin.systemd: - name: "{{ minecraft.server_name }}-health.timer" - state: started - enabled: true - when: monitoring.enabled - tags: [monitoring] - - tags: [monitoring] - -# ----------------------------------------------------------------------------- -# Final Verification -# ----------------------------------------------------------------------------- -- name: Final Verification - block: - - name: Wait for Minecraft server to start - ansible.builtin.uri: - url: "http://localhost:{{ minecraft.port }}" - return_content: false - status_code: [401, 200] # Minecraft responds to HTTP with 401 - register: server_check - retries: 30 - delay: 5 - until: server_check.status in [401, 200] - ignore_errors: true - tags: [verify] - - - name: Check service status - ansible.builtin.systemd: - name: "{{ minecraft.server_name }}.service" - register: service_status - tags: [verify] - - - name: Display verification results - ansible.builtin.debug: - msg: | - Server Status: {{ 'Running' if service_status.status.ActiveState == 'active' else 'Stopped' }} - Service: {{ service_status.status.SubState }} - Port {{ minecraft.port }}: {{ 'Open' if server_check is succeeded else 'Closed' }} - tags: [verify] - - tags: [verify] diff --git a/roles/minecraft-podman/templates/Containerfile.j2 b/roles/minecraft-podman/templates/Containerfile.j2 deleted file mode 100644 index 8625516..0000000 --- a/roles/minecraft-podman/templates/Containerfile.j2 +++ /dev/null @@ -1,28 +0,0 @@ -# Custom Minecraft Server Containerfile -# Deployed by Ansible - only used if minecraft.use_custom_container is true - -# Base image -FROM itzg/minecraft-server:java{{ minecraft.java_version | default('21') }} - -# Custom server type -ENV TYPE={{ minecraft.server_type | upper }} -ENV VERSION={{ minecraft.version }} - -# Custom plugins/mods directory (uncomment if using mods) -# VOLUME /data/mods -# VOLUME /data/plugins -# VOLUME /data/config - -# Custom entrypoint overrides -COPY server.properties /tmp/server.properties -RUN mkdir -p /data && cp /tmp/server.properties /data/server.properties - -# Health check -HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ - CMD curl -f http://localhost:{{ minecraft.port }} || exit 1 - -# Expose ports -EXPOSE {{ minecraft.port }}/tcp -{% if minecraft.rcon_enabled %} -EXPOSE {{ minecraft.rcon_port }}/tcp -{% endif %} diff --git a/roles/minecraft-podman/templates/backup.sh.j2 b/roles/minecraft-podman/templates/backup.sh.j2 deleted file mode 100644 index 6ce3949..0000000 --- a/roles/minecraft-podman/templates/backup.sh.j2 +++ /dev/null @@ -1,96 +0,0 @@ -#!/bin/bash -# -# Minecraft Server Backup Script -# Deployed by Ansible - {{ ansible_date_time.iso8601 if ansible_date_time is defined else 'managed' }} -# -# Creates rolling backups of the Minecraft world and data directories. -# Prunes old backups based on retention count. -# - -set -euo pipefail - -# Configuration -DATA_DIR="{{ paths.data_dir }}" -BACKUP_DIR="{{ paths.backup_dir }}" -RETENTION_COUNT="{{ backup.retention_count | default(10) }}" -COMPRESS="{{ backup.compress | default('true') }}" -SERVER_NAME="{{ minecraft.server_name }}" - -# Timestamp for this backup -TIMESTAMP="$(date +%Y%m%d_%H%M%S)" - -# Log function -log() { - echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" -} - -# Safety checks -if [ ! -d "$DATA_DIR" ]; then - log "ERROR: Data directory $DATA_DIR does not exist" - exit 1 -fi - -if [ ! -d "$BACKUP_DIR" ]; then - log "Creating backup directory: $BACKUP_DIR" - mkdir -p "$BACKUP_DIR" -fi - -# Create backup using tar -BACKUP_FILE="${BACKUP_DIR}/${SERVER_NAME}_${TIMESTAMP}" - -log "Starting backup of $DATA_DIR..." - -# Use atomic save if RCON is enabled -USE_RCON="{{ minecraft.rcon_enabled | default('false') }}" -if [ "$USE_RCON" = "true" ]; then - log "Using RCON for world save..." - # Send save-all command via rcon-cli or telnet - # This is a best-effort operation - fall back to tar if it fails - if command -v rcon-cli >/dev/null 2>&1; then - rcon-cli -a localhost -p {{ minecraft.rcon_port }} -P {{ minecraft.rcon_password }} save-all || true - sleep 5 - elif command -v mcrcon >/dev/null 2>&1; then - mcrcon -H localhost -P {{ minecraft.rcon_port }} -p {{ minecraft.rcon_password }} "save-all" || true - sleep 5 - else - log "RCON client not found, skipping save-all command (backup may be inconsistent)" - fi -fi - -# Deterministic backup using tar -if [ "$COMPRESS" = "true" ]; then - BACKUP_FILE="${BACKUP_FILE}.tar.gz" - log "Creating compressed backup: $BACKUP_FILE" - tar --warning=no-file-changed -czf "$BACKUP_FILE" \ - --exclude="$DATA_DIR/logs/*.gz" \ - -C "$(dirname $DATA_DIR)" "$(basename $DATA_DIR)" -else - BACKUP_FILE="${BACKUP_FILE}.tar" - log "Creating uncompressed backup: $BACKUP_FILE" - tar --warning=no-file-changed -cf "$BACKUP_FILE" \ - --exclude="$DATA_DIR/logs/*.gz" \ - -C "$(dirname $DATA_DIR)" "$(basename $DATA_DIR)" -fi - -log "Backup created successfully: $BACKUP_FILE" - -# Prune old backups, retaining the most recent N -log "Pruning old backups (keeping $RETENTION_COUNT)..." - -# Count backups (whether .tar or .tar.gz) -BACKUP_COUNT=$(ls "${BACKUP_DIR}/"${SERVER_NAME}_*.tar* 2>/dev/null | wc -l) -OVERFLOW=$((BACKUP_COUNT - RETENTION_COUNT)) - -if [ "$OVERFLOW" -gt 0 ]; then - # Remove oldest backups - ls -t "${BACKUP_DIR}/"${SERVER_NAME}_*.tar* 2>/dev/null | tail -n "$OVERFLOW" | while read -r old_backup; do - log "Removing old backup: $old_backup" - rm -f "$old_backup" - done -else - log "Backup count ($BACKUP_COUNT) is within retention limit ($RETENTION_COUNT)" -fi - -log "Backup completed at $(date '+%Y-%m-%d %H:%M:%S')" -log "Current backups:" -ls -lh "${BACKUP_DIR}/" 2>/dev/null || true diff --git a/roles/minecraft-podman/templates/health-check.sh.j2 b/roles/minecraft-podman/templates/health-check.sh.j2 deleted file mode 100644 index 9e2e082..0000000 --- a/roles/minecraft-podman/templates/health-check.sh.j2 +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/bash -# -# Minecraft Server Health Check Script -# Deployed by Ansible - managed file -# -# Checks that the Minecraft server is running and responding. -# - -set -euo pipefail - -SERVER_NAME="{{ minecraft.server_name }}" -PORT="{{ minecraft.port }}" -CONTAINER_NAME="{{ podman_container_name }}" - -# Colors -GREEN='\033[0;32m' -RED='\033[0;31m' -YELLOW='\033[1;33m' -NC='\033[0m' - -log() { - echo -e "$(date '+%Y-%m-%d %H:%M:%S') $*" -} - -# Check 1: Is the systemd service active? -SERVICE_STATUS=$(systemctl is-active "${SERVER_NAME}" 2>/dev/null || echo "inactive") -if [ "$SERVICE_STATUS" != "active" ]; then - log "${RED}[FAIL]${NC} Systemd service ${SERVER_NAME} is not active (status: ${SERVICE_STATUS})" - exit 1 -fi -log "${GREEN}[OK]${NC} Systemd service ${SERVER_NAME} is active" - -# Check 2: Is the container running? -if ! podman ps --format '{% raw %}{{.Names}} {{.Status}}{% endraw %}' | grep -q "${CONTAINER_NAME}"; then - log "${RED}[FAIL]${NC} Container ${CONTAINER_NAME} is not running" - exit 1 -fi -log "${GREEN}[OK]${NC} Container ${CONTAINER_NAME} is running" - -# Check 3: Is the Minecraft port responding? -# Minecraft responds to HTTP with 401 "It's a teapot" or similar -if curl -s -o /dev/null -m 5 http://localhost:${PORT} 2>/dev/null; then - log "${GREEN}[OK]${NC} Port ${PORT} is responding" -elif curl -s -o /dev/null -m 5 -w "%{http_code}" http://localhost:${PORT} 2>/dev/null | grep -q "401"; then - log "${GREEN}[OK]${NC} Port ${PORT} is responding (401 is expected for Minecraft)" -else - # Check if port is at least listening - if ss -tln | grep -q ":${PORT}"; then - log "${YELLOW}[WARN]${NC} Port ${PORT} is listening but not responding to HTTP (may be normal)" - else - log "${RED}[FAIL]${NC} Port ${PORT} is not listening" - exit 1 - fi -fi - -# Check 4: Check recent logs for errors -LOG_TAIL=$(journalctl -u "${SERVER_NAME}" --no-pager -n 50 2>/dev/null | grep -i "error\|fatal\|crash" | tail -n 5) -if [ -n "$LOG_TAIL" ]; then - log "${YELLOW}[WARN]${NC} Recent errors found in logs:" - echo "$LOG_TAIL" -else - log "${GREEN}[OK]${NC} No recent errors in logs" -fi - -log "${GREEN}Health check completed successfully${NC}" -exit 0 diff --git a/roles/minecraft-podman/templates/jvm.opts.j2 b/roles/minecraft-podman/templates/jvm.opts.j2 deleted file mode 100644 index 26b2950..0000000 --- a/roles/minecraft-podman/templates/jvm.opts.j2 +++ /dev/null @@ -1,4 +0,0 @@ -# JVM Options file for Minecraft server -# Deployed by Ansible - manage via java_args in group_vars/all.yml - -{{ minecraft.java_args | default('-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200') }} diff --git a/roles/minecraft-podman/templates/minecraft-backup.service.j2 b/roles/minecraft-podman/templates/minecraft-backup.service.j2 deleted file mode 100644 index 7bb7c86..0000000 --- a/roles/minecraft-podman/templates/minecraft-backup.service.j2 +++ /dev/null @@ -1,16 +0,0 @@ -# Systemd service for Minecraft backup -# Deployed by Ansible - -[Unit] -Description=Minecraft Server Backup -Requires={{ minecraft.server_name }}.service -After={{ minecraft.server_name }}.service - -[Service] -Type=oneshot -User={{ minecraft_user }} -Group={{ minecraft_user }} -ExecStart={{ paths.base_dir }}/backup.sh - -# Timeout for large worlds -TimeoutStartSec=3600 diff --git a/roles/minecraft-podman/templates/minecraft-backup.timer.j2 b/roles/minecraft-podman/templates/minecraft-backup.timer.j2 deleted file mode 100644 index beeef85..0000000 --- a/roles/minecraft-podman/templates/minecraft-backup.timer.j2 +++ /dev/null @@ -1,15 +0,0 @@ -# Systemd timer for Minecraft backup -# Deployed by Ansible - -[Unit] -Description=Minecraft Server Backup Timer - -[Timer] -# Backup schedule (default: every 6 hours) -OnCalendar={{ backup.schedule | default('*-*-* */6:00:00') }} - -# Run the backup immediately if the machine was powered off during the scheduled time -Persistent=true - -[Install] -WantedBy=timers.target diff --git a/roles/minecraft-podman/templates/minecraft-health.service.j2 b/roles/minecraft-podman/templates/minecraft-health.service.j2 deleted file mode 100644 index 5334dc7..0000000 --- a/roles/minecraft-podman/templates/minecraft-health.service.j2 +++ /dev/null @@ -1,11 +0,0 @@ -# Systemd service for Minecraft health checks -# Deployed by Ansible - -[Unit] -Description=Minecraft Server Health Check - -[Service] -Type=oneshot -User={{ minecraft_user }} -Group={{ minecraft_user }} -ExecStart={{ paths.base_dir }}/health-check.sh diff --git a/roles/minecraft-podman/templates/minecraft-health.timer.j2 b/roles/minecraft-podman/templates/minecraft-health.timer.j2 deleted file mode 100644 index 2f91ea4..0000000 --- a/roles/minecraft-podman/templates/minecraft-health.timer.j2 +++ /dev/null @@ -1,12 +0,0 @@ -# Systemd timer for Minecraft health checks -# Deployed by Ansible - -[Unit] -Description=Minecraft Server Health Check Timer - -[Timer] -OnBootSec=2min -OnUnitActiveSec={{ monitoring.interval | default(300) }}s - -[Install] -WantedBy=timers.target diff --git a/roles/minecraft-podman/templates/minecraft.env.j2 b/roles/minecraft-podman/templates/minecraft.env.j2 deleted file mode 100644 index 62f6b73..0000000 --- a/roles/minecraft-podman/templates/minecraft.env.j2 +++ /dev/null @@ -1,61 +0,0 @@ -# Minecraft Server Environment Variables -# Deployed by Ansible - Managed file, do not edit manually - -# Version and Server Type -TYPE={{ minecraft.server_type | upper }} -VERSION={{ minecraft.version }} - -# Memory -MEMORY={{ minecraft.java_memory }} -{% if minecraft.java_args is defined %} -JVM_OPTS="{{ minecraft.java_args }}" -{% endif %} - -# Network -PORT={{ minecraft.port }} -{% if minecraft.rcon_enabled %} -ENABLE_RCON=true -RCON_PORT={{ minecraft.rcon_port }} -RCON_PASSWORD={{ minecraft.rcon_password }} -{% else %} -ENABLE_RCON=false -{% endif %} - -# Server Settings -MOTD={{ minecraft.motd }} -MAX_PLAYERS={{ minecraft.max_players }} -GAMEMODE={{ minecraft.game_mode }} -DIFFICULTY={{ minecraft.difficulty }} -{% if minecraft.online_mode %} -ONLINE_MODE=true -{% else %} -ONLINE_MODE=false -{% endif %} -VIEW_DISTANCE={{ minecraft.view_distance | default(10) }} -SIMULATION_DISTANCE={{ minecraft.simulation_distance | default(6) }} - -{% if minecraft.whitelist_enabled %} -ENABLE_WHITELIST=true -{% else %} -ENABLE_WHITELIST=false -{% endif %} - -{% if minecraft.enable_command_block %} -ENABLE_COMMAND_BLOCK=true -{% else %} -ENABLE_COMMAND_BLOCK=false -{% endif %} - -{% if minecraft.max_world_size %} -MAX_WORLD_SIZE={{ minecraft.max_world_size }} -{% endif %} - -{% if minecraft.spawn_protection %} -SPAWN_PROTECTION={{ minecraft.spawn_protection }} -{% endif %} - -# Server name broadcast -SERVER_NAME={{ minecraft.server_name }} - -# Make the container non-interactive -EULA=TRUE diff --git a/roles/minecraft-podman/templates/minecraft.service.j2 b/roles/minecraft-podman/templates/minecraft.service.j2 deleted file mode 100644 index 036e650..0000000 --- a/roles/minecraft-podman/templates/minecraft.service.j2 +++ /dev/null @@ -1,42 +0,0 @@ -# Systemd unit for {{ minecraft.server_name }} Minecraft server running on Podman -# Deployed by Ansible - managed file -[Unit] -Description=Minecraft Server ({{ minecraft.server_name }}) - Podman Container -Documentation=https://hub.docker.com/r/itzg/minecraft-server -After=network-online.target -Wants=network-online.target - -[Service] -Type=simple -User={{ minecraft_user }} -Group={{ minecraft_user }} -WorkingDirectory={{ paths.data_dir }} - -# Pull the image if not present (idempotent) -ExecStartPre=/usr/bin/podman pull {{ podman.image }}:{{ podman.image_tag }} - -# Stop existing container before starting -ExecStartPre=-/usr/bin/podman rm -f {{ podman_container_name }} - -# Run the Minecraft server in a Podman container -ExecStart=/usr/bin/podman run --name {{ podman_container_name }} --replace --env-file {{ paths.base_dir }}/minecraft.env --volume {{ paths.data_dir }}:/data:Z {% if podman.extra_volumes is defined and podman.extra_volumes %}{% for vol in podman.extra_volumes %}--volume {{ vol }} {% endfor %}{% endif %}{% if podman.memory_limit is defined and podman.memory_limit %}--memory {{ podman.memory_limit }} {% endif %}{% if podman.cpu_shares is defined and podman.cpu_shares %}--cpu-shares {{ podman.cpu_shares }} {% endif %}{% if podman.network_mode == 'host' %}--network host {% else %}--publish {{ minecraft.port }}:{{ minecraft.port }}/tcp {% if minecraft.rcon_enabled %}--publish {{ minecraft.rcon_port }}:{{ minecraft.rcon_port }}/tcp {% endif %}{% endif %}{% for key, value in podman.labels.items() %}--label "{{ key }}={{ value }}" {% endfor %}--log-driver {{ podman.log_driver | default('journald') }} {{ podman.image }}:{{ podman.image_tag }} - -# Restart if it crashes (systemd handles restart policy) -Restart=on-failure -RestartSec=15 - -# Basic process limits -LimitNOFILE=65536 -LimitNPROC=4096 - -# Logging -StandardOutput=journal -StandardError=journal -SyslogIdentifier={{ minecraft.server_name }} - -# Allow container to manage its own namespaces/limits -NoNewPrivileges=false -ProtectSystem=false - -[Install] -WantedBy=multi-user.target diff --git a/roles/minecraft-podman/templates/restore.sh.j2 b/roles/minecraft-podman/templates/restore.sh.j2 deleted file mode 100644 index c302343..0000000 --- a/roles/minecraft-podman/templates/restore.sh.j2 +++ /dev/null @@ -1,106 +0,0 @@ -#!/bin/bash -# -# Minecraft Server Restore Script -# Deployed by Ansible - managed file -# -# Usage: ./restore.sh [path_to_backup_file] -# If no argument given, restores the most recent backup. -# -# WARNING: This will OVERWRITE the current world data! -# - -set -euo pipefail - -# Configuration -DATA_DIR="{{ paths.data_dir }}" -BACKUP_DIR="{{ paths.backup_dir }}" - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -log() { - echo -e "$(date '+%Y-%m-%d %H:%M:%S') $*" -} - -error() { - log "${RED}[ERROR]${NC} $*" - exit 1 -} - -warn() { - log "${YELLOW}[WARN]${NC} $*" -} - -ok() { - log "${GREEN}[OK]${NC} $*" -} - -# Determine which backup to restore -if [ $# -eq 1 ]; then - # Explicit file provided - RESTORE_FILE="$1" - if [ ! -f "$RESTORE_FILE" ]; then - # Try to find it in the backup dir - RESTORE_FILE="${BACKUP_DIR}/$1" - if [ ! -f "$RESTORE_FILE" ]; then - error "Backup file not found: $1 (looked in $BACKUP_DIR)" - fi - fi -else - # Find most recent backup - RESTORE_FILE=$(ls -t "${BACKUP_DIR}/"{{ minecraft.server_name }}_*.tar* 2>/dev/null | head -n1) - if [ -z "$RESTORE_FILE" ]; then - error "No backups found in $BACKUP_DIR" - fi -fi - -log "Selected backup: $RESTORE_FILE" - -# Double-check safety -warn "This will overwrite the current Minecraft world data in $DATA_DIR" -read -p "Are you sure you want to continue? (yes/no): " CONFIRM -if [ "$CONFIRM" != "yes" ]; then - log "Aborting restore." - exit 1 -fi - -# Stop the Minecraft server if running -if podman ps --format '{% raw %}{{.Names}}{% endraw %}' | grep -q '{{ podman_container_name }}'; then - warn "Stopping Minecraft server container..." - systemctl stop {{ minecraft.server_name }} - sleep 3 - warn "Server stopped." -fi - -# Create a temporary backup of current state (safety net) -TIMESTAMP="$(date +%Y%m%d_%H%M%S)" -SAFETY_BACKUP="${BACKUP_DIR}/pre_restore_${TIMESTAMP}.tar.gz" -log "Creating safety backup of current state: $SAFETY_BACKUP" -tar -czf "$SAFETY_BACKUP" -C "$(dirname $DATA_DIR)" "$(basename $DATA_DIR)" - -# Extract the restore file -log "Restoring from: $RESTORE_FILE" -case "$RESTORE_FILE" in - *.tar.gz|*.tgz) - tar -xzf "$RESTORE_FILE" -C "$(dirname $DATA_DIR)" - ;; - *.tar) - tar -xf "$RESTORE_FILE" -C "$(dirname $DATA_DIR)" - ;; - *) - error "Unsupported archive format: $RESTORE_FILE" - ;; -esac - -ok "Restore completed successfully!" - -# Restart the server -log "Restarting Minecraft server..." -systemctl start {{ minecraft.server_name }} -sleep 5 - -ok "Server restarted. Verify it's running: systemctl status {{ minecraft.server_name }}" -log "A safety backup of the pre-restore state was saved to: $SAFETY_BACKUP" diff --git a/roles/minecraft-podman/templates/server.properties.j2 b/roles/minecraft-podman/templates/server.properties.j2 deleted file mode 100644 index 7ac8b9e..0000000 --- a/roles/minecraft-podman/templates/server.properties.j2 +++ /dev/null @@ -1,59 +0,0 @@ -#Minecraft server properties -#Deployed by Ansible - Manage via group_vars/all.yml - -#Minecraft properties -enable-jmx-monitoring=false -rcon.port={{ minecraft.rcon_port | default(25575) }} -level-seed= -gamemode={{ minecraft.game_mode }} -enable-command-block={{ minecraft.enable_command_block | default('false') }} -enable-query=false -generator-settings={} -enforce-secure-profile={{ minecraft.enforce_secure_profile | default('true') }} -level-name=world -motd={{ minecraft.motd | default('A Minecraft Server') }} -query.port={{ minecraft.port | default(25565) }} -pvp=true -generate-structures=true -max-chained-neighbor-updates=1000000 -difficulty={{ minecraft.difficulty }} -network-compression-threshold=256 -max-tick-time=60000 -require-resource-pack=false -use-native-transport=true -max-players={{ minecraft.max_players | default(20) }} -online-mode={{ minecraft.online_mode | default('true') }} -enable-status=true -allow-flight=false -initial-disabled-packs= -broadcast-rcon-to-ops=true -view-distance={{ minecraft.view_distance | default(10) }} -server-ip= -resource-pack-prompt= -allow-nether=true -server-port={{ minecraft.port | default(25565) }} -enable-rcon={{ minecraft.rcon_enabled | default('false') }} -sync-chunk-writes=true -op-permission-level=4 -prevent-proxy-connections=false -hide-online-players=false -resource-pack= -entity-broadcast-range-percentage=100 -simulation-distance={{ minecraft.simulation_distance | default(6) }} -rcon.password={{ minecraft.rcon_password | default('') }} -player-idle-timeout=0 -force-gamemode=false -rate-limit=0 -hardcore=false -white-list={{ minecraft.whitelist_enabled | default('false') }} -broadcast-console-to-ops=true -spawn-npcs=true -spawn-animals=true -log-ips=true -function-permission-level=2 -level-type=minecraft\:normal -text-filtering-config= -spawn-monsters=true -enforce-whitelist=false -spawn-protection={{ minecraft.spawn_protection | default(16) }} -max-world-size={{ minecraft.max_world_size | default(29999984) }} diff --git a/site.yml b/site.yml deleted file mode 100644 index e717a02..0000000 --- a/site.yml +++ /dev/null @@ -1,62 +0,0 @@ ---- -# ============================================================================= -# Minecraft Podman Deployment - Main Playbook -# ============================================================================= -# Usage: -# ansible-playbook site.yml # Deploy to all minecraft servers -# ansible-playbook site.yml --limit external-apps # Deploy to specific host -# ansible-playbook site.yml --tags install # Only run install tasks -# ansible-playbook site.yml --tags config # Only run config tasks -# ansible-playbook site.yml --tags backup # Only run backup tasks -# ansible-playbook site.yml --tags update # Only run update tasks - -- name: Deploy Minecraft Server on Podman - hosts: minecraft - become: true - gather_facts: true - - pre_tasks: - - name: Display deployment info - ansible.builtin.debug: - msg: | - ======================================== - Minecraft Podman Deployment - ======================================== - Target: {{ inventory_hostname }} - Server: {{ minecraft.server_name }} - Type: {{ minecraft.server_type }} - Image: {{ podman.image }} - Port: {{ minecraft.port }} - Memory: {{ minecraft.java_memory }} - ======================================== - - - name: Verify target is Fedora - ansible.builtin.assert: - that: - - ansible_distribution == "Fedora" - fail_msg: "This playbook is designed for Fedora. Detected: {{ ansible_distribution }}" - success_msg: "Fedora {{ ansible_distribution_version }} confirmed" - - roles: - - role: minecraft-podman - tags: - - install - - config - - backup - - update - - always - - post_tasks: - - name: Display completion message - ansible.builtin.debug: - msg: | - ======================================== - Deployment Complete! - ======================================== - Server IP: {{ ansible_default_ipv4.address | default(ansible_host) }} - Port: {{ minecraft.port }} - RCON: {{ 'Enabled' if minecraft.rcon_enabled else 'Disabled' }} - Status: {{ minecraft.server_name }}.service - ======================================== - Connect: {{ ansible_default_ipv4.address | default(ansible_host) }}:{{ minecraft.port }} - ======================================== diff --git a/uninstall.yml b/uninstall.yml deleted file mode 100644 index e1fadc4..0000000 --- a/uninstall.yml +++ /dev/null @@ -1,112 +0,0 @@ ---- -# ============================================================================= -# Minecraft Podman Deployment - Uninstall Playbook -# ============================================================================= -# Usage: -# ansible-playbook uninstall.yml --limit external-apps -# -# WARNING: This will remove ALL Minecraft data, containers, and configuration -# from the target server. Run only if you're sure you want to clean up. -# ============================================================================= - -- name: Uninstall Minecraft Server from Podman - hosts: minecraft - become: true - gather_facts: true - - tasks: - - name: Confirm uninstall - ansible.builtin.pause: - prompt: "WARNING: This will remove all Minecraft data from {{ inventory_hostname }}. Type 'yes' to continue" - register: confirm - when: not ansible_check_mode - - - name: Abort if not confirmed - ansible.builtin.fail: - msg: "Uninstall aborted" - when: - - not ansible_check_mode - - confirm.user_input | lower != "yes" - - - name: Stop Minecraft service - ansible.builtin.systemd: - name: "minecraft.service" - state: stopped - enabled: false - ignore_errors: true - - - name: Stop backup timer - ansible.builtin.systemd: - name: "minecraft-backup.timer" - state: stopped - enabled: false - ignore_errors: true - - - name: Stop health timer - ansible.builtin.systemd: - name: "minecraft-health.timer" - state: stopped - enabled: false - ignore_errors: true - - - name: Remove systemd unit files - ansible.builtin.file: - path: "{{ item }}" - state: absent - loop: - - "/etc/systemd/system/minecraft.service" - - "/etc/systemd/system/minecraft-backup.timer" - - "/etc/systemd/system/minecraft-backup.service" - - "/etc/systemd/system/minecraft-health.timer" - - "/etc/systemd/system/minecraft-health.service" - ignore_errors: true - - - name: Reload systemd daemon - ansible.builtin.systemd: - daemon_reload: true - - - name: Stop and remove container - containers.podman.podman_container: - name: "minecraft" - state: absent - ignore_errors: true - register: container_remove - when: not ansible_check_mode - - - name: Remove container (fallback with command) - ansible.builtin.command: podman rm -f minecraft - ignore_errors: true - when: - - not ansible_check_mode - - container_remove is failed - - - name: Remove base directory - ansible.builtin.file: - path: "/opt/minecraft" - state: absent - ignore_errors: true - when: not ansible_check_mode - - - name: Remove Minecraft system user - ansible.builtin.user: - name: "minecraft" - state: absent - remove: true - ignore_errors: true - when: not ansible_check_mode - - - name: Close firewall ports - ansible.posix.firewalld: - port: "{{ item }}" - permanent: true - immediate: true - state: disabled - loop: - - "25565/tcp" - - "25575/tcp" - ignore_errors: true - tags: [firewall] - - - name: Uninstall complete message - ansible.builtin.debug: - msg: "Minecraft server removed from {{ inventory_hostname }}"