initial opencode commit

This commit is contained in:
2026-09-12 14:31:27 -06:00
parent a2deef0f5a
commit 09a5891364
30 changed files with 898 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
---
minecraft_data_dir: /srv/minecraft
minecraft_image: docker.io/itzg/minecraft-server:latest
minecraft_server_type: PAPER
minecraft_version: LATEST
minecraft_memory: 2G
minecraft_difficulty: normal
minecraft_motd: "Hardened Fedora 42 Minecraft Server"
minecraft_max_players: "20"
minecraft_view_distance: "10"
minecraft_online_mode: "TRUE"
minecraft_whitelist: ""
# Port the Java server listens on INSIDE the container (host port
# publish is controlled by minecraft_port / minecraft_udp).
minecraft_container_port: 25565
minecraft_prepull: true
# Geyser - Bedrock protocol bridge (geysermc/geyser). Runs in the same pod
# as the Java server and publishes the Bedrock UDP port so Bedrock clients
# can join the Java world.
enable_geyser: true
geyser_image: docker.io/geysermc/geyser:latest
# Bedrock UDP port published on the host AND listened on by Geyser inside
# the container (pod-level publish, must match the firewall rule).
geyser_port: 19132
# Inside the pod all containers share localhost, so Geyser talks to the Java
# server over 127.0.0.1:{{ minecraft_container_port }}.
geyser_remote_address: 127.0.0.1
# online matches the Java server's ONLINE_MODE. Set to "offline" only if you
# also run Floodgate and pair the servers with a shared key.
geyser_auth_type: online

View File

@@ -0,0 +1,101 @@
---
# Minecraft server deployment: a Quadlet pod running the Java server
# (itzg/minecraft-server) and, when enabled, the Geyser bridge container
# (geysermc/geyser) so Bedrock clients can join. Everything runs rootless
# under the admin user. Containers share the pod's network namespace, so
# Geyser reaches the Java server at 127.0.0.1.
- name: Build the list of data directories
ansible.builtin.set_fact:
minecraft_data_dirs: >-
{{ [minecraft_data_dir, minecraft_data_dir + '/data', minecraft_data_dir + '/backups']
+ ([minecraft_data_dir + '/geyser'] if enable_geyser | bool else []) }}
- name: Create the Minecraft data directory tree
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ admin_user }}"
group: "{{ admin_user }}"
mode: "0750"
loop: "{{ minecraft_data_dirs }}"
- name: Restore SELinux context on the data directory
ansible.builtin.command: restorecon -Rv {{ minecraft_data_dir }}
changed_when: false
- name: Create the Quadlet systemd unit directory
ansible.builtin.file:
path: "/home/{{ admin_user }}/.config/containers/systemd"
state: directory
owner: "{{ admin_user }}"
group: "{{ admin_user }}"
mode: "0700"
- name: Deploy the Minecraft pod unit
ansible.builtin.template:
src: minecraft.pod.j2
dest: "/home/{{ admin_user }}/.config/containers/systemd/minecraft.pod"
owner: "{{ admin_user }}"
group: "{{ admin_user }}"
mode: "0644"
- name: Deploy the Minecraft Java server unit
ansible.builtin.template:
src: minecraft-server.container.j2
dest: "/home/{{ admin_user }}/.config/containers/systemd/minecraft-server.container"
owner: "{{ admin_user }}"
group: "{{ admin_user }}"
mode: "0644"
- name: Deploy the Geyser config file
ansible.builtin.template:
src: geyser-config.yml.j2
dest: "{{ minecraft_data_dir }}/geyser/config.yml"
owner: "{{ admin_user }}"
group: "{{ admin_user }}"
mode: "0640"
when: enable_geyser | bool
- name: Deploy the Geyser bridge unit
ansible.builtin.template:
src: geyser.container.j2
dest: "/home/{{ admin_user }}/.config/containers/systemd/geyser.container"
owner: "{{ admin_user }}"
group: "{{ admin_user }}"
mode: "0644"
when: enable_geyser | bool
- name: Build the list of images to pull
ansible.builtin.set_fact:
minecraft_images: "{{ [minecraft_image] + ([geyser_image] if enable_geyser | bool else []) }}"
when: minecraft_prepull | bool
- name: Check if container images are already present
ansible.builtin.command: machinectl shell {{ admin_user }}@ -- podman image exists {{ item }}
loop: "{{ minecraft_images }}"
register: images_exist
changed_when: false
failed_when: false
when: minecraft_prepull | bool
- name: Pull missing container images
ansible.builtin.command: machinectl shell {{ admin_user }}@ -- podman pull {{ item.item }}
loop: "{{ images_exist.results }}"
when:
- minecraft_prepull | bool
- item.rc != 0
- name: Build the list of user services to enable
ansible.builtin.set_fact:
minecraft_units: "{{ ['minecraft-pod.service', 'minecraft-server.service'] + (['geyser.service'] if enable_geyser | bool else []) }}"
- name: Reload the user systemd daemon
ansible.builtin.command: machinectl shell {{ admin_user }}@ -- systemctl --user daemon-reload
changed_when: false
- name: Enable and start the Minecraft services
ansible.builtin.command: machinectl shell {{ admin_user }}@ -- systemctl --user enable --now {{ item }}
loop: "{{ minecraft_units }}"
register: mc_services
changed_when: false

View File

@@ -0,0 +1,17 @@
# Managed by Ansible - minecraft role (Geyser bridge).
# Minimal config: Geyser merges these keys over its built-in defaults.
# The Java server shares the pod's network namespace, so it is reachable
# at 127.0.0.1:{{ minecraft_container_port }}.
bedrock:
address: 0.0.0.0
port: {{ geyser_port }}
clone-remote-port: false
enable-proxy-protocol: false
remote:
address: {{ geyser_remote_address }}
port: {{ minecraft_container_port }}
auth-type: {{ geyser_auth_type }}
allow-passthrough-motd: true
allow-passthrough-player-counts: true

View File

@@ -0,0 +1,18 @@
[Unit]
Description=Geyser Bedrock bridge container ({{ geyser_image }})
Wants=network-online.target
After=network-online.target
[Container]
Label=app=geyser
ContainerName=geyser
Pod=minecraft.pod
Image={{ geyser_image }}
Volume={{ minecraft_data_dir }}/geyser:/geyser:Z
[Service]
Restart=always
RestartSec=10
[Install]
WantedBy=default.target

View File

@@ -0,0 +1,33 @@
[Unit]
Description=Minecraft Java server container ({{ minecraft_image }})
Wants=network-online.target
After=network-online.target
[Container]
Label=app=minecraft-server
ContainerName=minecraft-server
Pod=minecraft.pod
Image={{ minecraft_image }}
Environment=EULA=TRUE
Environment=TYPE={{ minecraft_server_type }}
Environment=VERSION={{ minecraft_version }}
Environment=MEMORY={{ minecraft_memory }}
Environment=DIFFICULTY={{ minecraft_difficulty }}
Environment=MOTD={{ minecraft_motd }}
Environment=MAX_PLAYERS={{ minecraft_max_players }}
Environment=VIEW_DISTANCE={{ minecraft_view_distance }}
Environment=ONLINE_MODE={{ minecraft_online_mode }}
Environment=OVERRIDE_SERVER_PROPERTIES=TRUE
{% if minecraft_whitelist | length > 0 %}
Environment=ENABLE_WHITELIST=TRUE
Environment=WHITELIST={{ minecraft_whitelist }}
{% endif %}
Volume={{ minecraft_data_dir }}/data:/data:Z
Volume={{ minecraft_data_dir }}/backups:/backups:Z
[Service]
Restart=always
RestartSec=10
[Install]
WantedBy=default.target

View File

@@ -0,0 +1,14 @@
[Unit]
Description=Minecraft pod (Java server + Geyser bridge)
[Pod]
PublishPort={{ minecraft_port }}:25565/tcp
{% if minecraft_udp | bool %}
PublishPort={{ minecraft_port }}:25565/udp
{% endif %}
{% if enable_geyser | bool %}
PublishPort={{ geyser_port }}:{{ geyser_port }}/udp
{% endif %}
[Install]
WantedBy=default.target