feat(minecraft): add new minecraft server role (#19)
Johto Infrastructure Pipeline / Run Ansible Lint (push) Successful in 1m52s
Johto Infrastructure Pipeline / Deploy to Production (push) Successful in 3m9s

### Description
This PR adds new `minecraft_server` to configure and start a Minecraft server container on targeted hosts.

### Related Issue
Closes #18

### Testing Done
- [x] Verifed new role creates container files correctly
- [x] verified new container is able to start and run via systemd
- [x] verified server is accessible via Minecraft client

### Checklist
- [x] My code follows the project's style guidelines.
- [x] I have performed a self-review of my own code.
- [x] I have updated the documentation (if necessary).

---------

Co-authored-by: Jordan Del Pilar <[email protected]>
Reviewed-on: #19
This commit was merged in pull request #19.
This commit is contained in:
2026-07-15 12:41:15 -07:00
co-authored by Jordan Del Pilar
parent 1c87c9c78d
commit 857ec00b14
8 changed files with 160 additions and 0 deletions
+13
View File
@@ -12,6 +12,8 @@ ansible_become_password: !vault |
podman_config_base_dir: /appdata/podman
podman_quadlet_base_dir: "/home/{{ ansible_user }}/.config/containers/systemd"
timezone: America/Los_Angeles
dns_services:
- name: adguard
image: docker.io/adguard/adguardhome:latest
@@ -237,3 +239,14 @@ backup_paths:
- /storage/public-assets
keep_daily: 7
keep_weekly: 4
minecraft_servers:
- name: vanilla
image: docker.io/itzg/minecraft-server:latest
port: 25565
env:
MEMORY: 4G
USE_AIKAR_FLAGS: "true"
TYPE: PAPER
ENABLE_AUTOPAUSE: "true"
OPS: redjordan1
+3
View File
@@ -29,3 +29,6 @@ all:
gitea_servers:
hosts:
new-bark:
minecraft_servers:
hosts:
new-bark:
+59
View File
@@ -0,0 +1,59 @@
# Role: Minecraft Server
Sets up and deploys minecraft server container
## Tags
- minecraft
## Required Variables
Below is an annotated breakdown of the required variables and their structure for this role
These blocks should be defined in the `host_vars` file for any host that should be a minecraft server
> [!WARNING]
> Any variable marked `# !SENSITIVE` **should not** be stored in plain text under any circumstance
### Minecraft Info
Defines settings for the Minecraft server container settings
```yaml
# (required) List of all minecraft server containers to be deployed
# you can run as many minecraft servers as the hardware can handle. However, all will need a unique port
# at least one service is required
minecraft_servers:
# (required) name of the server container
# all containers and services will be prefixed with 'mc-'
# for example if you list 'vanilla' as the name the resulting container/service name will be 'mc-vanilla'
# format: snake_case
- name:
# (required) URL of container image
# can be from any container registry
# recommended image is: docker.io/itzg/minecraft-server:latest
# format: url
image: docker.io/itzg/minecraft-server:latest
# (optional) host port to bind to the container
# this must be unique for each server instance
# default: 25565
# format: int
port:
# (optional) list of environment variables to pass to the container
# these are primarily used to define settings for the minecraft server
# for more info please read the docs for your specific container image
# memory setting example listed to show proper format
# format: key value pair
env:
MEMORY: 4G
```
## Templates
### minecraft.container.j2
This template is used to generate .container files for Minecraft servers. This template is heavily opinionated to be a minecraft server instance and should not be used a generic template for quadlets.
## Execution
> [!NOTE]
> If this role makes changes to the quadlet file on the host the server will be restarted. If you are hosting this server for multiple users please keep that in mind
To run this command without running all roles in the playbook, use the following command
```bash
ansible-playbook site.yaml --tags "minecraft"
```
@@ -0,0 +1,4 @@
---
container_owner: jdelpilar
mc_port: 25565
timezone: America/Los_Angeles
@@ -0,0 +1,7 @@
- name: Restart changed Minecraft Services
ansible.builtin.systemd:
name: "mc-{{ item.item.name }}"
state: restarted
scope: user
daemon_reload: true
loop: "{{ minecraft_quadlet_results.results | selectattr('changed', 'equalto', true) | list }}"
+27
View File
@@ -0,0 +1,27 @@
---
- name: Create Minecraft Directories
ansible.builtin.file:
path: "{{ podman_config_base_dir }}/mc-{{ item.name }}/data"
state: directory
mode: "0755"
loop: "{{ minecraft_servers }}"
- name: Create Minecraft Quadlets
ansible.builtin.template:
src: minecraft.container.j2
dest: "{{ podman_quadlet_base_dir }}/services/mc-{{ item.name }}.container"
owner: "{{ ansible_user }}"
mode: "644"
loop: "{{ minecraft_servers }}"
register: minecraft_quadlet_results
notify: Restart changed Minecraft Services
- name: Flush Handlers
ansible.builtin.meta: flush_handlers
- name: Start Minecraft Servers
ansible.builtin.systemd:
name: "mc-{{ item.name }}"
state: started
scope: user
loop: "{{ minecraft_servers }}"
@@ -0,0 +1,40 @@
# {{ ansible_managed }}
[Unit]
After=network-online.target
StartLimitBurst=10
StartLimitIntervalSec=120
[Container]
ContainerName=mc-{{ item.name }}
Image={{ item.image }}
Network=management-net
PublishPort={{ item.port | default(mc_port) }}:25565
AutoUpdate=registry
Label=category=management
Label=owner={{ item.container_owner | default('jdelpilar') }}
Volume={{ podman_config_base_dir }}/mc-{{ item.name }}/data:/data
{% if item.volumes is defined %}
{% for volume in item.volumes %}
Volume={{ volume }}
{% endfor %}
{% endif %}
Environment=TZ={{ timezone | default('America/Los_Angeles') }}
Environment=EULA=true
{% if item.env is defined %}
{% for key, value in item.env.items() | sort %}
Environment={{ key }}={{ value }}
{% endfor %}
{% endif %}
[Service]
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.target
+7
View File
@@ -29,3 +29,10 @@
tags:
- common
- backup
- name: Minecraft Setup
hosts: minecraft_servers
roles:
- minecraft_server
tags:
- minecraft