Dedicated Counter Strike Global Offensive server via docker.


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


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.

UDP 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

Dedicated or Listen Servers
TCP 27015 (SRCDS Rcon port)

Steamworks P2P Networking and Steam Voice Chat
UDP 3478 (Outbound)
UDP 4379 (Outbound)
UDP 4380 (Outbound)

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.


My dockerfile is as follows:

FROM rhel:latest

RUN yum -y install && 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).


For starting up the server I created a script called put inside the volume at /home/steam/Steam (sorry about formatting issues):

# 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"


echo "Welcome to the Counter Strike Global Offensive Dedicated Server!"
echo && echo
echo "To change gamemodes type quit in the CSGO console"
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 "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[@]}"
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
"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
"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
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
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
"Update CSGO")
cd "/home/steam/Steam/"
sh ./
let QUIT=1
*) echo Invalid option. Please choose again.;;


Finally we can now do the startup script.


Server start:

docker run -ti --rm\
           -v /storage/docker/steamcmd/csgo:/home/steam/Steam\
           /bin/bash /home/steam/Steam/


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):

 docker run -ti --rm --sig-proxy=false --privileged=true\
            -v /storage/docker/steamcmd/csgo:/home/steam/Steam\

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

cd /home/steam/Steam
curl -O
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.


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


  • /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.
sv_password "PASSWORD GOES HERE"
sv_region "0"
sv_contact "YOUR@CONTACT.NET"

mp_freezetime 10
mp_join_grace_time 15
mp_match_end_restart 0

sv_cheats 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

exec banned_user.cfg
exec banned_ip.cfg
  • /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=>
    <br><center>Welcome to Schotty's Privates</center>
    <br><center>Visit for more useful things</center>
    <br><center>Mumble server is available for use at <font color=white></center>
    <br><center><font color=red>Stop in while playing!</center></pre></body>


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.


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.