diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..8b04dd67 --- /dev/null +++ b/.env.example @@ -0,0 +1,9 @@ +TICKRATE=128 +MAXPLAYERS=24 +API_KEY= # Only needed if workshop maps are needed +STEAM_ACCOUNT= # Only needed for online play +RCON_PASSWORD= +SERVER_PASSWORD= + +# Auto-update configuration +UPDATE_CHECK_INTERVAL=300 # Check for CS2 updates every 300 seconds (5 minutes) diff --git a/Dockerfile b/Dockerfile index 06e5cce4..77b8f4d0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,47 +1,33 @@ -FROM registry.gitlab.steamos.cloud/steamrt/sniper/platform:latest-container-runtime-depot - -USER root - -RUN apt-get update --fix-missing \ - && apt-get install -y --no-install-recommends \ - dnsutils \ - git-all \ - lib32z1=1:1.2.11.dfsg-2+deb11u2 \ - wget=1.21-1+deb11u1 \ - && sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \ - && dpkg-reconfigure --frontend=noninteractive locales - -RUN addgroup steam \ - && useradd -g steam steam \ - && usermod -aG sudo steam - -ENV TICKRATE="" -ENV MAXPLAYERS="" -ENV API_KEY="" -ENV STEAM_ACCOUNT="" - -RUN echo "steam ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/steam \ - && chmod 0440 /etc/sudoers.d/steam - -ENV HOME="/home/steam/cs2/" - -RUN mkdir -p $HOME && \ - chown -R steam:steam $HOME - -ENV SRC_DIR="/home/cs2-modded-server" - -WORKDIR $SRC_DIR - -COPY custom_files $SRC_DIR/custom_files - -COPY install_docker.sh \ - run.sh \ - start.sh \ - stop.sh \ - $SRC_DIR - -COPY game/csgo $SRC_DIR/game/csgo - -USER steam - -CMD [ "sudo", "-E", "bash", "/home/cs2-modded-server/install_docker.sh" ] +FROM registry.gitlab.steamos.cloud/steamrt/sniper/platform:latest-container-runtime-depot + +USER root + +RUN apt-get update --fix-missing && apt-get install -y --no-install-recommends dnsutils git-all lib32z1=1:1.2.11.dfsg-2+deb11u2 wget=1.21-1+deb11u1 && sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && dpkg-reconfigure --frontend=noninteractive locales + +RUN addgroup steam && useradd -g steam steam && usermod -aG sudo steam + +ENV TICKRATE="" +ENV MAXPLAYERS="" +ENV API_KEY="" +ENV STEAM_ACCOUNT="" +ENV UPDATE_CHECK_INTERVAL="300" + +RUN echo "steam ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/steam && chmod 0440 /etc/sudoers.d/steam + +ENV HOME="/home/steam/cs2/" + +RUN mkdir -p $HOME && chown -R steam:steam $HOME + +ENV SRC_DIR="/home/cs2-modded-server" + +WORKDIR $SRC_DIR + +COPY custom_files $SRC_DIR/custom_files + +COPY install_docker.sh run.sh start.sh stop.sh auto_update.sh $SRC_DIR + +COPY game/csgo $SRC_DIR/game/csgo + +USER steam + +CMD [ "sudo", "-E", "bash", "/home/cs2-modded-server/install_docker.sh" ] diff --git a/README.md b/README.md index 0c9c3965..8ff644f4 100644 --- a/README.md +++ b/README.md @@ -211,6 +211,7 @@ Key | Default value | What is it `EXEC` | `on_boot.cfg` | Config file to run when server boots. If switching gamemode, it's recommended to do a delay see the example `on_boot.cfg` file `DUCK_DOMAIN` | `` | (Linux only) [Duck DNS](https://www.duckdns.org/) domain if you want to utalise the free service to get a domain for your server instead of IP `DUCK_TOKEN` | `` | (Linux only) [Duck DNS](https://www.duckdns.org/) access token to update domain when server boots +`UPDATE_CHECK_INTERVAL` | `300` | Time in seconds between update checks for CS2. The auto-updater will check Steam for new CS2 builds at this interval and automatically update the server (default: 300 = 5 minutes) ## Playing workshop maps/collections diff --git a/auto_update.sh b/auto_update.sh new file mode 100755 index 00000000..c8519a82 --- /dev/null +++ b/auto_update.sh @@ -0,0 +1,126 @@ +#!/usr/bin/env bash + +# CS2 Auto-Update Script +# Checks for CS2 updates on Steam and automatically updates the server + +# Configuration +CHECK_INTERVAL=${UPDATE_CHECK_INTERVAL:-300} # Check every 5 minutes by default +user="steam" +APPID=730 # CS2 AppID +INSTALL_DIR="/home/${user}/cs2" +VERSION_FILE="${INSTALL_DIR}/.cs2_version" +LOGFILE="/tmp/cs2_autoupdate.log" + +log() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "${LOGFILE}" +} + +get_current_buildid() { + if [ -f "${VERSION_FILE}" ]; then + cat "${VERSION_FILE}" + else + echo "0" + fi +} + +get_latest_buildid() { + # Use SteamCMD to check the latest available build ID + local output=$(/steamcmd/steamcmd.sh +login anonymous +app_info_update 1 +app_info_print ${APPID} +quit 2>&1) + + # Extract buildid from the output + local buildid=$(echo "$output" | grep -A 1000 '"730"' | grep -m 1 '"buildid"' | grep -o '[0-9]*') + + if [ -z "$buildid" ]; then + log "ERROR: Could not retrieve buildid from Steam" + return 1 + fi + + echo "$buildid" +} + +update_server() { + log "Update detected! Starting CS2 server update..." + + # Run SteamCMD to update the server + sudo -u $user /steamcmd/steamcmd.sh +api_logging 1 1 +@sSteamCmdForcePlatformType linux +@sSteamCmdForcePlatformBitness 64 +force_install_dir ${INSTALL_DIR} +login anonymous +app_update ${APPID} validate +quit + + if [ $? -eq 0 ]; then + log "CS2 update completed successfully" + return 0 + else + log "ERROR: CS2 update failed" + return 1 + fi +} + +restart_server() { + log "Restarting CS2 server..." + + # Find and gracefully stop the CS2 server process + local cs2_pid=$(pgrep -f "cs2.*-dedicated") + + if [ -n "$cs2_pid" ]; then + log "Stopping CS2 server (PID: $cs2_pid)" + kill -TERM $cs2_pid + + # Wait up to 30 seconds for graceful shutdown + for i in {1..30}; do + if ! kill -0 $cs2_pid 2>/dev/null; then + log "CS2 server stopped gracefully" + break + fi + sleep 1 + done + + # Force kill if still running + if kill -0 $cs2_pid 2>/dev/null; then + log "Force stopping CS2 server" + kill -KILL $cs2_pid + fi + fi + + # The container should automatically restart the server via the CMD + log "Server will restart automatically via container CMD" +} + +main() { + log "CS2 Auto-Update service started (checking every ${CHECK_INTERVAL} seconds)" + + # Store initial version + local latest_build=$(get_latest_buildid) + if [ -n "$latest_build" ]; then + echo "$latest_build" > "${VERSION_FILE}" + log "Initial build ID: $latest_build" + fi + + while true; do + sleep ${CHECK_INTERVAL} + + local current_build=$(get_current_buildid) + local latest_build=$(get_latest_buildid) + + if [ -z "$latest_build" ]; then + log "WARNING: Could not check for updates, will retry in ${CHECK_INTERVAL} seconds" + continue + fi + + log "Current build: $current_build | Latest build: $latest_build" + + if [ "$current_build" != "$latest_build" ]; then + log "New CS2 update available! (Current: $current_build -> Latest: $latest_build)" + + if update_server; then + echo "$latest_build" > "${VERSION_FILE}" + restart_server + log "Update process completed" + else + log "Update failed, will retry on next check" + fi + else + log "No update available" + fi + done +} + +# Run main function +main diff --git a/docker-compose.yml b/docker-compose.yml index 95fe687f..bf525e5b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,6 +4,7 @@ services: container_name: cs2-modded-server env_file: - .env + restart: unless-stopped volumes: - cs2-volume:/home/steam/ - type: bind @@ -22,4 +23,4 @@ services: # command: tail -F anything volumes: - cs2-volume: \ No newline at end of file + cs2-volume: diff --git a/install_docker.sh b/install_docker.sh index 9f21a3ad..6fd14e64 100755 --- a/install_docker.sh +++ b/install_docker.sh @@ -176,6 +176,12 @@ else fi echo "Starting server on $PUBLIC_IP:$PORT" +n# Start auto-update service in background +echo "Starting CS2 auto-update service..." +sudo bash /home/cs2-modded-server/auto_update.sh > /tmp/cs2_autoupdate.log 2>&1 & +AUTO_UPDATE_PID=$! +echo "Auto-update service started with PID: $AUTO_UPDATE_PID" +echo "" # https://developer.valvesoftware.com/wiki/Counter-Strike_2/Dedicated_Servers#Command-Line_Parameters echo ./game/bin/linuxsteamrt64/cs2 \ -dedicated \