feat: add homelab deployment configs, documentation, and automation scripts
This commit is contained in:
73
snarfnet-game-seeds/README.md
Normal file
73
snarfnet-game-seeds/README.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# 🌲 SnarfNet Game Seed Management Plane
|
||||
|
||||
Declarative, GitOps-ready game server management plane for the SnarfNet dedicated gaming machine (`bc:24:11:67:16:cd` @ `140.44.44.80`), modeled on the declarative seed pattern (`arasoi/yggdrasil-releases` and `arasoi/yggdrasil-seeds`).
|
||||
|
||||
---
|
||||
|
||||
## 🎮 Declared Game Servers
|
||||
|
||||
| Game | Steam AppID | Container Image | Ports | RAM (Res / Limit) | World Save Path |
|
||||
| :--- | :--- | :--- | :--- | :--- | :--- |
|
||||
| **Enshrouded** | `2278520` | `skarab42/enshrouded-server:latest` | `15636/udp`, `15637/udp` | 8GB / 16GB | `/opt/game-servers/enshrouded/savegame` |
|
||||
| **Farming Simulator 25** | `2300320` | `thijsvanloef/farming-simulator-25:latest` | `10823/tcp`, `10823/udp` | 6GB / 12GB | `/opt/game-servers/fs25/savegame` |
|
||||
| **Stationeers** | `600760` | `sprits/stationeers-server:latest` | `27016/udp`, `27015/udp` | 4GB / 8GB | `/opt/game-servers/stationeers/saves` |
|
||||
| **Valheim** (Crossplay) | `896660` | `lloesche/valheim-server:latest` | `2456/udp`, `2457/udp` | 4GB / 8GB | `/opt/game-servers/valheim/worlds` |
|
||||
| **V Rising** | `1829350` | `trueosiris/vrising:latest` | `9876/udp`, `9877/udp` | 4GB / 8GB | `/opt/game-servers/vrising/Saves` |
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Management CLI (`core/manager.py`)
|
||||
|
||||
The manager CLI reconciles declared seeds against the host runtime, triggers automated world backups to Synology NAS, and issues Wake-on-LAN magic packets.
|
||||
|
||||
### Commands
|
||||
|
||||
```bash
|
||||
# 1. Preview declared server configuration
|
||||
python core/manager.py plan
|
||||
|
||||
# 2. Render docker-compose.yml for live deployment
|
||||
python core/manager.py compose
|
||||
|
||||
# 3. Trigger manual atomic snapshot & sync to Synology NAS
|
||||
python core/manager.py backup
|
||||
|
||||
# 4. Wake up the gaming PC via Wake-on-LAN (bc:24:11:67:16:cd)
|
||||
python core/manager.py wol
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💾 Backup & Disaster Recovery Architecture
|
||||
|
||||
All game world save files are preserved in atomic tarballs and synchronized to the Synology NAS:
|
||||
- **NAS Backup NFS Target**: `14.10.10.71:/volume1/docker/game-backups`
|
||||
- **Host Mount**: `/mnt/nas/game-backups`
|
||||
- **Automated Timer**: Daily at 04:00 AM via `gameseed-backup.timer`
|
||||
- **Retention**: 14 rolling snapshots per game
|
||||
|
||||
---
|
||||
|
||||
## 🌐 UDM Pro Port Forwarding Matrix
|
||||
|
||||
To permit external friends and players to join the servers, ensure the following port forwards are mapped from WAN to `140.44.44.80` on the UDM Pro:
|
||||
|
||||
```
|
||||
Enshrouded: UDP 15636-15637 -> 140.44.44.80
|
||||
Farming Simulator 25: TCP/UDP 10823 -> 140.44.44.80
|
||||
Stationeers: UDP 27015-27016 -> 140.44.44.80
|
||||
Valheim: UDP 2456-2457 -> 140.44.44.80
|
||||
V Rising: UDP 9876-9877 -> 140.44.44.80
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Bootstrap New Host
|
||||
|
||||
To provision the physical gaming PC:
|
||||
```bash
|
||||
sudo bash scripts/setup-host.sh
|
||||
python3 core/manager.py compose
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
164
snarfnet-game-seeds/core/manager.py
Normal file
164
snarfnet-game-seeds/core/manager.py
Normal file
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
SnarfNet Game Seed Management Plane (Yggdrasil-compatible)
|
||||
Declarative orchestrator for private game servers on SnarfNet Gaming PC.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import glob
|
||||
import yaml
|
||||
import socket
|
||||
import struct
|
||||
import tarfile
|
||||
import datetime
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
TARGET_MAC = "bc:24:11:67:16:cd"
|
||||
BROADCAST_IP = "140.44.44.255"
|
||||
NAS_BACKUP_ROOT = "/mnt/nas/game-backups"
|
||||
SEEDS_DIR = Path(__file__).parent.parent / "seeds"
|
||||
|
||||
def send_wol(mac=TARGET_MAC, bcast=BROADCAST_IP):
|
||||
"""Sends a Wake-on-LAN magic packet to the gaming PC."""
|
||||
clean_mac = mac.replace(":", "").replace("-", "")
|
||||
if len(clean_mac) != 12:
|
||||
raise ValueError(f"Invalid MAC address: {mac}")
|
||||
data = bytes.fromhex("FF" * 6 + clean_mac * 16)
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
|
||||
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
||||
s.sendto(data, (bcast, 9))
|
||||
print(f"[WOL] Sent magic packet to {mac} via {bcast}:9")
|
||||
|
||||
def load_seeds():
|
||||
"""Loads all declarative seed YAML files from the seeds directory."""
|
||||
seeds = []
|
||||
for filepath in glob.glob(str(SEEDS_DIR / "*.seed.yaml")):
|
||||
with open(filepath, "r", encoding="utf-8") as f:
|
||||
docs = yaml.safe_load(f)
|
||||
if docs and docs.get("kind") == "GameSeed":
|
||||
seeds.append(docs)
|
||||
return seeds
|
||||
|
||||
def cmd_plan():
|
||||
"""Previews desired state across all defined game seeds."""
|
||||
seeds = load_seeds()
|
||||
print(f"\n=======================================================")
|
||||
print(f"🌲 SnarfNet Game Seed Plan ({len(seeds)} Seeds Declared)")
|
||||
print(f"=======================================================")
|
||||
for s in seeds:
|
||||
meta = s.get("metadata", {})
|
||||
spec = s.get("spec", {})
|
||||
game = spec.get("game", {})
|
||||
server = spec.get("server", {})
|
||||
net = spec.get("network", {})
|
||||
runtime = spec.get("runtime", {})
|
||||
res = spec.get("resources", {})
|
||||
|
||||
ports = ", ".join([f"{p['port']}/{p['protocol']}" for p in net.get("ports", [])])
|
||||
print(f"\n🎮 [{meta.get('name')}] {meta.get('displayName')}")
|
||||
print(f" Steam AppID: {game.get('appId')} (Branch: {game.get('branch')})")
|
||||
print(f" Image: {runtime.get('image')}")
|
||||
print(f" Ports: {ports}")
|
||||
print(f" Memory: {res.get('memoryReservation')} -> {res.get('memoryLimit')}")
|
||||
print(f" Save Dir: {server.get('saveDirectory')}")
|
||||
print(f" Backup: {spec.get('backup', {}).get('schedule')} (Retention: {spec.get('backup', {}).get('retentionDays')}d)")
|
||||
|
||||
def cmd_generate_compose(output_path="docker-compose.yml"):
|
||||
"""Generates standard docker-compose.yml from all declared seeds."""
|
||||
seeds = load_seeds()
|
||||
services = {}
|
||||
|
||||
for s in seeds:
|
||||
name = s["metadata"]["name"]
|
||||
spec = s["spec"]
|
||||
runtime = spec.get("runtime", {})
|
||||
server = spec.get("server", {})
|
||||
net = spec.get("network", {})
|
||||
res = spec.get("resources", {})
|
||||
|
||||
ports = []
|
||||
for p in net.get("ports", []):
|
||||
ports.append(f"{p['port']}:{p['port']}/{p['protocol'].lower()}")
|
||||
|
||||
save_dir = server.get("saveDirectory")
|
||||
data_dir = f"/opt/game-servers/{name}/data"
|
||||
|
||||
services[name] = {
|
||||
"image": runtime.get("image"),
|
||||
"container_name": f"gameseed-{name}",
|
||||
"restart": runtime.get("restartPolicy", "unless-stopped"),
|
||||
"environment": runtime.get("environment", {}),
|
||||
"ports": ports,
|
||||
"volumes": [
|
||||
f"{save_dir}:{save_dir}",
|
||||
f"{data_dir}:/serverdata"
|
||||
],
|
||||
"deploy": {
|
||||
"resources": {
|
||||
"limits": {
|
||||
"memory": res.get("memoryLimit", "8Gi"),
|
||||
"cpus": res.get("cpuLimit", "4")
|
||||
},
|
||||
"reservations": {
|
||||
"memory": res.get("memoryReservation", "4Gi")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compose = {
|
||||
"version": "3.8",
|
||||
"services": services
|
||||
}
|
||||
|
||||
with open(output_path, "w", encoding="utf-8") as f:
|
||||
yaml.dump(compose, f, sort_keys=False)
|
||||
print(f"[COMPOSE] Rendered {len(services)} services to {output_path}")
|
||||
|
||||
def cmd_backup():
|
||||
"""Executes atomic snapshots of all world save directories and copies to Synology NAS."""
|
||||
seeds = load_seeds()
|
||||
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
nas_root = Path(NAS_BACKUP_ROOT)
|
||||
|
||||
print(f"\n📦 Starting Declarative Game Save Backups ({timestamp})...")
|
||||
for s in seeds:
|
||||
name = s["metadata"]["name"]
|
||||
save_dir = Path(s["spec"]["server"]["saveDirectory"])
|
||||
target_dir = nas_root / name
|
||||
target_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
archive_name = f"{name}_save_{timestamp}.tar.gz"
|
||||
archive_path = target_dir / archive_name
|
||||
|
||||
if save_dir.exists():
|
||||
print(f" Archiving {name}: {save_dir} -> {archive_path}")
|
||||
with tarfile.open(archive_path, "w:gz") as tar:
|
||||
tar.add(save_dir, arcname=name)
|
||||
print(f" ✓ Backup complete: {archive_path} ({archive_path.stat().st_size} bytes)")
|
||||
else:
|
||||
print(f" [SKIP] Save directory {save_dir} not found on host.")
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python manager.py <plan|compose|backup|wol>")
|
||||
sys.exit(1)
|
||||
|
||||
action = sys.argv[1].lower()
|
||||
if action == "plan":
|
||||
cmd_plan()
|
||||
elif action == "compose":
|
||||
cmd_generate_compose()
|
||||
elif action == "backup":
|
||||
cmd_backup()
|
||||
elif action == "wol":
|
||||
send_wol()
|
||||
else:
|
||||
print(f"Unknown command: {action}")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
96
snarfnet-game-seeds/scripts/setup-host.sh
Normal file
96
snarfnet-game-seeds/scripts/setup-host.sh
Normal file
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env bash
|
||||
# ==============================================================================
|
||||
# SnarfNet Gaming PC Bootstrap Script
|
||||
# MAC: bc:24:11:67:16:cd | IP: 140.44.44.80 (Compute / Game VLAN)
|
||||
# ==============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
echo "======================================================="
|
||||
echo "🌲 Bootstrapping SnarfNet Dedicated Game Server Host"
|
||||
echo "======================================================="
|
||||
|
||||
# 1. System Updates & Essential Tools
|
||||
echo ">>> Installing prerequisites and system tools..."
|
||||
apt-get update && apt-get install -y \
|
||||
curl wget git jq ufw nfs-common ethtool net-tools \
|
||||
python3 python3-yaml python3-pip apt-transport-https \
|
||||
ca-certificates gnupg lsb-release
|
||||
|
||||
# 2. Configure Wake-on-LAN (Persistent via systemd)
|
||||
echo ">>> Configuring Wake-on-LAN for primary interface..."
|
||||
NIC=$(ip route show default | awk '{print $5}' | head -n1)
|
||||
ethtool -s "$NIC" wol g || true
|
||||
|
||||
cat <<EOF > /etc/systemd/system/wol.service
|
||||
[Unit]
|
||||
Description=Enable Wake-on-LAN on $NIC
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/sbin/ethtool -s $NIC wol g
|
||||
|
||||
[Install]
|
||||
WantedBy=basic.target
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
systemctl enable wol.service
|
||||
|
||||
# 3. Mount Synology NAS Game Backup Share
|
||||
echo ">>> Configuring Synology NAS NFS Mount (14.10.10.71:/volume1/docker/game-backups)..."
|
||||
mkdir -p /mnt/nas/game-backups
|
||||
if ! grep -qs '/mnt/nas/game-backups' /etc/fstab; then
|
||||
echo "14.10.10.71:/volume1/docker/game-backups /mnt/nas/game-backups nfs rw,hard,intr,nolock,timeo=14 0 0" >> /etc/fstab
|
||||
fi
|
||||
mount -a || true
|
||||
|
||||
# 4. Install Docker & Compose (if not present)
|
||||
if ! command -v docker &> /dev/null; then
|
||||
echo ">>> Installing Docker Engine..."
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
systemctl enable docker
|
||||
systemctl start docker
|
||||
fi
|
||||
|
||||
# 5. Prepare Game Directory Structure
|
||||
echo ">>> Creating game server storage paths..."
|
||||
mkdir -p /opt/game-servers/{enshrouded,fs25,stationeers,valheim,vrising}/{savegame,saves,worlds,data}
|
||||
chmod -R 775 /opt/game-servers
|
||||
|
||||
# 6. Setup Seed Manager Service & Daily Cron
|
||||
echo ">>> Installing SnarfNet Seed Reconciler and Backup Timer..."
|
||||
cat <<EOF > /etc/systemd/system/gameseed-backup.service
|
||||
[Unit]
|
||||
Description=SnarfNet Declarative Game Server Save Backup
|
||||
After=network.target docker.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
WorkingDirectory=/opt/snarfnet-game-seeds
|
||||
ExecStart=/usr/bin/python3 /opt/snarfnet-game-seeds/core/manager.py backup
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
cat <<EOF > /etc/systemd/system/gameseed-backup.timer
|
||||
[Unit]
|
||||
Description=Nightly Game Save Backup Timer (04:00 AM)
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 04:00:00
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
Timers.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable gameseed-backup.timer
|
||||
systemctl start gameseed-backup.timer
|
||||
|
||||
echo "======================================================="
|
||||
echo "✓ Host bootstrap complete!"
|
||||
echo "Run: python3 /opt/snarfnet-game-seeds/core/manager.py compose && docker compose up -d"
|
||||
echo "======================================================="
|
||||
|
||||
42
snarfnet-game-seeds/seeds/enshrouded.seed.yaml
Normal file
42
snarfnet-game-seeds/seeds/enshrouded.seed.yaml
Normal file
@@ -0,0 +1,42 @@
|
||||
apiVersion: yggdrasil.snarfnet.net/v1alpha1
|
||||
kind: GameSeed
|
||||
metadata:
|
||||
name: enshrouded
|
||||
displayName: "Enshrouded Dedicated Server"
|
||||
version: "1.0.0"
|
||||
spec:
|
||||
game:
|
||||
appId: 2278520
|
||||
branch: public
|
||||
autoUpdate: true
|
||||
server:
|
||||
name: "SnarfNet Enshrouded Sanctuary"
|
||||
passwordSecret: "ENSHROUDED_SERVER_PASSWORD"
|
||||
maxPlayers: 16
|
||||
saveDirectory: "/opt/game-servers/enshrouded/savegame"
|
||||
network:
|
||||
ip: "140.44.44.80"
|
||||
ports:
|
||||
- port: 15636
|
||||
protocol: UDP
|
||||
description: "Game Query & Traffic"
|
||||
- port: 15637
|
||||
protocol: UDP
|
||||
description: "Steam Query Port"
|
||||
resources:
|
||||
cpuLimit: "8"
|
||||
memoryLimit: "16Gi"
|
||||
memoryReservation: "8Gi"
|
||||
runtime:
|
||||
image: "skarab42/enshrouded-server:latest"
|
||||
restartPolicy: unless-stopped
|
||||
environment:
|
||||
SERVER_NAME: "SnarfNet Enshrouded Sanctuary"
|
||||
SERVER_SLOTS: 16
|
||||
GAME_PORT: 15636
|
||||
QUERY_PORT: 15637
|
||||
backup:
|
||||
schedule: "0 4 * * *" # Daily 04:00 AM
|
||||
retentionDays: 14
|
||||
targetPath: "/mnt/nas/game-backups/enshrouded"
|
||||
|
||||
41
snarfnet-game-seeds/seeds/farming-simulator-25.seed.yaml
Normal file
41
snarfnet-game-seeds/seeds/farming-simulator-25.seed.yaml
Normal file
@@ -0,0 +1,41 @@
|
||||
apiVersion: yggdrasil.snarfnet.net/v1alpha1
|
||||
kind: GameSeed
|
||||
metadata:
|
||||
name: farming-simulator-25
|
||||
displayName: "Farming Simulator 25 Dedicated Server"
|
||||
version: "1.0.0"
|
||||
spec:
|
||||
game:
|
||||
appId: 2300320
|
||||
branch: public
|
||||
autoUpdate: true
|
||||
server:
|
||||
name: "SnarfNet FS25 Countryside"
|
||||
passwordSecret: "FS25_SERVER_PASSWORD"
|
||||
adminPasswordSecret: "FS25_ADMIN_PASSWORD"
|
||||
maxPlayers: 16
|
||||
saveDirectory: "/opt/game-servers/fs25/savegame"
|
||||
network:
|
||||
ip: "140.44.44.80"
|
||||
ports:
|
||||
- port: 10823
|
||||
protocol: TCP
|
||||
description: "Game Web Management & Client Connection"
|
||||
- port: 10823
|
||||
protocol: UDP
|
||||
description: "Game Network Traffic"
|
||||
resources:
|
||||
cpuLimit: "6"
|
||||
memoryLimit: "12Gi"
|
||||
memoryReservation: "6Gi"
|
||||
runtime:
|
||||
image: "thijsvanloef/farming-simulator-25:latest"
|
||||
restartPolicy: unless-stopped
|
||||
environment:
|
||||
SERVER_NAME: "SnarfNet FS25 Countryside"
|
||||
GAME_PORT: 10823
|
||||
backup:
|
||||
schedule: "0 4 * * *"
|
||||
retentionDays: 14
|
||||
targetPath: "/mnt/nas/game-backups/farming-simulator-25"
|
||||
|
||||
44
snarfnet-game-seeds/seeds/stationeers.seed.yaml
Normal file
44
snarfnet-game-seeds/seeds/stationeers.seed.yaml
Normal file
@@ -0,0 +1,44 @@
|
||||
apiVersion: yggdrasil.snarfnet.net/v1alpha1
|
||||
kind: GameSeed
|
||||
metadata:
|
||||
name: stationeers
|
||||
displayName: "Stationeers Dedicated Server"
|
||||
version: "1.0.0"
|
||||
spec:
|
||||
game:
|
||||
appId: 600760
|
||||
branch: public
|
||||
autoUpdate: true
|
||||
server:
|
||||
name: "SnarfNet Stationeers Moonbase"
|
||||
worldName: "Moon"
|
||||
passwordSecret: "STATIONEERS_SERVER_PASSWORD"
|
||||
maxPlayers: 10
|
||||
saveDirectory: "/opt/game-servers/stationeers/saves"
|
||||
network:
|
||||
ip: "140.44.44.80"
|
||||
ports:
|
||||
- port: 27016
|
||||
protocol: UDP
|
||||
description: "Game Traffic Port"
|
||||
- port: 27015
|
||||
protocol: UDP
|
||||
description: "Steam Query Port"
|
||||
resources:
|
||||
cpuLimit: "4"
|
||||
memoryLimit: "8Gi"
|
||||
memoryReservation: "4Gi"
|
||||
runtime:
|
||||
image: "sprits/stationeers-server:latest"
|
||||
restartPolicy: unless-stopped
|
||||
environment:
|
||||
SERVER_NAME: "SnarfNet Stationeers Moonbase"
|
||||
WORLD_NAME: "Moon"
|
||||
GAME_PORT: 27016
|
||||
QUERY_PORT: 27015
|
||||
AUTO_SAVE_INTERVAL: 300
|
||||
backup:
|
||||
schedule: "0 4 * * *"
|
||||
retentionDays: 14
|
||||
targetPath: "/mnt/nas/game-backups/stationeers"
|
||||
|
||||
47
snarfnet-game-seeds/seeds/valheim.seed.yaml
Normal file
47
snarfnet-game-seeds/seeds/valheim.seed.yaml
Normal file
@@ -0,0 +1,47 @@
|
||||
apiVersion: yggdrasil.snarfnet.net/v1alpha1
|
||||
kind: GameSeed
|
||||
metadata:
|
||||
name: valheim
|
||||
displayName: "Valheim Dedicated Server"
|
||||
version: "1.0.0"
|
||||
spec:
|
||||
game:
|
||||
appId: 896660
|
||||
branch: public
|
||||
autoUpdate: true
|
||||
server:
|
||||
name: "SnarfNet Valheim Valhalla"
|
||||
worldName: "Snarfheim"
|
||||
passwordSecret: "VALHEIM_SERVER_PASSWORD"
|
||||
crossplay: true
|
||||
maxPlayers: 10
|
||||
saveDirectory: "/opt/game-servers/valheim/worlds"
|
||||
network:
|
||||
ip: "140.44.44.80"
|
||||
ports:
|
||||
- port: 2456
|
||||
protocol: UDP
|
||||
description: "Game Traffic Port"
|
||||
- port: 2457
|
||||
protocol: UDP
|
||||
description: "Steam Query Port"
|
||||
resources:
|
||||
cpuLimit: "6"
|
||||
memoryLimit: "8Gi"
|
||||
memoryReservation: "4Gi"
|
||||
runtime:
|
||||
image: "lloesche/valheim-server:latest"
|
||||
restartPolicy: unless-stopped
|
||||
environment:
|
||||
SERVER_NAME: "SnarfNet Valheim Valhalla"
|
||||
WORLD_NAME: "Snarfheim"
|
||||
SERVER_PORT: 2456
|
||||
SERVER_PUBLIC: 1
|
||||
CROSSPLAY: "true"
|
||||
UPDATE_CRON: "0 5 * * *"
|
||||
BEPINEX: "false"
|
||||
backup:
|
||||
schedule: "0 4 * * *"
|
||||
retentionDays: 14
|
||||
targetPath: "/mnt/nas/game-backups/valheim"
|
||||
|
||||
43
snarfnet-game-seeds/seeds/vrising.seed.yaml
Normal file
43
snarfnet-game-seeds/seeds/vrising.seed.yaml
Normal file
@@ -0,0 +1,43 @@
|
||||
apiVersion: yggdrasil.snarfnet.net/v1alpha1
|
||||
kind: GameSeed
|
||||
metadata:
|
||||
name: vrising
|
||||
displayName: "V Rising Dedicated Server"
|
||||
version: "1.0.0"
|
||||
spec:
|
||||
game:
|
||||
appId: 1829350
|
||||
branch: public
|
||||
autoUpdate: true
|
||||
server:
|
||||
name: "SnarfNet V Rising Vampire Lair"
|
||||
saveName: "SnarfNet_Vampires"
|
||||
passwordSecret: "VRISING_SERVER_PASSWORD"
|
||||
maxPlayers: 20
|
||||
saveDirectory: "/opt/game-servers/vrising/Saves"
|
||||
network:
|
||||
ip: "140.44.44.80"
|
||||
ports:
|
||||
- port: 9876
|
||||
protocol: UDP
|
||||
description: "Game Traffic Port"
|
||||
- port: 9877
|
||||
protocol: UDP
|
||||
description: "Query Port"
|
||||
resources:
|
||||
cpuLimit: "6"
|
||||
memoryLimit: "8Gi"
|
||||
memoryReservation: "4Gi"
|
||||
runtime:
|
||||
image: "trueosiris/vrising:latest"
|
||||
restartPolicy: unless-stopped
|
||||
environment:
|
||||
SERVERNAME: "SnarfNet V Rising Vampire Lair"
|
||||
SAVENAME: "SnarfNet_Vampires"
|
||||
GAMEPORT: 9876
|
||||
QUERYPORT: 9877
|
||||
backup:
|
||||
schedule: "0 4 * * *"
|
||||
retentionDays: 14
|
||||
targetPath: "/mnt/nas/game-backups/vrising"
|
||||
|
||||
Reference in New Issue
Block a user