Files
Internal-apps/roles/7dtd/tasks/main.yml

119 lines
4.6 KiB
YAML

---
# 7 Days to Die dedicated server (vinanrra/7dtd-server container, LinuxGSM-based, SteamCMD-installed).
# PUBLIC server: players connect to 7dtd.boxswapper.io:26900 (TCP+UDP) and enter the join password
# (sdtd_server_password). Server config is rendered from roles/7dtd/templates/sdtdserver.xml.j2 on
# every deploy - vars.yml is the source of truth for the server config.
# External prerequisites (NOT managed by this repo):
# - Cloudflare A record 7dtd.boxswapper.io -> public IP (grey-cloud, like mc.boxswapper.io)
# - Router port forwards: TCP+UDP 26900, UDP 26901-26902 + TCP 8081 (telnet) -> 10.10.0.47
# - CHANGED sdtd_server_password / sdtd_telnet_password in vars.yml before first deploy
- name: Create 7 Days to Die data directory
ansible.builtin.file:
path: /opt/apps/7dtd/data
state: directory
mode: '0755'
# The container (linuxserver-style base) runs as uid/gid 1000 (PUID/PGID) and chowns its volumes on
# start; pre-seeding with that ownership lets the init script and server write alongside our xml.
# NOTE: NO /etc/timezone or /etc/localtime bind mounts here (unlike minecraft/zomboid) - the image's
# user.sh writes BOTH paths itself to apply the TimeZone env var, so ro binds crash-loop the container.
- name: Create 7 Days to Die saves dir (container user)
ansible.builtin.file:
path: /opt/apps/7dtd/data/7DaysToDie
state: directory
owner: '1000'
group: '1000'
mode: '0755'
- name: Create 7 Days to Die serverfiles directory (container user)
ansible.builtin.file:
path: /opt/apps/7dtd/serverfiles
state: directory
owner: '1000'
group: '1000'
mode: '0755'
# Mods live in the bind-mounted serverfiles; the container loads them on its next start
# (recreate on every deploy re-reads them). zips come from roles/7dtd/files/mods (sdtd_mods
# in vars.yml), extracted one level deep (the zips already carry their own _Singularity/
# and zByteblazarsNoRespawnNearBackpack/ subfolders, which fix load order by name).
- name: Create 7 Days to Die Mods directory (container user)
ansible.builtin.file:
path: /opt/apps/7dtd/serverfiles/Mods
state: directory
owner: '1000'
group: '1000'
mode: '0755'
- name: Deploy 7 Days to Die mods from vendored zips
ansible.builtin.unarchive:
src: "{{ item }}"
dest: /opt/apps/7dtd/serverfiles/Mods
owner: '1000'
group: '1000'
mode: '0755'
loop: "{{ sdtd_mods }}"
- name: Template 7 Days to Die serverconfig from vars.yml
ansible.builtin.template:
src: sdtdserver.xml.j2
dest: /opt/apps/7dtd/serverfiles/sdtdserver.xml
owner: '1000'
group: '1000'
mode: '0644'
# LinuxGSM reads config-lgsm/sdtdserver/sdtdserver.cfg on EVERY invocation (start/monitor/stop).
# Bind-mounting it makes the role the owner of that config (see vars.yml sdtd_lgsm_querymode);
# a previously unmanaged podman volume left defaults in place, causing the monitor crash-loop.
- name: Create 7 Days to Die LGSM config directory (container user)
ansible.builtin.file:
path: /opt/apps/7dtd/lgsm
state: directory
owner: '1000'
group: '1000'
mode: '0755'
- name: Template 7 Days to Die LGSM config from vars.yml
ansible.builtin.template:
src: sdtdserver.cfg.j2
dest: /opt/apps/7dtd/lgsm/sdtdserver.cfg
owner: '1000'
group: '1000'
mode: '0644'
- name: Deploy 7 Days to Die Server
containers.podman.podman_container:
image: "{{ sdtd_image }}"
name: 7dtd
env: "{{ sdtd_env_base }}"
restart_policy: always
recreate: true
state: started
volumes:
- /opt/apps/7dtd/data:/home/sdtdserver/.local/share/7DaysToDie:z
- /opt/apps/7dtd/serverfiles:/home/sdtdserver/serverfiles:z
- /opt/apps/7dtd/lgsm:/home/sdtdserver/lgsm/config-lgsm/sdtdserver:z
ports:
# Required: game port (TCP+UDP), Steam query/beacon ports (UDP)
- "26900:26900/tcp"
- "26900:26900/udp"
- "26901:26901/udp"
- "26902:26902/udp"
# Optional: telnet admin console (gated by sdtd_telnet_password)
- "8081:8081/tcp"
network:
- npm_internal
ip: '{{ sdtd_ip }}'
vars:
# sdtd_env_base: START_MODE=1 starts the server; PUID/PGID match the pre-seeded dir ownership;
# MONITOR=YES restarts the game process if it crashes (LinuxGSM cron).
# IMPORTANT: restart_policy: always is only valid with START_MODE=1 (never 0/2/4 per image docs).
sdtd_env_base:
START_MODE: "{{ sdtd_start_mode }}"
VERSION: "{{ sdtd_version }}"
PUID: "{{ sdtd_puid }}"
PGID: "{{ sdtd_pgid }}"
TimeZone: "{{ sdtd_timezone }}"
BACKUP: "{{ sdtd_backup }}"
MONITOR: "{{ sdtd_monitor }}"
TEST_ALERT: "NO"