From 8c21923358c34cb70669ac4e8824408e700d8539 Mon Sep 17 00:00:00 2001 From: Bastian de Byl Date: Sat, 13 Dec 2025 21:18:33 -0500 Subject: [PATCH] zomboid added, caddyfile updates, debylio migration, ddns migration --- ansible/roles/podman/defaults/main.yml | 9 ++ ansible/roles/podman/handlers/main.yml | 9 ++ .../podman/tasks/containers/base/awsddns.yml | 29 ++++- .../podman/tasks/containers/home/zomboid.yml | 106 ++++++++++++++++++ ansible/roles/podman/tasks/main.yml | 9 +- .../roles/podman/templates/caddy/Caddyfile.j2 | 55 ++++++--- .../podman/templates/zomboid/entrypoint.sh.j2 | 103 +++++++++++++++++ ansible/vars/vault.yml | Bin 13077 -> 13337 bytes 8 files changed, 302 insertions(+), 18 deletions(-) create mode 100644 ansible/roles/podman/tasks/containers/home/zomboid.yml create mode 100644 ansible/roles/podman/templates/zomboid/entrypoint.sh.j2 diff --git a/ansible/roles/podman/defaults/main.yml b/ansible/roles/podman/defaults/main.yml index d2f7d67..5ecd67e 100644 --- a/ansible/roles/podman/defaults/main.yml +++ b/ansible/roles/podman/defaults/main.yml @@ -15,6 +15,7 @@ partkeepr_path: "{{ podman_volumes }}/partkeepr" partsy_path: "{{ podman_volumes }}/partsy" photos_path: "{{ podman_volumes }}/photos" uptime_kuma_path: "{{ podman_volumes }}/uptime-kuma" +zomboid_path: "{{ podman_volumes }}/zomboid" pihole_path: "{{ podman_volumes }}/pihole" sshpass_cron_path: "{{ podman_volumes }}/sshpass_cron" caddy_path: "{{ podman_volumes }}/caddy" @@ -35,6 +36,14 @@ uptime_kuma_server_name: uptime.debyltech.com parts_server_name: parts.bdebyl.net photos_server_name: photos.bdebyl.net +# debyl.io domains (migration from bdebyl.net) +base_server_name_io: debyl.io +assistant_server_name_io: assistant.debyl.io +cloud_server_name_io: cloud.debyl.io +home_server_name_io: home.debyl.io +parts_server_name_io: parts.debyl.io +photos_server_name_io: photos.debyl.io + # Legacy nginx/ModSecurity configuration removed - Caddy provides built-in security # Web server configuration (Caddy is the default) diff --git a/ansible/roles/podman/handlers/main.yml b/ansible/roles/podman/handlers/main.yml index 88cd92c..fa095dd 100644 --- a/ansible/roles/podman/handlers/main.yml +++ b/ansible/roles/podman/handlers/main.yml @@ -33,3 +33,12 @@ tags: - caddy - caddy-config + +- name: reload zomboid systemd + become: true + become_user: "{{ podman_user }}" + ansible.builtin.systemd: + daemon_reload: true + scope: user + tags: + - zomboid diff --git a/ansible/roles/podman/tasks/containers/base/awsddns.yml b/ansible/roles/podman/tasks/containers/base/awsddns.yml index 792e6ef..74dc68a 100644 --- a/ansible/roles/podman/tasks/containers/base/awsddns.yml +++ b/ansible/roles/podman/tasks/containers/base/awsddns.yml @@ -78,4 +78,31 @@ - name: create systemd startup job for awsddns-fulfillr include_tasks: podman/systemd-generate.yml vars: - container_name: awsddns-fulfillr \ No newline at end of file + container_name: awsddns-fulfillr + +- import_tasks: podman/podman-check.yml + vars: + container_name: awsddns-debyl + container_image: "{{ image }}" + +- name: create home.debyl.io awsddns server container + become: true + become_user: "{{ podman_user }}" + diff: false + containers.podman.podman_container: + name: awsddns-debyl + image: "{{ image }}" + restart_policy: on-failure:3 + log_driver: journald + env: + AWS_ZONE_TTL: 60 + AWS_ZONE_ID: "Z07501202A6AYMHCVP50A" + AWS_ZONE_HOSTNAME: "home.debyl.io" + AWS_ACCESS_KEY_ID: "{{ aws_access_key_id }}" + AWS_SECRET_ACCESS_KEY: "{{ aws_secret_access_key }}" + AWS_DEFAULT_REGION: "{{ aws_default_region }}" + +- name: create systemd startup job for awsddns-debyl + include_tasks: podman/systemd-generate.yml + vars: + container_name: awsddns-debyl \ No newline at end of file diff --git a/ansible/roles/podman/tasks/containers/home/zomboid.yml b/ansible/roles/podman/tasks/containers/home/zomboid.yml new file mode 100644 index 0000000..ed60c32 --- /dev/null +++ b/ansible/roles/podman/tasks/containers/home/zomboid.yml @@ -0,0 +1,106 @@ +--- +- name: create zomboid host directory volumes + become: true + ansible.builtin.file: + path: "{{ item }}" + state: directory + owner: "{{ podman_subuid.stdout }}" + group: "{{ podman_user }}" + mode: 0755 + notify: restorecon podman + loop: + - "{{ zomboid_path }}/server" + - "{{ zomboid_path }}/data" + - "{{ zomboid_path }}/scripts" + +- name: copy zomboid entrypoint script + become: true + ansible.builtin.template: + src: zomboid/entrypoint.sh.j2 + dest: "{{ zomboid_path }}/scripts/entrypoint.sh" + owner: "{{ podman_subuid.stdout }}" + group: "{{ podman_user }}" + mode: 0755 + notify: restorecon podman + +- name: flush handlers + ansible.builtin.meta: flush_handlers + +- import_tasks: podman/podman-check.yml + vars: + container_name: zomboid + container_image: "{{ image }}" + +- name: create zomboid container + become: true + become_user: "{{ podman_user }}" + containers.podman.podman_container: + name: zomboid + image: "{{ image }}" + restart_policy: on-failure:3 + log_driver: journald + env: + SERVER_NAME: zomboid + MIN_RAM: 8g + MAX_RAM: 24g + AUTO_UPDATE: "true" + ADMIN_PASSWORD: "{{ zomboid_admin_password }}" + SERVER_PASSWORD: "{{ zomboid_password }}" + volumes: + - "{{ zomboid_path }}/server:/home/steam/pzserver" + - "{{ zomboid_path }}/data:/home/steam/Zomboid" + - "{{ zomboid_path }}/scripts/entrypoint.sh:/entrypoint.sh:ro" + ports: + - "16261:16261/udp" + - "16262:16262/udp" + command: /bin/bash /entrypoint.sh + +- name: create systemd startup job for zomboid + include_tasks: podman/systemd-generate.yml + vars: + container_name: zomboid + +# Ensure zomboid restarts on any exit (including admin-triggered restarts) +- name: configure zomboid systemd to always restart + become: true + become_user: "{{ podman_user }}" + ansible.builtin.lineinfile: + path: "{{ podman_home }}/.config/systemd/user/zomboid.service" + regexp: "^Restart=" + line: "Restart=always" + notify: reload zomboid systemd + +# Configuration management (requires server to have run once to generate ini) +- name: configure zomboid server settings + become: true + ansible.builtin.lineinfile: + path: "{{ zomboid_path }}/data/Server/zomboid.ini" + regexp: "^{{ item.key }}=" + line: "{{ item.key }}={{ item.value }}" + loop: + - { key: "PublicName", value: "Modded Joboid" } + - { key: "MaxPlayers", value: "8" } + - { key: "Password", value: "{{ zomboid_password }}" } + - { key: "Mods", value: "PzkVanillaPlusCarPack;PZKExtendedVehicleZones;PZKCarzoneWorkshop;Pogo;Pogo;Pogo;LethalHeadHit;VanillaFoodsExpanded;VanillaFoodsExpanded;RebalancedPropMoving;GaelGunStore_B42;STA_PryOpen;tsarslib;Ahu;Ahu;Ahu;ModernStatus;StandardizedVehicleUpgrades3V;StandardizedVehicleUpgrades3Core;survivingthroughseasons;survivingthroughseasons;RVInteriorExpansionPart2;RVInteriorExpansion;TchernoLib;HereGoesTheSun;hf_point_blank;WayMoreCars;WaterGoesBad;WaterGoesBad;PROJECTRVInterior42;ClimbWall;amclub;RepairableWindows;RepairableWindows;StarlitLibrary;StarlitLibrary;StarlitLibrary;ImmersiveBlackouts;ModLoadOrderSorter_b42;NeatUI_Framework;SomewhatWater;SomewhatWaterBright;VanillaVehiclesAnimated;VanillaVehiclesAnimated_SVU;VVA_nascarlights;VVA_cullseats;VVA_slowdoors;kitsunelib;ChuckleberryFinnAlertSystem;ImmersiveVehiclePaint;darkerMap;SLDarkerSnowB42;BecomeBraveB42;Louisville spawn v42;ItemretexturePSC" } + - { key: "WorkshopItems", value: "3217685049;3058134369;3543588687;3577903007;2699828474;3616176188;3579640010;3402491515;3422418897;3451167732;3304582091;3403490889;2753086629;3622163276;3618427553;3389605231;3618557184;2990322197;3520758551;2849467715;3543229299;3389681224;3404737883;3378304610;3378285185;3607686447;3423660713;3508537032;3582960654;3281755175;3390453390;3077900375;3464606086;2939187818;3390411200;3388028737;3387071727;3618491765" } + tags: zomboid-conf + +# Sandbox settings (requires world reset to take effect) +- name: configure zomboid sandbox settings + become: true + ansible.builtin.lineinfile: + path: "{{ zomboid_path }}/data/Server/zomboid_SandboxVars.lua" + regexp: "^\\s*{{ item.key }} = " + line: " {{ item.key }} = {{ item.value }}," + backrefs: false + loop: + - { key: "StartMonth", value: "12" } + - { key: "StartDay", value: "15" } + tags: zomboid-conf + +# World reset tasks REMOVED - too dangerous to have in automation +# To reset the world manually: +# 1. Stop the server: systemctl --user stop zomboid.service +# 2. Delete saves: rm -rf /home/podman/.local/share/volumes/zomboid/data/Saves +# 3. Delete db: rm -rf /home/podman/.local/share/volumes/zomboid/data/db +# 4. Start the server: systemctl --user start zomboid.service diff --git a/ansible/roles/podman/tasks/main.yml b/ansible/roles/podman/tasks/main.yml index f494b96..c50cefc 100644 --- a/ansible/roles/podman/tasks/main.yml +++ b/ansible/roles/podman/tasks/main.yml @@ -88,5 +88,10 @@ - import_tasks: containers/home/gregtime.yml vars: - image: localhost/greg-time-bot:1.3.1 - tags: gregtime \ No newline at end of file + image: localhost/greg-time-bot:1.3.2 + tags: gregtime + +- import_tasks: containers/home/zomboid.yml + vars: + image: docker.io/cm2network/steamcmd:root + tags: zomboid \ No newline at end of file diff --git a/ansible/roles/podman/templates/caddy/Caddyfile.j2 b/ansible/roles/podman/templates/caddy/Caddyfile.j2 index 7bd4855..b216960 100644 --- a/ansible/roles/podman/templates/caddy/Caddyfile.j2 +++ b/ansible/roles/podman/templates/caddy/Caddyfile.j2 @@ -53,20 +53,25 @@ # SITE CONFIGURATIONS # ============================================================================ -# Simple redirect: {{ base_server_name }} -> debyl.io +# Simple redirect: {{ base_server_name }} -> {{ base_server_name_io }} {{ base_server_name }} { - redir https://debyl.io permanent + redir https://{{ base_server_name_io }}{uri} 302 } # ============================================================================ # SIMPLE REVERSE PROXIES # ============================================================================ -# Photos service - {{ photos_server_name }} +# Photos service - redirect old to new {{ photos_server_name }} { + redir https://{{ photos_server_name_io }}{uri} 302 +} + +# Photos service - {{ photos_server_name_io }} +{{ photos_server_name_io }} { import common_headers reverse_proxy localhost:8088 - + log { output file /var/log/caddy/photos.log format json @@ -89,23 +94,28 @@ # IP-RESTRICTED SITES # ============================================================================ -# Home Assistant - {{ assistant_server_name }} +# Home Assistant - redirect old to new {{ assistant_server_name }} { + redir https://{{ assistant_server_name_io }}{uri} 302 +} + +# Home Assistant - {{ assistant_server_name_io }} +{{ assistant_server_name_io }} { {{ ip_restricted_site() }} - + handle @local { reverse_proxy localhost:8123 { # WebSocket support is automatic flush_interval -1 } - + header { Strict-Transport-Security "max-age=31536000; includeSubDomains" X-Content-Type-Options "nosniff" Referrer-Policy "same-origin" } } - + log { output file /var/log/caddy/assistant.log format json @@ -115,8 +125,13 @@ # CI/Drone - REMOVED # ci.bdebyl.net configuration removed - Drone CI infrastructure decommissioned -# Home server - {{ home_server_name }} +# Home server - redirect old to new {{ home_server_name }} { + redir https://{{ home_server_name_io }}{uri} 302 +} + +# Home server - {{ home_server_name_io }} +{{ home_server_name_io }} { {{ ip_restricted_site() }} handle @local { @@ -124,8 +139,13 @@ } } -# Parts/Partsy - {{ parts_server_name }} +# Parts/Partsy - redirect old to new {{ parts_server_name }} { + redir https://{{ parts_server_name_io }}{uri} 302 +} + +# Parts/Partsy - {{ parts_server_name_io }} +{{ parts_server_name_io }} { {{ ip_restricted_site() }} handle @local { @@ -161,29 +181,34 @@ # COMPLEX CONFIGURATIONS # ============================================================================ -# Nextcloud - {{ cloud_server_name }} +# Nextcloud - redirect old to new {{ cloud_server_name }} { + redir https://{{ cloud_server_name_io }}{uri} 302 +} + +# Nextcloud - {{ cloud_server_name_io }} +{{ cloud_server_name_io }} { request_body { max_size {{ caddy_max_request_body_mb }}MB } - + reverse_proxy localhost:8089 { header_up Host {host} header_up X-Real-IP {remote} # X-Forwarded-For and X-Forwarded-Proto are automatic } - + header { Strict-Transport-Security "max-age=31536000; includeSubDomains" X-Content-Type-Options "nosniff" Referrer-Policy "same-origin" -X-Powered-By } - + # Nextcloud specific redirects redir /.well-known/carddav /remote.php/dav 301 redir /.well-known/caldav /remote.php/dav 301 - + log { output file /var/log/caddy/cloud.log format json diff --git a/ansible/roles/podman/templates/zomboid/entrypoint.sh.j2 b/ansible/roles/podman/templates/zomboid/entrypoint.sh.j2 new file mode 100644 index 0000000..6330790 --- /dev/null +++ b/ansible/roles/podman/templates/zomboid/entrypoint.sh.j2 @@ -0,0 +1,103 @@ +#!/bin/bash +set -e + +STEAMCMD="/home/steam/steamcmd/steamcmd.sh" +INSTALL_DIR="/home/steam/pzserver" +DATA_DIR="/home/steam/Zomboid" +SERVER_NAME="${SERVER_NAME:-zomboid}" +MIN_RAM="${MIN_RAM:-8g}" +MAX_RAM="${MAX_RAM:-24g}" + +echo "=== Project Zomboid Build 42 Server ===" +echo "Server Name: ${SERVER_NAME}" +echo "RAM: ${MIN_RAM} - ${MAX_RAM}" + +# Fix ownership of mounted volumes (container runs as steam user, UID 1000) +echo "=== Fixing volume permissions ===" +chown -R steam:steam "${INSTALL_DIR}" || true +chown -R steam:steam "${DATA_DIR}" || true +chmod -R 755 "${INSTALL_DIR}" || true +chmod -R 755 "${DATA_DIR}" || true + +# Create required subdirectories with correct ownership +mkdir -p "${DATA_DIR}/Server" +mkdir -p "${DATA_DIR}/Saves/Multiplayer" +mkdir -p "${DATA_DIR}/db" +chown -R steam:steam "${DATA_DIR}" + +# Ensure steam user has proper home directory setup +export HOME=/home/steam + +# Initialize SteamCMD if needed (creates config directories) +if [ ! -d "/home/steam/Steam" ]; then + echo "=== Initializing SteamCMD ===" + su -c "${STEAMCMD} +quit" steam || true +fi + +# Update/Install PZ dedicated server with Build 42 unstable branch +if [ "${AUTO_UPDATE:-true}" = "true" ]; then + echo "=== Updating Project Zomboid Server (Build 42 unstable) ===" + # Run steamcmd as steam user with proper quoting for beta flag + su -c "${STEAMCMD} +force_install_dir ${INSTALL_DIR} +login anonymous +app_update 380870 -beta unstable validate +quit" steam + echo "=== Update complete ===" +fi + +# Ensure data directories exist (created earlier with correct permissions) + +# Configure server settings on first run +SERVER_INI="${DATA_DIR}/Server/${SERVER_NAME}.ini" +if [ ! -f "${SERVER_INI}" ]; then + echo "=== First run detected, server will generate default config ===" +fi + +# Handle admin password for first run +# PZ requires interactive password input on first run, so we create a db file +ADMIN_DB="${DATA_DIR}/db/${SERVER_NAME}.db" +if [ ! -f "${ADMIN_DB}" ] && [ -n "${ADMIN_PASSWORD}" ]; then + echo "=== Setting up admin account ===" + mkdir -p "${DATA_DIR}/db" + # The server will prompt for password on first run + # We'll use expect-like behavior or let it use defaults +fi + +# Modify memory settings in ProjectZomboid64.json (Build 42 uses JSON config) +PZ_JSON="${INSTALL_DIR}/ProjectZomboid64.json" +if [ -f "${PZ_JSON}" ]; then + echo "=== Setting JVM memory: Xms=${MIN_RAM}, Xmx=${MAX_RAM} ===" + # Add -Xms if not present, otherwise update it + if grep -q "\-Xms" "${PZ_JSON}"; then + sed -i "s/-Xms[0-9]*[gGmM]*/-Xms${MIN_RAM}/g" "${PZ_JSON}" + else + # Insert -Xms before -Xmx + sed -i "s/\"-Xmx/\"-Xms${MIN_RAM}\",\n\t\t\"-Xmx/g" "${PZ_JSON}" + fi + sed -i "s/-Xmx[0-9]*[gGmM]*/-Xmx${MAX_RAM}/g" "${PZ_JSON}" +fi + +# If server password is set, we'll need to configure it in the ini after first run +# For now, store it for later configuration +if [ -n "${SERVER_PASSWORD}" ]; then + echo "${SERVER_PASSWORD}" > "${DATA_DIR}/.server_password" +fi + +if [ -n "${ADMIN_PASSWORD}" ]; then + echo "${ADMIN_PASSWORD}" > "${DATA_DIR}/.admin_password" +fi + +# Change to install directory and start server +cd "${INSTALL_DIR}" + +echo "=== Starting Project Zomboid Server ===" +echo "Connect to: home.bdebyl.net:16261" + +# Start server - on first run this will prompt for admin password +# We handle this by providing input via stdin if password file exists +if [ -f "${DATA_DIR}/.admin_password" ] && [ ! -f "${ADMIN_DB}" ]; then + # First run with admin password + ADMIN_PASS=$(cat "${DATA_DIR}/.admin_password") + echo "=== First run: setting admin password ===" + printf "%s\n%s\n" "${ADMIN_PASS}" "${ADMIN_PASS}" | su -c "bash start-server.sh -servername ${SERVER_NAME}" steam +else + # Normal run + exec su -c "bash start-server.sh -servername ${SERVER_NAME}" steam +fi diff --git a/ansible/vars/vault.yml b/ansible/vars/vault.yml index b018e5316a7cd5d3f9071f12e0e376a66dd06bcf..be73d20341cc566e4e0c928cab5ebb1f2b4c33bb 100644 GIT binary patch literal 13337 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 literal 13077 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