-
Notifications
You must be signed in to change notification settings - Fork 0
Architektur
← Home
ProjectZomboiD ist ein Config-as-Code-Setup: Der gewünschte Zustand des Servers liegt als deklarative Dateien im Repo, Generatoren und Skripte setzen ihn idempotent um. Diese Seite erklärt Prinzipien, Komponenten, Datenflüsse und Verzeichnisse.
-
Config-as-Code:
.env+ Templates erzeugen die Server-Configs — Server-INIs werden nie von Hand editiert (Repo-Prinzip, README/docs/01-architektur.md). -
Single Source of Truth: Mods leben ausschließlich in
mods.yaml, Spawn-Punkte inspawns.yaml, Settings in.env. Generierte Dateien sind Abfallprodukte. - Idempotenz: Jedes Skript ist mehrfach ausführbar, ohne Schaden anzurichten (Repo-Prinzip, docs/01; install.sh nennt es explizit).
- Fail-safe Updates: Kein Update ohne Pre-Backup + Healthcheck + Auto-Rollback (Repo-Prinzip, README/docs/01).
- Alles per Git nachvollziehbar: Jede Mod-/Config-Änderung ist ein Commit — revertbar und historisiert (Repo-Regel, README).
-
Ein CLI:
makeist die einzige Oberfläche, die man sich merken muss (Repo-Prinzip, docs/01).
Wer ruft wen — von oben nach unten:
| Ebene | Komponente | Zweck | Gerufen von |
|---|---|---|---|
| CLI | Makefile |
Einheitliches CLI, 16 Targets (make help zeigt alle) |
Admin |
| CLI | make install/update/backup/... |
Delegieren an die Skripte | Admin, Timer |
| Skripte | scripts/lib/common.sh |
Logging, .env-Loader, Discord-Notify, Guards |
alle Bash-Skripte |
| Skripte | scripts/install.sh |
SteamCMD + App 380870 + Verzeichnisse + Render + Mods (idempotent) | make install |
| Skripte | scripts/render-config.sh |
envsubst-Rendern der Templates nach $PZ_DATA_DIR/Server
|
make render, install.sh |
| Skripte |
scripts/mods-generate.sh / mods-validate.sh
|
mods.yaml → WorkshopItems/Mods/Map; Validierung | make mods |
| Skripte | scripts/spawns-generate.sh |
spawns.yaml → Lua | make spawns |
| Skripte | scripts/update.sh |
Announce → Stop → Backup → Update → Render → Start → Healthcheck → Auto-Rollback |
make update, Update-Timer |
| Skripte |
scripts/backup.sh / restore.sh
|
tar.gz-Rotation (7 täglich / 4 wöchentlich, Repo-Default) bzw. interaktiver Restore |
make backup/make restore, Backup-Timer |
| Skripte | scripts/monitor.sh |
Cron-Watchdog mit .planned-stop-Flag (respektiert geplante Stops) |
Cron, minütlich |
| Skripte | scripts/healthcheck.sh |
Prozess + UDP-Port + Journal-Fehler-Scan |
make status/make healthcheck, update.sh |
| Skripte | scripts/announce.sh |
RCON-Countdowns an Spieler vor Stop/Update (via mcrcon) |
update.sh |
| Skripte | scripts/notify.sh |
Manueller Discord-Ping für den Admin (notify.sh "Titel" "Nachricht" [farbe]); automatisierte Skripte rufen stattdessen notify() aus common.sh direkt auf |
Admin (manueller Aufruf) |
| Init | systemd/zomboid.service |
Startet start-server.sh -servername ${SERVER_NAME} -Xmx${RAM_XMX}; Restart=always, LimitNOFILE=65535 (Repo-Default, Unit-Datei) |
systemd |
| Init | systemd/zomboid-*.timer |
Backup täglich 04:00 (Persistent), Update im templated Fenster |
systemd |
| Runtime | Spielserver-Prozess | Project Zomboid Dedicated Server (App 380870) | systemd/Docker |
| Container | docker/docker-compose.yml |
Optionaler Pfad: Service zomboid, Ports 16261/udp + 16262/udp + 27015/tcp, Healthcheck pgrep -f ProjectZomboid
|
Docker — Details Docker-Betrieb |
| CI | .github/workflows/ci.yml |
shellcheck + mods-validate + YAML-Check + Secret-Scan bei jedem Push | Git-Push |
| Notfall | gcp/ |
Gestoppte Failover-Instanz + Backup-Sync | Admin — Details GCP-Failover |
Zahlenwerte der Tabelle sind Repo-Stand bzw. Repo-Default: 16 Targets (1:1 aus Makefile), App 380870 (Steam-App-ID des PZ Dedicated Servers, so vom Repo verwendet), Ports 16261/udp + 16262/udp + 27015/tcp (docker-compose.yml), Backup-Timer 04:00 Uhr (zomboid-backup.timer) — jeweils aus den genannten Repo-Dateien übernommen.
mods.yaml
└─(make mods → mods-generate.sh, Sortierung nach Load-Order-Kategorien)
config/generated/workshop-items.txt (WorkshopItems= / Mods= / Map=)
└─(manuelle Übernahme der drei Zeilen in die Server-INI — kein Skript macht das)
${PZ_DATA_DIR}/Server/servertest.ini (Mod-Zeilen von Hand einpflegen)
└─(Server-Restart)
Repo-Stand: Die Übernahme der WorkshopItems=/Mods=/Map=-Zeilen in die Server-INI ist ein manueller Schritt. render-config.sh rendert nur config/templates/*.tmpl per envsubst — dort sind die Mod-Zeilen auskommentiert (# WorkshopItems=... usw., servertest.ini.tmpl) — und mods-generate.sh weist im Log lediglich darauf hin, die Zeilen in die Server-INI zu übernehmen (wörtlich: „in ${SERVER_NAME}.ini uebernehmen"; mit dem Repo-Default SERVER_NAME=servertest meint das die servertest.ini). Eine bekannte Eigenheit des Repo-Stands, kein Automatismus.
Das Prinzip „Server-INIs nie von Hand editieren" gilt daher für die per envsubst erzeugten Werte — ausgenommen sind die Mod-Zeilen, die bewusst manuell aus workshop-items.txt gepflegt werden müssen.
Der Generator sortiert aktive Mods nach den Kategorien library → framework → map → gameplay → qol (= Load-Order), setzt den B42-Pflicht-Backslash vor jede Mod-ID und hängt Muldraugh, KY in der Map=-Zeile immer zuletzt (Repo-Verhalten, mods-generate.sh).
.env
└─(render-config.sh / envsubst)
config/templates/servertest.ini.tmpl
→ ${PZ_DATA_DIR}/Server/servertest.ini (Hauptconfig — Dateiname = Template-Basisname)
→ ${PZ_DATA_DIR}/Server/${SERVER_NAME}_SandboxVars.lua (Sandbox-Preset coop-balanced)
→ ${PZ_DATA_DIR}/Server/${SERVER_NAME}_*.lua (Spawn-Dateien, per sed umbenannt)
envsubst ersetzt dabei genau die 12 aufgezählten Variablen aus der VARS-Liste in render-config.sh (inkl. SERVER_NAME innerhalb der INI-Werte). SERVER_NAME bestimmt aber nicht den INI-Dateinamen: Die Hauptconfig heißt immer servertest.ini (Template-Basisname, Repo-Verhalten render-config.sh); SERVER_NAME benennt nur die Sandbox-Preset-Datei (${SERVER_NAME}_SandboxVars.lua) und steuert die Umbenennung der Spawn-Lua-Dateien (sed s/^servertest/${SERVER_NAME}/).
Bekannte Eigenheit: Der Serverprozess wird mit -servername ${SERVER_NAME} gestartet und erwartet daher ${PZ_DATA_DIR}/Server/${SERVER_NAME}.ini. Mit dem Repo-Default SERVER_NAME=servertest fällt das mit der gerenderten servertest.ini zusammen; weicht SERVER_NAME davon ab, muss die gerenderte Datei manuell auf den passenden Namen gebracht werden — dafür gibt es im Repo-Stand keine Automatik.
spawns.yaml
└─(make spawns → spawns-generate.sh)
config/generated/spawns/*.lua
└─(render-config.sh kopiert; generierte Version hat Vorrang vor config/spawns/)
${PZ_DATA_DIR}/Server/${SERVER_NAME}_spawnregions.lua usw.
Verifiziert am Clone (Stand: Commit 11, main):
ProjectZomboiD/
├── Makefile Ein CLI: alle Targets (make help)
├── .env.example Vorlage für .env: Server-Basis, Pfade, RAM, Ports, Backups, GCP
├── mods.yaml Modliste — Single Source of Truth
├── spawns.yaml Spawn-Regionen + eigene Coop-Spawns
├── CHANGELOG.md Versionshistorie des Setups
├── .github/workflows/ci.yml CI: shellcheck + mods-validate + YAML-Check + Secret-Scan
├── backups/ Lokale Backup-Ablage im Repo-Baum (.gitkeep-Platzhalter)
├── logs/ Log-Ablage (.gitkeep-Platzhalter)
├── config/
│ ├── templates/ servertest.ini.tmpl — envsubst-Vorlage der Server-INI
│ ├── presets/sandbox/ coop-balanced.lua — Coop-Sandbox-Preset
│ ├── spawns/ Spawn-Vorlagen (spawnregions, ravencreek)
│ └── generated/ Generator-Ausgabe (workshop-items.txt, spawns/) — entsteht erst beim Generieren
├── scripts/ 12 Bash-Skripte (announce, backup, healthcheck, install, monitor, notify, render-config, restore, mods-generate, mods-validate, spawns-generate, update) …
│ ├── lib/common.sh … gemeinsame Bibliothek (env, log, notify, Guards)
│ └── windows/ 4 PowerShell-Gegenstücke (install, backup, update, monitor)
├── systemd/ zomboid.service + backup/update service+timer + README
├── docker/ docker-compose.yml + .env.docker.example (optionaler Betrieb)
├── gcp/ Failover: create-instance.sh, startup-script.sh, sync-backups.sh, README
├── docs/ 10 deutsche Vertiefungs-Guides (01-architektur … 10-runbook-raven-creek)
└── servermods/README.md Anleitung: eigene Mods im Workshop-Format entwickeln
So hängen die Komponenten zur Laufzeit zusammen:
Server-Start (nach sudo systemctl start zomboid):
systemd (zomboid.service, Restart=always)
→ start-server.sh -servername ${SERVER_NAME} -Xmx${RAM_XMX}
→ Project-Zomboid-Serverprozess (liest ${PZ_DATA_DIR}/Server/${SERVER_NAME}.ini laut -servername; mit dem Repo-Default SERVER_NAME=servertest ist das die gerenderte servertest.ini — siehe Datenfluss (b))
Update-Zyklus (make update bzw. zomboid-update.timer → scripts/update.sh):
announce.sh (RCON-Countdown)
→ Stop → backup.sh (Pre-Backup)
→ SteamCMD +app_update 380870
→ render-config.sh (Configs neu rendern)
→ Start → healthcheck.sh
→ bei FAIL: Auto-Rollback auf den Stand vor dem Update
.env wird niemals committet (Repo-Regel: Secrets); die CI prüft bei jedem Push mit shellcheck die Skripte, validiert mods.yaml, prüft YAML und scannt auf Secrets (Repo-Inventar, .github/workflows/ci.yml). Jede Mod- oder Config-Änderung ist ein Commit und damit revertbar — die Wiki-Seiten Modding-Workflow und Updates-und-Rollback beschreiben die zugehörigen Abläufe.
Was auf dem Linux-Host wo liegt (Defaults 1:1 aus .env.example und install.sh; alle Werte Repo-Default):
| Variable | Default-Pfad | Inhalt |
|---|---|---|
PZ_HOME |
/opt/pzserver |
Wurzel der Server-Installation; Heimat des dedizierten Users pzserver
|
PZ_SERVER_DIR |
/opt/pzserver/server |
Spiel-Binaries (per SteamCMD, App 380870) inkl. start-server.sh
|
PZ_DATA_DIR |
/opt/pzserver/Zomboid |
Zomboid-Datenverzeichnis: Saves, gerenderte Server-INIs, SandboxVars, Spawn-Lua (Server/-Unterordner) |
STEAMCMD_DIR |
/opt/pzserver/steamcmd |
SteamCMD-Installation; Workshop-Downloads liegen darunter unter steamapps/workshop/content/108600/
|
BACKUP_DIR |
/opt/pzserver/backups |
tar.gz-Archive; Rotation 7 täglich / 4 wöchentlich (Repo-Default, RETENTION_DAILY/WEEKLY) |
Als Notfallreserve läuft in GCP eine normalerweise gestoppte e2-standard-4-Instanz (Debian 12, 50 GB Disk — beides Repo-Default, gcp/create-instance.sh) neben einem Backup-Bucket in europe-west3; laufend kostet das rund $0.13/h (Community-Quelle: GCP-Preisliste — Näherung). Fällt der Haupt-Host aus, startet man die Instanz; ihr Startup-Skript installiert Docker und Git, klont das Repo und holt die täglichen daily-*.tar.gz aus dem Bucket nach /data/Zomboid, dann startet der Container mit SLOTS=3 und XMX=8G (Repo-Verhalten, gcp/startup-script.sh). Die Backups werden per gsutil rsync täglich per Cron auf dem Haupt-Host in den Bucket gespiegelt — gcp/README.md empfiehlt dafür z. B. 04:30, nach dem nächtlichen Backup. Vollständige Anleitung: GCP-Failover.
- Makefile-Referenz — das CLI im Detail
- Skripte-Referenz — jedes Skript einzeln
- systemd-Referenz — Units, Timer, Watchdog
- GCP-Failover — Notfallbetrieb komplett
- Vertieft in Repo:
docs/01-architektur.md
Labels: Community-Quelle = extern belegt (Herkunft in Klammern, z. B. pzwiki, Steam-Diskussionen, GCP-Preisliste) · Repo-Default = steht genau so im Repo (Template, Skript oder .env.example) · Heuristik = begründete Empfehlung dieses Projekts, nicht extern verifiziert.
The Indie Stone (TIS) publiziert keine offiziellen Storage-/IOPS-/Performance-Specs — Zahlen in diesem Wiki nie als TIS-Anforderung lesen.
Inhalte zielen auf den B42-Stable-Branch: seit B42.20 der Default-Zweig in Steam, kein -beta-Opt-in nötig (Community-Quelle).
Details zu Labels, Quellen und Redaktionsregeln: Konventionen-und-Quellen.
Einstieg
Referenz
- Makefile-Referenz
- Cheatsheet-Tagesbetrieb
- ENV-Variablen
- Server-Konfiguration
- Admin-Befehle
- Mods-Referenz
- Spawn-System
- Skripte-Referenz
- systemd-Referenz
- Ports-und-Netzwerk
- SteamCMD-Referenz
Betrieb
- Wartung-und-Automatik
- Backup-und-Restore
- Updates-und-Rollback
- Monitoring-und-Alerts
- Sicherheit-und-Hardening
- Docker-Betrieb
- GCP-Failover
Tiefenwissen
- Modding-Workflow
- Performance-Guide
- Storage-und-Map-Streaming
- Hardware-Empfehlungen
- Troubleshooting
- Runbook-Raven-Creek
Meta