Compare commits

..

No commits in common. "032fd2aa2d744a71bffa62eaa2cb8833562c8550" and "4cfa6d653be7aaf2ed5bca6ef45c4761f121472f" have entirely different histories.

16 changed files with 516 additions and 165 deletions

19
.github/workflows/docker-image.yml vendored Normal file
View file

@ -0,0 +1,19 @@
name: Docker Image CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build the Docker image
working-directory: ./bookworm
run: docker build . --file Dockerfile --tag joedwards32/cs2:latest

69
.github/workflows/docker-publish.yml vendored Normal file
View file

@ -0,0 +1,69 @@
name: Docker Build and Publish
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
on:
schedule:
- cron: '21 5 * * 0'
push:
branches: [ "main" ]
# Publish semver tags as releases.
tags: [ 'v*.*.*' ]
pull_request:
branches: [ "main" ]
env:
# Use docker.io for Docker Hub if empty
REGISTRY: docker.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write
steps:
- name: Check out the repo
uses: actions/checkout@v4
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log in to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=semver,pattern={{version}}
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671
with:
context: ./bookworm
file: ./bookworm/Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

105
README.md
View file

@ -50,18 +50,25 @@ STEAMGUARD="" (Optional, Steam Guard key if enabled. Use your most
### Server Configuration ### Server Configuration
```dockerfile ```dockerfile
SRCDS_TOKEN="" (Game Server Token from https://steamcommunity.com/dev/managegameservers)
CS2_SERVERNAME="changeme" (Set the visible name for your private server) CS2_SERVERNAME="changeme" (Set the visible name for your private server)
CS2_IP=0.0.0.0 (CS2 server listening IP address, 0.0.0.0 - all IP addresses on the local machine, empty - IP identified automatically) CS2_CHEATS=0 (0 - disable cheats, 1 - enable cheats)
CS2_SERVER_HIBERNATE=0 (Put server in a low CPU state when there are no players.
0 - hibernation disabled, 1 - hibernation enabled
n.b. hibernation has been observed to trigger server crashes)
CS2_IP="" (CS2 server listening IP address, 0.0.0.0 - all IP addresses on the local machine, empty - IP identified automatically)
CS2_PORT=27015 (CS2 server listen port tcp_udp) CS2_PORT=27015 (CS2 server listen port tcp_udp)
CS2_RCON_PORT="" (Optional, use a simple TCP proxy to have RCON listen on an alternative port. CS2_RCON_PORT="" (Optional, use a simple TCP proxy to have RCON listen on an alternative port.
Useful for services like AWS Fargate which do not support mixed protocol ports.) Useful for services like AWS Fargate which do not support mixed protocol ports.)
CS2_LAN="0" (0 - LAN mode disabled, 1 - LAN Mode enabled) CS2_LAN="0" (0 - LAN mode disabled, 1 - LAN Mode enabled)
CS2_RCONPW="changeme" (RCON password) CS2_RCONPW="changeme" (RCON password)
CS2_PW="changeme" (CS2 server password) CS2_PW="changeme" (Optional, CS2 server password)
CS2_MAXPLAYERS=10 (Max players) CS2_MAXPLAYERS=10 (Max players)
CS2_ADDITIONAL_ARGS="" (Optional additional arguments to pass into cs2) CS2_ADDITIONAL_ARGS="" (Optional additional arguments to pass into cs2)
``` ```
**Note:** When using `CS2_RCON_PORT` don't forget to map the port chosen with TCP protocol (e.g., add `-p 27050:27050/tcp` on the `docker run` command or add the port to the `docker-compose.yml` file).
### Game Modes ### Game Modes
```dockerfile ```dockerfile
@ -69,8 +76,8 @@ CS2_GAMEALIAS="" (Game type, e.g. casual, competitive, deathmatch.
See https://developer.valvesoftware.com/wiki/Counter-Strike_2/Dedicated_Servers) See https://developer.valvesoftware.com/wiki/Counter-Strike_2/Dedicated_Servers)
CS2_GAMETYPE=0 (Used if CS2_GAMEALIAS not defined. See https://developer.valvesoftware.com/wiki/Counter-Strike_2/Dedicated_Servers) CS2_GAMETYPE=0 (Used if CS2_GAMEALIAS not defined. See https://developer.valvesoftware.com/wiki/Counter-Strike_2/Dedicated_Servers)
CS2_GAMEMODE=1 (Used if CS2_GAMEALIAS not defined. See https://developer.valvesoftware.com/wiki/Counter-Strike_2/Dedicated_Servers) CS2_GAMEMODE=1 (Used if CS2_GAMEALIAS not defined. See https://developer.valvesoftware.com/wiki/Counter-Strike_2/Dedicated_Servers)
CS2_MAPGROUP="mg_active" (Map pool) CS2_MAPGROUP="mg_active" (Map pool. Ignored if workshop maps are defined.)
CS2_STARTMAP="de_inferno" (Start map) CS2_STARTMAP="de_inferno" (Start map. Ignored if workshop maps are defined.)
``` ```
### Bots ### Bots
@ -81,6 +88,96 @@ CS2_BOT_QUOTA="" (Number of bots)
CS2_BOT_QUOTA_MODE="" (fill, competitive) CS2_BOT_QUOTA_MODE="" (fill, competitive)
``` ```
### CSTV/SourceTV
```dockerfile
TV_ENABLE=0 (0 - disable, 1 - enable)
TV_PORT=27020 (SourceTV/CSTV port to bind to)
TV_AUTORECORD=0 (Automatically record all games as CSTV demos: 0=off, 1=on)
TV_PW="changeme" (CSTV password for clients)
TV_RELAY_PW="changeme" (CSTV password for relay proxies)
TV_MAXRATE=0 (Max CSTV spectator bandwidth rate allowed, 0 == unlimited)
TV_DELAY=0 (CSTV broadcast delay in seconds)
```
### Logs
```dockerfile
CS2_LOG="on" ('on'/'off')
CS2_LOG_MONEY=0 (Turns money logging on/off: 0=off, 1=on)
CS2_LOG_DETAIL=0 (Combat damage logging: 0=disabled, 1=enemy, 2=friendly, 3=all)
CS2_LOG_ITEMS=0 (Turns item logging on/off: 0=off, 1=on)
```
### Steam Workshop
Support for Steam Workshop is experimental!
```dockerfile
CS2_HOST_WORKSHOP_MAP="" (Steam Workshop Map ID to load on server start)
CS2_HOST_WORKSHOP_COLLECTION="" (Steam Workshop Collection ID to download)
```
If a Workshop Collection is set, maps can be selected via rcon. E.g:
```
ds_workshop_listmaps
ds_workshop_changelevel $map_name
```
# Customizing this Container
## Debug Logging
If you want to increase the verbosity of log output set the `DEBUG` environment variable:
```dockerfile
DEBUG=0 (0=none, 1=steamcmd, 2=cs2, 3=all)
```
## Validating Game Files
If you break the game through your customisations and want steamcmd to validate and redownload then set the `STEAMAPPVALIDATE` environment variable to `1`:
```dockerfile
STEAMAPPVALIDATE=0 (0=skip validation, 1=validate game files)
```
## Pre and Post Hooks
The container includes two scripts for executing custom actions:
* `/home/steam/cs2-dedicated/pre.sh` is executed before the CS2 server starts
* `/home/steam/cs2-dedicated/post.sh` is executed after the CS2 server stops
When using a persient volume mounted at `/home/steam/cs2-dedicated/` you may edit these scripts to perform custom actions, such as enabling metamod.
Alternatively, you may have docker mount files from outside the container to override these files. E.g.:
```
-v /path/to/pre.sh:/home/steam/cs2-dedicated/pre.sh
```
## Overriding Game Mode Defaults
The default configurations for each game mode are stored in `/home/steam/cs2-dedicated/game/csgo/cfg/`. For example, the Competitive mode defaults are set by `gamemode_competitive.cfg`.
When using a persistent volume mounted at `/home/steam/cs2-dedicated/`, these defaults can be overridden by adding your own settings to `gamemode_competitive_server.cfg`.
```
// Game Mode Competitive Server Overrides
mp_maxrounds 16 // Shorter games
```
## Customisation Bundle
The container can be instructed to download a extract a Tar Gzip bundle, Tar or Zip archive of configuration files and other customisations from a given URL.
```dockerfile
CS2_CFG_URL="" (HTTP/HTTPS URL to fetch a Tar Gzip bundle, Tar or Zip archive of configuration files/mods)
```
# Credits # Credits
This container leans heavily on the work of [CM2Walki](https://github.com/CM2Walki/), especially his [SteamCMD](https://github.com/CM2Walki/steamcmd) container image. GG! This container leans heavily on the work of [CM2Walki](https://github.com/CM2Walki/), especially his [SteamCMD](https://github.com/CM2Walki/steamcmd) container image. GG!

View file

@ -4,7 +4,7 @@
# BUILD STAGE # BUILD STAGE
FROM cm2network/steamcmd:root as build_stage FROM cm2network/steamcmd:root-bookworm as build_stage
LABEL maintainer="astra@zio.sh" LABEL maintainer="astra@zio.sh"
@ -20,39 +20,39 @@ COPY etc/post.sh "/etc/post.sh"
RUN set -x \ RUN set -x \
# Install, update & upgrade packages # Install, update & upgrade packages
&& dpkg --add-architecture i386 \ && dpkg --add-architecture i386 \
&& apt-get update \ && apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \ && apt-get install -y --no-install-recommends --no-install-suggests \
libcurl4:i386 \ libcurl4:i386 \
wget \ wget \
ca-certificates \ ca-certificates \
lib32z1 \ lib32z1 \
simpleproxy \ simpleproxy \
libicu-dev \ libicu-dev \
unzip \ unzip \
patch \ jq \
patch \
&& mkdir -p "${STEAMAPPDIR}" \ && mkdir -p "${STEAMAPPDIR}" \
# Add entry script # Add entry script
&& chmod +x "${HOMEDIR}/entry.sh" \ && chmod +x "${HOMEDIR}/entry.sh" \
&& chown -R "${USER}:${USER}" "${HOMEDIR}/entry.sh" "${STEAMAPPDIR}" \ && chown -R "${USER}:${USER}" "${HOMEDIR}/entry.sh" "${STEAMAPPDIR}" \
&& chmod +x /etc/post.sh /etc/pre.sh \ && chmod +x /etc/post.sh /etc/pre.sh \
# Clean up # Clean up
&& apt-get clean \ && apt-get clean \
&& find /var/lib/apt/lists/ -type f -delete && find /var/lib/apt/lists/ -type f -delete
# BASE # BASE
FROM build_stage AS bullseye-base FROM build_stage AS bookworm-base
ENV CS2_SERVERNAME="cs2 private server" \ ENV CS2_SERVERNAME="cs2 private server" \
CS2_CHEATS=0 \
CS2_IP=0.0.0.0 \ CS2_IP=0.0.0.0 \
CS2_PORT=27015 \
CS2_SERVER_HIBERNATE=0 \ CS2_SERVER_HIBERNATE=0 \
CS2_PORT=27015 \
CS2_RCON_PORT="" \ CS2_RCON_PORT="" \
CS2_MAXPLAYERS=10 \ CS2_MAXPLAYERS=10 \
CS2_CHEATS=0 \
CS2_RCONPW="changeme" \ CS2_RCONPW="changeme" \
CS2_PW="changeme" \
CS2_MAPGROUP="mg_active" \ CS2_MAPGROUP="mg_active" \
CS2_STARTMAP="de_inferno" \ CS2_STARTMAP="de_inferno" \
CS2_GAMEALIAS="" \ CS2_GAMEALIAS="" \
@ -61,12 +61,17 @@ ENV CS2_SERVERNAME="cs2 private server" \
CS2_LAN=0 \ CS2_LAN=0 \
TV_AUTORECORD=0 \ TV_AUTORECORD=0 \
TV_ENABLE=0 \ TV_ENABLE=0 \
TV_PW="changeme" \
TV_PORT=27020 \ TV_PORT=27020 \
TV_PW="changeme" \
TV_RELAY_PW="changeme" \ TV_RELAY_PW="changeme" \
TV_MAXRATE=0 \ TV_MAXRATE=0 \
TV_DELAY=0 \ TV_DELAY=0 \
SRCDS_TOKEN="" \ SRCDS_TOKEN="" \
CS2_CFG_URL="" \
CS2_LOG="on" \
CS2_LOG_MONEY=0 \
CS2_LOG_DETAIL=0 \
CS2_LOG_ITEMS=0 \
CS2_ADDITIONAL_ARGS="" CS2_ADDITIONAL_ARGS=""
# Set permissions on STEAMAPPDIR # Set permissions on STEAMAPPDIR

202
bookworm/etc/entry.sh Normal file
View file

@ -0,0 +1,202 @@
#!/bin/bash
# Debug
## Steamcmd debugging
if [[ $DEBUG -eq 1 ]] || [[ $DEBUG -eq 3 ]]; then
STEAMCMD_SPEW="+set_spew_level 4 4"
fi
## CS2 server debugging
if [[ $DEBUG -eq 2 ]] || [[ $DEBUG -eq 3 ]]; then
CS2_LOG="on"
CS2_LOG_MONEY=1
CS2_LOG_DETAIL=3
CS2_LOG_ITEMS=1
fi
# Create App Dir
mkdir -p "${STEAMAPPDIR}" || true
# Download Updates
if [[ "$STEAMAPPVALIDATE" -eq 1 ]]; then
VALIDATE="validate"
else
VALIDATE=""
fi
## SteamCMD can fail to download
## Retry logic
MAX_ATTEMPTS=3
attempt=0
while [[ $steamcmd_rc != 0 ]] && [[ $attempt -lt $MAX_ATTEMPTS ]]; do
((attempt+=1))
if [[ $attempt -gt 1 ]]; then
echo "Retrying SteamCMD, attempt ${attempt}"
# Stale appmanifest data can lead for HTTP 401 errors when requesting old
# files from SteamPipe CDN
echo "Removing steamapps (appmanifest data)..."
rm -rf "${STEAMAPPDIR}/steamapps"
fi
eval bash "${STEAMCMDDIR}/steamcmd.sh" "${STEAMCMD_SPEW}"\
+force_install_dir "${STEAMAPPDIR}" \
+@bClientTryRequestManifestWithoutCode 1 \
+login anonymous \
+app_update "${STEAMAPPID}" "${VALIDATE}"\
+quit
steamcmd_rc=$?
done
## Exit if steamcmd fails
if [[ $steamcmd_rc != 0 ]]; then
exit $steamcmd_rc
fi
# steamclient.so fix
mkdir -p ~/.steam/sdk64
ln -sfT ${STEAMCMDDIR}/linux64/steamclient.so ~/.steam/sdk64/steamclient.so
# Install server.cfg
mkdir -p $STEAMAPPDIR/game/csgo/cfg
cp /etc/server.cfg "${STEAMAPPDIR}"/game/csgo/cfg/server.cfg
# Install hooks if they don't already exist
if [[ ! -f "${STEAMAPPDIR}/pre.sh" ]] ; then
cp /etc/pre.sh "${STEAMAPPDIR}/pre.sh"
fi
if [[ ! -f "${STEAMAPPDIR}/post.sh" ]] ; then
cp /etc/post.sh "${STEAMAPPDIR}/post.sh"
fi
# Download and extract custom config bundle
if [[ ! -z $CS2_CFG_URL ]]; then
echo "Downloading config pack from ${CS2_CFG_URL}"
TEMP_DIR=$(mktemp -d)
TEMP_FILE="${TEMP_DIR}/$(basename ${CS2_CFG_URL})"
wget -qO "${TEMP_FILE}" "${CS2_CFG_URL}"
case "${TEMP_FILE}" in
*.zip)
echo "Extracting ZIP file..."
unzip -q "${TEMP_FILE}" -d "${STEAMAPPDIR}"
;;
*.tar.gz | *.tgz)
echo "Extracting TAR.GZ or TGZ file..."
tar xvzf "${TEMP_FILE}" -C "${STEAMAPPDIR}"
;;
*.tar)
echo "Extracting TAR file..."
tar xvf "${TEMP_FILE}" -C "${STEAMAPPDIR}"
;;
*)
echo "Unsupported file type"
rm -rf "${TEMP_DIR}"
exit 1
;;
esac
rm -rf "${TEMP_DIR}"
fi
# Rewrite Config Files
sed -r -i -e "s/^(hostname) .*/\1 ${CS2_SERVERNAME}/g" \
-e "s/^(sv_cheats) .*/\1 ${CS2_CHEATS}/g" \
-e "s/^(sv_hibernate_when_empty) .*/\1 ${CS2_SERVER_HIBERNATE}/g" \
-e "s/^(sv_password) .*/\1 ${CS2_PW}/g" \
-e "s/^(rcon_password) .*/\1 ${CS2_RCONPW}/g" \
-e "s/^(tv_enable) .*/\1 ${TV_ENABLE}/g" \
-e "s/^(tv_port) .*/\1 ${TV_PORT}/g" \
-e "s/^(tv_autorecord) .*/\1 ${TV_AUTORECORD}/g" \
-e "s/^(tv_password) .*/\1 ${TV_PW}/g" \
-e "s/^(tv_relaypassword) .*/\1 ${TV_RELAY_PW}/g" \
-e "s/^(tv_maxrate) .*/\1 ${TV_MAXRATE}/g" \
-e "s/^(tv_delay) .*/\1 ${TV_DELAY}/g" \
-e "s/^(tv_name) .*/\1 ${CS2_SERVERNAME} CSTV/g" \
-e "s/^(tv_title) .*/\1${CS2_SERVERNAME} CSTV/g" \
"${STEAMAPPDIR}"/game/csgo/cfg/server.cfg
if [[ ! -z $CS2_BOT_DIFFICULTY ]] ; then
sed -r -i "s/^(bot_difficulty) .*/\1 ${CS2_BOT_DIFFICULTY}/" "${STEAMAPPDIR}"/game/csgo/cfg/*
fi
if [[ ! -z $CS2_BOT_QUOTA ]] ; then
sed -r -i "s/^(bot_quota) .*/\1 ${CS2_BOT_QUOTA}/" "${STEAMAPPDIR}"/game/csgo/cfg/*
fi
if [[ ! -z $CS2_BOT_QUOTA_MODE ]] ; then
sed -r -i "s/^(bot_quota_mode) .*/\1 ${CS2_BOT_QUOTA_MODE}/" "${STEAMAPPDIR}"/game/csgo/cfg/*
fi
# Switch to server directory
cd "${STEAMAPPDIR}/game/bin/linuxsteamrt64"
# Pre Hook
source "${STEAMAPPDIR}/pre.sh"
# Construct server arguments
if [[ -z $CS2_GAMEALIAS ]]; then
# If CS2_GAMEALIAS is undefined then default to CS2_GAMETYPE and CS2_GAMEMODE
CS2_GAME_MODE_ARGS="+game_type ${CS2_GAMETYPE} +game_mode ${CS2_GAMEMODE}"
else
# Else, use alias to determine game mode
CS2_GAME_MODE_ARGS="+game_alias ${CS2_GAMEALIAS}"
fi
if [[ -z $CS2_IP ]]; then
CS2_IP_ARGS=""
else
CS2_IP_ARGS="-ip ${CS2_IP}"
fi
if [[ ! -z $SRCDS_TOKEN ]]; then
SV_SETSTEAMACCOUNT_ARGS="+sv_setsteamaccount ${SRCDS_TOKEN}"
fi
if [[ ! -z $CS2_HOST_WORKSHOP_COLLECTION ]] || [[ ! -z $CS2_HOST_WORKSHOP_MAP ]]; then
CS2_MP_MATCH_END_CHANGELEVEL="+mp_match_end_changelevel true" # https://github.com/joedwards32/CS2/issues/57#issuecomment-2245595368
CS2_STARTMAP="\<empty\>" # https://github.com/joedwards32/CS2/issues/57#issuecomment-2245595368
CS2_MAPGROUP_ARGS=
else
CS2_MAPGROUP_ARGS="+mapgroup ${CS2_MAPGROUP}"
fi
if [[ ! -z $CS2_HOST_WORKSHOP_COLLECTION ]]; then
CS2_HOST_WORKSHOP_COLLECTION_ARGS="+host_workshop_collection ${CS2_HOST_WORKSHOP_COLLECTION}"
fi
if [[ ! -z $CS2_HOST_WORKSHOP_MAP ]]; then
CS2_HOST_WORKSHOP_MAP_ARGS="+host_workshop_map ${CS2_HOST_WORKSHOP_MAP}"
fi
if [[ ! -z $CS2_PW ]]; then
CS2_PW_ARGS="+sv_password ${CS2_PW}"
fi
# Start Server
if [[ ! -z $CS2_RCON_PORT ]]; then
echo "Establishing Simpleproxy for ${CS2_RCON_PORT} to 127.0.0.1:${CS2_PORT}"
simpleproxy -L "${CS2_RCON_PORT}" -R 127.0.0.1:"${CS2_PORT}" &
fi
echo "Starting CS2 Dedicated Server"
eval "./cs2" -dedicated \
"${CS2_IP_ARGS}" -port "${CS2_PORT}" \
-console \
-usercon \
-maxplayers "${CS2_MAXPLAYERS}" \
"${CS2_GAME_MODE_ARGS}" \
"${CS2_MAPGROUP_ARGS}" \
+map "${CS2_STARTMAP}" \
"${CS2_HOST_WORKSHOP_COLLECTION_ARGS}" \
"${CS2_HOST_WORKSHOP_MAP_ARGS}" \
"${CS2_MP_MATCH_END_CHANGELEVEL}" \
+rcon_password "${CS2_RCONPW}" \
"${SV_SETSTEAMACCOUNT_ARGS}" \
"${CS2_PW_ARGS}" \
+sv_lan "${CS2_LAN}" \
+tv_port "${TV_PORT}" \
"${CS2_ADDITIONAL_ARGS}"
# Post Hook
source "${STEAMAPPDIR}/post.sh"

2
bullseye/etc/post.sh → bookworm/etc/post.sh Normal file → Executable file
View file

@ -2,4 +2,4 @@
# POST HOOK # POST HOOK
# Make your customisation here # Make your customisation here
echo "post-hook: noop" echo "post-hook: noop"

2
bullseye/etc/pre.sh → bookworm/etc/pre.sh Normal file → Executable file
View file

@ -2,4 +2,4 @@
# PRE HOOK # PRE HOOK
# Make your customisation here # Make your customisation here
echo "pre-hook: noop" echo "pre-hook: noop"

44
bookworm/etc/server.cfg Normal file
View file

@ -0,0 +1,44 @@
// Server Defaults
hostname "{{SERVER_HOSTNAME}}" // Set server hostname
sv_cheats {{SERVER_CHEATS}} // Enable or disable cheats
sv_hibernate_when_empty {{SERVER_HIBERNATE}} // Disable server hibernation
// Passwords
rcon_password "{{SERVER_RCON_PW}}" // Set rcon password
sv_password "{{SERVER_PW}}" // Set server password
// CSTV
sv_hibernate_postgame_delay 30 // Delay server hibernation after all clients disconnect
tv_allow_camera_man 1 // Auto director allows spectators to become camera man
tv_allow_static_shots 1 // Auto director uses fixed level cameras for shots
tv_autorecord {{TV_AUTORECORD}} // Automatically records all games as CSTV demos: 0=off, 1=on.
tv_chatgroupsize 0 // Set the default chat group size
tv_chattimelimit 8 // Limits spectators to chat only every n seconds
tv_debug 0 // CSTV debug info.
tv_delay {{TV_DELAY}} // CSTV broadcast delay in seconds
tv_delaymapchange 1 // Delays map change until broadcast is complete
tv_deltacache 2 // Enable delta entity bit stream cache
tv_dispatchmode 1 // Dispatch clients to relay proxies: 0=never, 1=if appropriate, 2=always
tv_enable {{TV_ENABLE}} // Activates CSTV on server: 0=off, 1=on.
tv_maxclients 10 // Maximum client number on CSTV server.
tv_maxrate {{TV_MAXRATE}} // Max CSTV spectator bandwidth rate allowed, 0 == unlimited
tv_name "{{SERVER_HOSTNAME}} CSTV" // CSTV host name
tv_overridemaster 0 // Overrides the CSTV master root address.
tv_port {{TV_PORT}} // Host SourceTV port
tv_password "{{TV_PW}}" // CSTV password for clients
tv_relaypassword "{{TV_RELAY_PW}}" // CSTV password for relay proxies
tv_relayvoice 1 // Relay voice data: 0=off, 1=on
tv_timeout 60 // CSTV connection timeout in seconds.
tv_title "{{SERVER_HOSTNAME}} CSTV" // Set title for CSTV spectator UI
tv_transmitall 1 // Transmit all entities (not only director view)
// Logs
log {{SERVER_LOG}} // Turns logging 'on' or 'off', defaults to 'on'
mp_logmoney {{SERVER_LOG_MONEY}} // Turns money logging on/off: 0=off, 1=on
mp_logdetail {{SERVER_LOG_DETAIL}} // Combat damage logging: 0=disabled, 1=enemy, 2=friendly, 3=all
mp_logdetail_items {{SERVER_LOG_ITEMS}} // Turns item logging on/off: 0=off, 1=on

View file

@ -2,4 +2,4 @@
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
docker build --target=bullseye-base -t $DOCKER_REPO:latest -t $DOCKER_REPO:base ${SCRIPT_DIR}/.. docker build --target=bookworm-base -t $DOCKER_REPO:latest -t $DOCKER_REPO:base ${SCRIPT_DIR}/..

2
bookworm/hooks/push Normal file
View file

@ -0,0 +1,2 @@
#!/bin/bash
docker push --all-tags ${DOCKER_REPO}

View file

@ -1,104 +0,0 @@
#!/bin/bash
mkdir -p "${STEAMAPPDIR}" || true
if [[ "$STEAMAPPVALIDATE" -eq 1 ]]; then
VALIDATE="validate"
else
VALIDATE=""
fi
# Download Updates
bash "${STEAMCMDDIR}/steamcmd.sh" +force_install_dir "${STEAMAPPDIR}" \
+login anonymous \
+app_update "${STEAMAPPID}" "${VALIDATE}" \
+quit
# steamclient.so fix
mkdir -p ~/.steam/sdk64
ln -sfT ${STEAMCMDDIR}/linux64/steamclient.so ~/.steam/sdk64/steamclient.so
# Install server.cfg
cp /etc/server.cfg "${STEAMAPPDIR}"/game/csgo/cfg/server.cfg
sed -r -i -e "s/^(hostname) .*/\1 ${CS2_SERVERNAME}/g" \
-e "s/^(sv_cheats) .*/\1 ${CS2_CHEATS}/g" \
-e "s/^(sv_hibernate_when_empty) .*/\1 ${CS2_SERVER_HIBERNATE}/g" \
-e "s/^(sv_password) .*/\1 ${CS2_PW}/g" \
-e "s/^(rcon_password) .*/\1 ${CS2_RCONPW}/g" \
-e "s/^(tv_enable) .*/\1 ${TV_ENABLE}/g" \
-e "s/^(tv_port) .*/\1 ${TV_PORT}/g" \
-e "s/^(tv_autorecord) .*/\1 ${TV_AUTORECORD}/g" \
-e "s/^(tv_password) .*/\1 ${TV_PW}/g" \
-e "s/^(tv_relaypassword) .*/\1 ${TV_RELAY_PW}/g" \
-e "s/^(tv_maxrate) .*/\1 ${TV_MAXRATE}/g" \
-e "s/^(tv_delay) .*/\1 ${TV_DELAY}/g" \
-e "s/^(tv_name) .*/\1 ${CS2_SERVERNAME} CSTV/g" \
-e "s/^(tv_title) .*/\1${CS2_SERVERNAME} CSTV/g" \
"${STEAMAPPDIR}"/game/csgo/cfg/server.cfg
# Install hooks
if [[ ! -f "${STEAMAPPDIR}/pre.sh" ]] ; then
cp /etc/pre.sh "${STEAMAPPDIR}/pre.sh"
fi
if [[ ! -f "${STEAMAPPDIR}/post.sh" ]] ; then
cp /etc/post.sh "${STEAMAPPDIR}/post.sh"
fi
# Rewrite Config Files
if [[ ! -z $CS2_BOT_DIFFICULTY ]] ; then
sed -r -i "s/^(bot_difficulty) .*/\1 ${CS2_BOT_DIFFICULTY}/" "${STEAMAPPDIR}"/game/csgo/cfg/*
fi
if [[ ! -z $CS2_BOT_QUOTA ]] ; then
sed -r -i "s/^(bot_quota) .*/\1 ${CS2_BOT_QUOTA}/" "${STEAMAPPDIR}"/game/csgo/cfg/*
fi
if [[ ! -z $CS2_BOT_QUOTA_MODE ]] ; then
sed -r -i "s/^(bot_quota_mode) .*/\1 ${CS2_BOT_QUOTA_MODE}/" "${STEAMAPPDIR}"/game/csgo/cfg/*
fi
# Switch to server directory
cd "${STEAMAPPDIR}/game/bin/linuxsteamrt64"
# Pre Hook
bash "${STEAMAPPDIR}/pre.sh"
# Construct server arguments
if [[ -z $CS2_GAMEALIAS ]]; then
# If CS2_GAMEALIAS is undefined then default to CS2_GAMETYPE and CS2_GAMEMODE
CS2_GAME_MODE_ARGS="+game_type ${CS2_GAMETYPE} +game_mode ${CS2_GAMEMODE}"
else
# Else, use alias to determine game mode
CS2_GAME_MODE_ARGS="+game_alias ${CS2_GAMEALIAS}"
fi
if [[ -z $CS2_IP ]]; then
CS2_IP_ARGS=""
else
CS2_IP_ARGS="-ip ${CS2_IP}"
fi
if [[ ! -z $SRCDS_TOKEN ]]; then
SV_SETSTEAMACCOUNT_ARGS="+sv_setsteamaccount ${SRCDS_TOKEN}"
fi
# Start Server
if [[ ! -z $CS2_RCON_PORT ]]; then
echo "Establishing Simpleproxy for ${CS2_RCON_PORT} to 127.0.0.1:${CS2_PORT}"
simpleproxy -L "${CS2_RCON_PORT}" -R 127.0.0.1:"${CS2_PORT}" &
fi
eval "./cs2" -dedicated \
"${CS2_IP_ARGS}" -port "${CS2_PORT}" \
-console \
-usercon \
-maxplayers "${CS2_MAXPLAYERS}" \
"${CS2_GAME_MODE_ARGS}" \
+mapgroup "${CS2_MAPGROUP}" \
+map "${CS2_STARTMAP}" \
+rcon_password "${CS2_RCONPW}" \
"${SV_SETSTEAMACCOUNT_ARGS}" \
+sv_password "${CS2_PW}" \
+sv_lan "${CS2_LAN}" \
"${CS2_ADDITIONAL_ARGS}"
# Post Hook
bash "${STEAMAPPDIR}/post.sh"

View file

@ -1,37 +0,0 @@
// Server Defaults
hostname "changeme" // Set server hostname
sv_cheats 0 // Enable or disable cheats
sv_hibernate_when_empty 0 // Disable server hibernation
// Passwords
rcon_password "changeme" // Set rcon password
sv_password "changeme" // Set server password
// CSTV
sv_hibernate_postgame_delay 30 // Delay server hibernation after all clients disconnect
tv_allow_camera_man 1 // Auto director allows spectators to become camera man
tv_allow_static_shots 1 // Auto director uses fixed level cameras for shots
tv_autorecord 0 // Automatically records all games as CSTV demos: 0=off, 1=on.
tv_chatgroupsize 0 // Set the default chat group size
tv_chattimelimit 8 // Limits spectators to chat only every n seconds
tv_debug 0 // CSTV debug info.
tv_delay 30 // CSTV broadcast delay in seconds
tv_delaymapchange 1 // Delays map change until broadcast is complete
tv_deltacache 2 // Enable delta entity bit stream cache
tv_dispatchmode 1 // Dispatch clients to relay proxies: 0=never, 1=if appropriate, 2=always
tv_enable 0 // Activates CSTV on server: 0=off, 1=on.
tv_maxclients 10 // Maximum client number on CSTV server.
tv_maxrate 20000 // Max CSTV spectator bandwidth rate allowed, 0 == unlimited
tv_name "changeme" // CSTV host name
tv_overridemaster 0 // Overrides the CSTV master root address.
tv_port 0 // Host SourceTV port
tv_password "changeme" // CSTV password for clients
tv_relaypassword "changeme" // CSTV password for relay proxies
tv_relayvoice 1 // Relay voice data: 0=off, 1=on
tv_timeout 60 // CSTV connection timeout in seconds.
tv_title "changeme" // Set title for CSTV spectator UI
tv_transmitall 1 // Transmit all entities (not only director view)

View file

@ -1,2 +0,0 @@
#!/bin/bash
docker push --all-tags ${DOCKER_REPO}

BIN
examples/cs2.cfg.tgz Normal file

Binary file not shown.

View file

@ -0,0 +1,56 @@
services:
cs2-server:
image: joedwards32/cs2
container_name: cs2-dedicated
environment:
# Server configuration
- SRCDS_TOKEN # Game Server Token from https://steamcommunity.com/dev/managegameservers
- DEBUG=0 # (0 - off, 1 - steamcmd, 2 - cs2, 3 - all)
- STEAMAPPVALIDATE=0 # (0 - no validation, 1 - enable validation)
- CS2_SERVERNAME=changeme # (Set the visible name for your private server)
- CS2_CHEATS=0 # (0 - disable cheats, 1 - enable cheats)
- CS2_PORT=27015 # (CS2 server listen port tcp_udp)
- CS2_SERVER_HIBERNATE=0 # (Put server in a low CPU state when there are no players. 0 - hibernation disabled, 1 - hibernation enabled)
- CS2_RCON_PORT # (Optional, use a simple TCP proxy to have RCON listen on an alternative port. Useful for services like AWS Fargate which do not support mixed protocol ports.)
- CS2_LAN=0 # (0 - LAN mode disabled, 1 - LAN Mode enabled)
- CS2_RCONPW=changeme # (RCON password)
- CS2_PW # (Optional, CS2 server password)
- CS2_MAXPLAYERS=10 # (Max players)
- CS2_ADDITIONAL_ARGS # (Optional additional arguments to pass into cs2)
- CS2_CFG_URL # HTTP/HTTPS URL to fetch a Tar Gzip bundle, Tar or Zip archive of configuration files/mods
# Game modes
- CS2_GAMEALIAS # (Game type, e.g. casual, competitive, deathmatch. See https://developer.valvesoftware.com/wiki/Counter-Strike_2/Dedicated_Servers)
- CS2_GAMETYPE=0 # (Used if CS2_GAMEALIAS not defined. See https://developer.valvesoftware.com/wiki/Counter-Strike_2/Dedicated_Servers)
- CS2_GAMEMODE=1 # (Used if CS2_GAMEALIAS not defined. See https://developer.valvesoftware.com/wiki/Counter-Strike_2/Dedicated_Servers)
- CS2_MAPGROUP=mg_active # (Map pool. Ignored if Workshop maps are defined.)
- CS2_STARTMAP=de_inferno # (Start map. Ignored if Workshop maps are defined.)
# Workshop Maps
- CS2_HOST_WORKSHOP_COLLECTION # The workshop collection to use
- CS2_HOST_WORKSHOP_MAP # The workshop map to use. If collection is also defined, this is the starting map.
# Bots
- CS2_BOT_DIFFICULTY # (0 - easy, 1 - normal, 2 - hard, 3 - expert)
- CS2_BOT_QUOTA # (Number of bots)
- CS2_BOT_QUOTA_MODE # (fill, competitive)
# TV
- TV_AUTORECORD=0 # Automatically records all games as CSTV demos: 0=off, 1=on.
- TV_ENABLE=0 # Activates CSTV on server: 0=off, 1=on.
- TV_PORT=27020 # Host SourceTV port
- TV_PW=changeme # CSTV password for clients
- TV_RELAY_PW=changeme # CSTV password for relay proxies
- TV_MAXRATE=0 # World snapshots to broadcast per second. Affects camera tickrate.
- TV_DELAY=0 # CSTV broadcast delay in seconds
# Logs
- CS2_LOG=on # 'on'/'off'
- CS2_LOG_MONEY=0 # Turns money logging on/off: (0=off, 1=on)
- CS2_LOG_DETAIL=0 # Combat damage logging: (0=disabled, 1=enemy, 2=friendly, 3=all)
- CS2_LOG_ITEMS=0 # Turns item logging on/off: (0=off, 1=on)
volumes:
- cs2:/home/steam/cs2-dedicated/ # Persistent data volume mount point inside container
ports:
- "27015:27015/tcp" # TCP
- "27015:27015/udp" # UDP
- "27020:27020/udp" # UDP
stdin_open: true # Add local console for docker attach, docker attach --sig-proxy=false cs2-dedicated
tty: true # Add local console for docker attach, docker attach --sig-proxy=false cs2-dedicated
volumes:
cs2: