Skip to content

DOCKER DECDICATED CSGO SERVER

Getting a dedicated server up and going isn't terribly difficult.  But to make it that much easier, here is how to do it (RHEL 7 focus, change to suit your distro of choice).  One thing you will see is I love the bash script.  Automation reliably is great.  These are my friends.  Once created, or copied and pasted, a lot of the grunt work is taken care of.

Quick inventory of scripts:

  • dockerfile
  • steamcmd installer
  • CSGO Server Start
  • CSGO Container Start

PREPARATION

First, as one should be aware (you are now if not), docker images don't keep data from start -> stop -> start.  So that's where volumes come into play.  I have an NFS server that doles out the data for all my servers so I have that mounted and being passed in.  You can change this as it suits your needs.  In my case /storage/docker is an NFS mount.  I have each container design in its own directory.   That works rather well, as it makes manipulating data a bit easier as I can mount this on my workstation to make edits, changes, unpack tarballs, etc.

  • There is a user created in the dockerfile called 'steam'.   This user has rwx rights on the files from the volume mounted in from below.
  • My volume gets mounted in the container as /home/steam/Steam.  This makes the need for forcing the install moot.
  • There are a ton of ports we need to open on the firewall and router.

CS:GO Ports:

  • DP 27000 to 27015 inclusive (Game client traffic)
  • UDP 27015 to 27030 inclusive (Typically Matchmaking and HLTV)
  • TCP 27014 to 27050 inclusive (Steam downloads)
  • UDP 4380
  • TCP 27015 (SRCDS Rcon port)
  • UDP 3478 (Outbound Steamworks P2P Networking and Steam Voice Chat)
  • UDP 4379 (Outbound Steamworks P2P Networking and Steam Voice Chat)
  • UDP 4380 (Outbound)Steamworks P2P Networking and Steam Voice Chat

We need to prep things before we can actually execute the server script.  But first we will get the other stuff taken care of so we can prep, then update, then start.

DOCKERFILE

My dockerfile is as follows:

FROM rhel:latest

RUN yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm && yum -y update && yum -y install glibc libstdc++ glibc.i686 libstdc++.i686 vim wget curl tmux

RUN useradd steam

USER steam
ENV HOME /home/steam
CMD /bin/bash

Build it:

docker build -t steam .

We can actually reuse this container format for any other Steam title.  I do this for Starbound and Starmade servers (eventually Ark too).  Remember with docker, we want to go generic so the container could be launched in more scenarios, and to keep the package list short to avoid problems with security, file space consumed, and update time (rebuilding basically).

LAUNCH MENU SCRIPT

For starting up the server I created a script called start_server.sh put inside the volume at /home/steam/Steam :

#!/bin/bash
#CS:GO Dedicated Server Menu
trap '' 2 ##Disable CTL-C
QUIT=0 ##Looping variable. When set to !0 the loop will break.

while [ $QUIT == 0 ] ; do

cd "/home/steam/Steam/steamapps/common/Counter-Strike Global Offensive Beta - Dedicated Server"

reset
clear

echo "Welcome to the Schotty.com Counter Strike Global Offensive Dedicated Server!"
echo && echo
echo "To change gamemodes type quit in the CSGO console"
echo
echo "The Quit option below will terminate the container"

PASSWORD=$(grep sv_password ~/Steam/steamapps/common/Counter-Strike\ Global\ Offensive\ Beta\ -\ Dedicated\ Server/csgo/cfg/autoexec.cfg | grep -oP '(sv_password )\K.*')
echo
echo "The server password will be : $PASSWORD"
echo && echo

PS3='Please enter gamemode to start: '

modes=("Classic Casual" "Classic Competitive" "Arms Race" "Demolition" "Deathmatch" "Update CSGO" "Quit")

select opt in "${modes[@]}"
do
case $opt in
"Classic Casual")
cd "/home/steam/Steam/steamapps/common/Counter-Strike Global Offensive Beta - Dedicated Server"
./srcds_run -game csgo -console -usercon +game_type 0 +game_mode 0 +mapgroup mg_active +map de_dust2
break
;;
"Classic Competitive")
cd "/home/steam/Steam/steamapps/common/Counter-Strike Global Offensive Beta - Dedicated Server"
./srcds_run -game csgo -console -usercon +game_type 0 +game_mode 1 +mapgroup mg_active +map de_dust2
break
;;
"Arms Race")
cd "/home/steam/Steam/steamapps/common/Counter-Strike Global Offensive Beta - Dedicated Server"
./srcds_run -game csgo -console -usercon +game_type 1 +game_mode 0 +mapgroup mg_armsrace +map ar_shoots
break
;;
"Demolition")
cd "/home/steam/Steam/steamapps/common/Counter-Strike Global Offensive Beta - Dedicated Server"
./srcds_run -game csgo -console -usercon +game_type 1 +game_mode 1 +mapgroup mg_demolition +map de_lake
break
;;
"Deathmatch")
cd "/home/steam/Steam/steamapps/common/Counter-Strike Global Offensive Beta - Dedicated Server"
./srcds_run -game csgo -console -usercon +game_type 1 +game_mode 2 +mapgroup mg_allclassic +map de_dust
break
;;
"Update CSGO")
cd "/home/steam/Steam/"
sh ./csgo_update.sh
break
;;
"Quit")
let QUIT=1
break
;;
*) echo Invalid option. Please choose again.;;
esac
done
done

CSGO UPDATE SCRIPT

Here is a very simple updater script that I use for updating CSGO:

#!/bin/bash
cd /home/steam/Steam
./steamcmd.sh +login anonymous +app_update 740 +quit

CONTAINER STARTUP SCRIPT

Finally we can now do the startup script.

Server start:

#!/bin/bash
docker run -ti --rm\
           --sig-proxy=false\
           --privileged=true\
           -p=27000-27014:27000-27014/udp\
           -p=27015-27030:27015-27030/udp\
           -p=27014-27050:27014-27050\
           -p=4380:4380/udp\
           -p=3478:3478/udp\
           -p=4379:4379/udp\
           -p=1500:1500/udp\
           -p=3005:3005/udp\
           -p=3101:3101/udp\
           -p=28960:28960/udp\
           -m=1g\
           -v /storage/docker/steamcmd/csgo:/home/steam/Steam\
           --name=CSGO\
           -w=/home/steam/Steam\
           steam:latest\
           /bin/bash /home/steam/Steam/start_server.sh

PREPPING YOUR VOLUME

OK, now we got the meat of the work done, we have to start the container in a special way.  We will not have to do this unless we need to reload steamcmd for some odd reason.  Things happen, so we will make this a script too, just in case.

Volume Preparation Script (note that I did use a different name for this container):

#!/bin/bash
 docker run -ti --rm --sig-proxy=false --privileged=true\
            -p=27000-27014:27000-27014/udp\
            -p=27015-27030:27015-27030/udp\
            -p=27014-27050:27014-27050\
            -p=4380:4380/udp\
            -p=3478:3478/udp\
            -p=4379:4379/udp\
            -p=1500:1500/udp\
            -p=3005:3005/udp\
            -p=3101:3101/udp\
            -p=28960:28960/udp\
            -m=1g\
            -v /storage/docker/steamcmd/csgo:/home/steam/Steam\
            --name=CSGO_steamcmd\
            -w=/home/steam/Steam\
            steam:latest\
            /bin/bash

Ok we need to run this script and then start the following.  Keep in mind that the root directory of the volume getting passed in will be where a lot of our stuff gets dumped into.

First we need to pull in the steamcmd files.  Save this as get_steamcmd.sh

#!/bin//bash
cd /home/steam/Steam
curl -O https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz
tar -xvzf steamcmd_linux.tar.gz

Now we have what we need to get off the ground.  We could have done this manually, but why not script this so we can hit the fix-me button if something gets hosed?

Now we run the Server Update script from above.  This should start the container, update CSGO and quit out.

SERVER CONFIG (BRIEF OVERVIEW)

OK, now that we are here, we can configure the server.
Edit:

  • /home/steam/Steam/steamapps/common/Counter-Strike\ Global\ Offensive\ Beta\ -\ Dedicated\ Server/csgo/cfg/autoexec.cfg  Take note here of what I fuzzed out, as you will need to change the values to something right to you.
hostname "HOSTNAME GOES HERE"
sv_password "PASSWORD GOES HERE"
rcon_password "ANOTHER PASSWORD GOES HERE"
sv_tags "YOUR,TAGS,SEPARATED,WITH,COMMAS"
sv_region "0"
sv_contact "YOUR@CONTACT.NET"

mp_freezetime 10
mp_join_grace_time 15
mp_match_end_restart 0

sv_cheats 0
sv_lan_0

bot_quota 20
bot_quota_mode "fill"
bot_prefix "-=BOT=-"
bot_difficulty 1
bot_chatter "normal"
bot_auto_vacate 1
bot_join_after_player 1
bot_allow_rogues 0
bot_join_team any

writeid
writeip
exec banned_user.cfg
exec banned_ip.cfg</pre>
  • /home/steam/Steam/steamapps/common/Counter-Strike\ Global\ Offensive\ Beta\ -\ Dedicated\ Server/csgo/motd.txt  Fix this up to suit your own needs.  Its a txt file that's essentially html.  Google it for more info.
<body scroll="no">
<pre><font color=red>
<br>
<center><img src=http://www.schotty.com/img/docker.png></img></center>
<br>
<center>Welcome to Schotty's Privates</center>
<br>
<center>Visit schotty.com for more useful things</center>
<br>
<center>Mumble server is available for use at <font color=white>schotty.com</center>
<center><font color=red>Stop in while playing!</center>
<br>
</pre>
</body>

START IT ALL UP

OK, so here is where we put it all together and start the server up.  We need to run the container server start script.  You should be presented with a nice menu for game mode of choice.

IN SUMMARY AND CONCLUSION

This should have been enough to get going, but a few things I left out, mostly on purpose.  I have what I need to get what I want to do done.  So going forward we have containers for:

  • A repair container to rebuild/redownload steamcmd
  • The real server container for running the CSGO dedicated server and updating the dedicated server software

So depending on what we want, we start the corresponding script, and it does its thing automatically for us.