Subsections of Gaming
Auto Update Steamcmd Servers
Idee
Mit Steamcmd können verschiedene Spieleserver heruntergeladen werden.
Die lokal installierte Version hat eine buildid, die mit der öffentlich verfügbaren Version verglichen wird.
Unterscheiden sich die beiden IDs, werden die Dateien mittels Docker und des Steamcmd Images aktualisiert.
Läuft der Container des Servers noch, wird dieser gestoppt und im anschluss neugestartet.
Genauere Infos zum Verhalten wird noch weiter unten beleuchtet.
Skript
Grundsätzlich ist dieses Skript für Docker basierte Server gedacht. Es kann auch andere Systeme updaten, allerdings sind Prüfungen und Funktionen für Docker eingebaut. Einfach unter /usr/local/sbin/update_steam_game.sh
ablegen.
#!/bin/bash
set -e
: "${APP_ID:=}"
: "${APP_DIR:=}"
: "${APP_UID:=1000}"
: "${APP_GID:=1000}"
: "${APP_DIR_INIT:=0}"
: "${CONTAINER_NAME:=}"
: "${UPDATE_SCRIPT:=}"
[[ ! -d "${APP_DIR}" && "${APP_DIR_INIT}" != "1" ]] && echo "APP_DIR [${APP_DIR}] does not exist" && exit 1
# get state of game
TEMP_FILE=$(mktemp)
URL="https://api.steamcmd.net/v1/info/${APP_ID}"
curl -X GET "${URL}" -o ${TEMP_FILE} > /dev/null 2>&1
local_buildid=$(grep -oP 'buildid.+"\K[0-9]+' ${APP_DIR}/appmanifest_${APP_ID}.acf 2>/dev/null|| echo 0)
remote_buildid=$(jq -r '.data.[].depots.branches.public.buildid' "${TEMP_FILE}")
rm "${TEMP_FILE}"
if [[ "${local_buildid}" == "${remote_buildid}" ]]; then
echo "no update needed - buildid local[${local_buildid}] remote[${remote_buildid}]"
exit 0
fi
# stop container if existing and not stopped
state=$(docker ps -a -f name="^${CONTAINER_NAME}$" --format json | jq -r '.State')
if [[ ${state} == "" ]];then
echo "Container [${CONTAINER_NAME}] does not exist (check ENV CONTAINER_NAME variable)"
elif [[ ! ${state} =~ exited ]];then
echo "stopping container [${CONTAINER_NAME}]"
docker stop "${CONTAINER_NAME}"
stopped=1
fi
# update by script / default cmd
if [[ -x "${UPDATE_SCRIPT}" ]];then
echo "UPDATE BY SCRIPT [${UPDATE_SCRIPT}]"
${UPDATE_SCRIPT}
else
# create directory and fix permissions
if [[ ! -d "${APP_DIR}" ]];then
mkdir -p "${APP_DIR}"
fi
ts=$(date +'%s')
chown -R 1000:1000 "${APP_DIR}"
cmd="docker run --network host --rm -it --name=${CONTAINER_NAME:-steam_$ts}_updater -v ${APP_DIR}:/home/steam/Steam/steamapps:rw cm2network/steamcmd /home/steam/steamcmd/steamcmd.sh +login anonymous +app_update ${APP_ID} validate +quit"
echo "UPDATE BY COMMAND [${cmd}]"
$cmd
chown -R ${APP_UID}:${APP_GID} "${APP_DIR}"
fi
[[ ${stopped} -eq 1 ]] && echo "starting docker container [${CONTAINER_NAME}]" && docker start "${CONTAINER_NAME}"
Berechtigung fixen:
chmod 700 /usr/local/sbin/update_steam_game.sh
Benutzung
Zu Beginn des Skripts werden folgende Variablen gesetzt:
Variable | Verwendung |
---|---|
APP_ID | ID des Spiels, Palworld z.B. hat die ID 2394010 |
APP_DIR | Pfad zu steamapps (Installation), im Dockercontainer wäre dies der Pfad zu /home/steam/Steam/steamapps |
APP_DIR_INIT | Existiert der Ordner noch nicht, wird dieser angelegt und das Spiel erstmalig heruntergeladen |
CONTAINER_NAME | Name des Server-Containers der geprüft und ggf. neugestartet werden soll |
UPDATE_SCRIPT | Pfad zu einem eigenen Update Skript, welches Anstelle des docker run Befehls mit Standard Steamcmd Parametern ausgeführt wird (z.B. wenn Login nötig ist, oder anderer Branch) |
OPTIONALE VARIABLEN | |
APP_UID | Nach dem Update wird der Owner von APP_DIR auf diese ID gesetzt |
APP_GID | Nach dem Update wird die Owner Group von APP_DIR auf diese GID gesetzt |
Beispiel:
Auto Update für Palworld, kann so auch als Cronjob / Systemd Timer laufen…
APP_ID="2394010" APP_DIR_INIT="1" APP_DIR="/srv/docker/containers/steam/palworld.testing2/" CONTAINER_NAME="steam_palworld_test" /usr/local/sbin/update_steam_game.sh
CSGO Training Server mit Docker und Auto-Update
Vorwort
Das Spiel ist Programm, viele spielten es schon mit 1.6, oder gar früheren Versionen.
Hier kurz und bündig die Installation eines Training-Servers basierend auf Docker.
Installation
Es können beliebig viele CSGO-Server gestartet werden, einfach einen weiteren Service in der docker-compose.yml und weitere env-Datei hinzufügen! Der Auto-Updater erkennt selbständig weitere Instanzen.
# File: docker-compose.yml
version: "3"
services:
# Dokumentation: https://github.com/timche/docker-csgo-updater
csgo_updater:
container_name: "csgo_updater"
# timches Updater Image
image: "timche/csgo-updater"
restart: "unless-stopped"
# kann auch isoliert laufen, network_mode ist aber einfacher
network_mode: "host"
volumes:
# notwendig um via Socket Docker Befehle (wie einen Neustart) zu senden
- "/var/run/docker.sock:/var/run/docker.sock"
environment:
# Container mit dem folgenden Image werden berücksichtigt
UPDATER_CONTAINER_IMAGE: "timche/csgo"
# Interval (Sekunden) in denen Container gescannt werden
UPDATER_POLL_INTERVAL: 60
csgo_practice:
container_name: "csgo_practice"
# fertiges Image mit Training-Plugin
image: "timche/csgo:pug-practice"
restart: "unless-stopped"
network_mode: "host"
volumes:
- "/srv/docker/containers/csgo_practice/:/home/csgo/server:rw"
env_file:
- practice.env
In der practive.env kommen alle Umgebungsvariablen hinein, die der Container berüsichtigt.
Weitere Informationen und Anleitungen für die REPLACE_-Keys findet man im Projekt
https://github.com/timche/docker-csgo/blob/main/README.md
# File: practice.env
CSGO_GSLT=REPLACE_SPIELSERVER_ACCOUNT_KEY
CSGO_WS_API_KEY=REPLACE_MEIN_WEB_API_KEY
CSGO_MAP=de_mirage
CSGO_MAX_PLAYERS=16
CSGO_HOSTNAME=My Train server
CSGO_RCON_PW=mein_rcon_pw
CSGO_PW=mein_server_password
CSGO_TICKRATE=64
CSGO_GAME_TYPE=0
CSGO_TV_ENABLE=true
CSGO_TV_NAME=My Train TV
CSGO_TV_DELAY=45
CSGO_TV_PORT=27020
CSGO_DISABLE_BOTS=true
Auto-Update
Der CSGO-Updater Container prüft im Stdout-Log des Spieleservers, ob diese vom Steam-Server zu einem restart gebeten werden (MasterRequestRestart).
Wird die Zeile erkannt, löst der Updater einen Restart aus (sofern der Server leer ist) und die CSGO-Server-Container laden die aktuelle Spieleversion herunter.
Palworld Server mit Docker
Diese Anleitung beschreibt die Erstellung eines Palworld Servers mit Einstellungen und Backup in einem isolierten Docker-Container.
Vorbereitung
Es wird Docker und rsync benötigt.
pacman -Syu docker rsync
apt update
apt install docker.io rsync
Server downloaden
Die Installation des Servers findet im Ordner /srv/docker/containers/steam/palworld/ statt, dieser muss an mehreren Stellen angepasst werden, falls ein anderer Ort gewünscht ist!
mkdir -p /srv/docker/containers/steam/palworld/
chown 1000:1000 /srv/docker/containers/steam/palworld/
docker run --network host --rm -it --name=steamcmd -v /srv/docker/containers/steam/palworld/:/home/steam/Steam/steamapps:rw cm2network/steamcmd /home/steam/steamcmd/steamcmd.sh +login anonymous +app_update 2394010 validate +quit
Server vorbereiten
Einfach eine docker-compose.yml anlegen
Die IP-Adresse (1.2.3.4) durch die öffentliche IP ersetzen und ggf. Port, falls ein anderer gewünscht ist.
version: "3"
services:
palworld-server:
container_name: 'steam_palworld'
hostname: 'palworld-server'
image: 'cm2network/steamcmd'
ports:
- 8211:8211/udp
- 27015:27015/tcp
volumes:
- /srv/docker/containers/steam/palworld/:/home/steam/Steam/steamapps:rw
entrypoint:
- "/home/steam/Steam/steamapps/common/PalServer/PalServer.sh"
# FALLS der Server gelistet werden soll, sonst Zeile löschen
- "EpicApp=PalServer"
# HIER öffentliche IP einsetzen
- "-publicip=1.2.3.4"
# FALLS ein anderer Port genutzt wird, anpassen
- "-publicport=8211"
environment:
PGID: 1000
PUID: 1000
restart: unless-stopped
networks:
default:
ipv4_address: 172.22.25.2
networks:
default:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.22.25.0/24
driver_opts:
com.docker.network.bridge.name: br_steam
Nun muss die Server-Config selbst kopiert werden:
mkdir -p /srv/docker/containers/steam/palworld/common/PalServer/Pal/Saved/Config/
chown -R 1000:1000 /srv/docker/containers/steam/palworld
cp /srv/docker/containers/steam/palworld/common/PalServer/DefaultPalWorldSettings.ini /srv/docker/containers/steam/palworld/common/PalServer/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini
Danach kann die Konfiguration angepasst werden. Informationen zu den Parametern findet man zu genüge im Internet…
Start des Servers
docker-compose up -d
Grundsätzlich loggt der Server kaum etwas und man findet nur Hinweise auf den Kontakt des Steam-Netzwerks, ansonsten bleibt es recht ruhig:
2024-02-01T10:22:44.694623116Z - Existing per-process limit (soft=xxxxx, hard=xxxxx) is enough for us (need only xxxxx)
2024-02-01T10:22:44.694638425Z Increasing per-process limit of core file size to infinity.
2024-02-01T10:22:44.694641135Z - Existing per-process limit (soft=xxxxx, hard=xxxxx) is enough for us (need only xxxxx)
2024-02-01T10:22:44.775042934Z CAppInfoCacheReadFromDiskThread took 0 milliseconds to initialize
2024-02-01T10:22:44.787811558Z Setting breakpad minidump AppID = 2394010
2024-02-01T10:22:44.788494153Z [S_API FAIL] Tried to access Steam interface SteamUser021 before SteamAPI_Init succeeded.
2024-02-01T10:22:44.788499153Z [S_API FAIL] Tried to access Steam interface SteamFriends017 before SteamAPI_Init succeeded.
2024-02-01T10:22:45.224352804Z [S_API FAIL] Tried to access Steam interface STEAMAPPS_INTERFACE_VERSION008 before SteamAPI_Init succeeded.
2024-02-01T10:22:45.279131338Z [S_API FAIL] Tried to access Steam interface SteamNetworkingUtils004 before SteamAPI_Init succeeded.
Backup
Das Skript wird alle 10 Minuten ausgeführt und löscht alte Backups nach 7 Tagen.
Ein einfaches Skript unter /usr/local/bin/backup_palworld.sh
anlegen.
#/bin/bash
# 7 Tage Backups behalten
BACKUP_ROTATE_HOURS="$(( 7 * 24 ))"
BACKUP_DIR="/srv/backup/palworld/"
DATE=$(date +'%Y-%m-%d-%H-%M-%S')
PATH_DST="${BACKUP_DIR}/${DATE}/"
PATH_SRC="/srv/docker/containers/steam/palworld/common/PalServer/Pal/Saved/"
mkdir -p ${BACKUP_DIR}
# kopieren des Backups
rsync -aH "${PATH_SRC}" "${PATH_DST}"
# Zeitstempel auf NOW()
touch "${PATH_DST}"
backup_timeout_minutes="$(( $BACKUP_ROTATE_HOURS * 60 ))"
# alte Backups finden die älter als Rotation sind und löschen
find "${BACKUP_DIR}" -maxdepth 1 -mmin +${backup_timeout_minutes} -exec rm -rv {} \;
Das Skript mmuss noch ausführbar gemacht werden und kann dann im Crontab hinterlegt werden:
chmod 700 /usr/local/bin/backup_palworld.sh
crontab -e
# alle 10 Minuten Backup ausführen
*/10 * * * * /usr/local/bin/backup_palworld.sh
Vintage Story Server mit Docker
Vorwort
Vintage Story ist Survival-Sandbox-Game, welches gemeinsames Spielen mit Freunden mittels Server ermöglicht;
Vorbereitung
Für den Bau ist Docker und Git notwendig! Falls nicht bereits installiert:
pacman -Syu docker git
apt update
apt install git docker.io
Docker Image bauen
Aus rechtlichen Gründen (ich habe im Chat beim Entwickler gefragt) darf ich keine fertigen Images auf Docker Hub oder anderen Registries anbieten. Deshalb habe ich ein kleines Projekt zum bauen des Images angelegt.
Einfach das Projekt herunterladen, oder auschecken:
# Projekt auschecken
git clone https://github.com/dr3st/docker-vintage-story.git
cd docker-vintage-story
# Image bauen
VS_VERSION=1.16.4 ./build.sh
Sollte es Schwierigkeiten beim bauen geben, weil zum Beispiel die Firewall etwas unterbindet, kann der Build-Befehl angepasst werden.
Alle Parameter hinter build.sh werden an “docker build” übergeben.
VS_VERSION=1.14.9 ./build.sh [--network host]
Danach steht das Image vintagestory:1.16.4
zur Verfügung.
Beim Bauen wird das aktuelle Spiel vom Hersteller heruntergeladen und in das Image integriert, siehe Dockerfile: https://github.com/dr3st/docker-vintage-story/blob/main/Dockerfile
Server einrichten
Die möglichen Parameter des Docker Images sind der README zu entnehmen: https://github.com/dr3st/docker-vintage-story/blob/main/README.md#parameters
# File: docker-compose.yml
version: '3.1'
services:
vintage_story:
image: "vintagestory:1.16.4"
container_name: vintage_story
restart: unless-stopped
network_mode: host
environment:
PUID: 1000
PGID: 1000
volumes:
- "/srv/docker/containers/vintage_story:/data:rw"
Im Anschluss wird der Vintage Story Server seine Daten im Hostverzeichnis /srv/docker/containers/vintage_story abspeichern, sodass weitere Konfigurationen innerhalb dieses Verzeichnisses möglich sind.