Skip to content
Permalink
Browse files

Add Docker support for dedicated server

  • Loading branch information...
fcrespel committed Nov 25, 2018
1 parent a2ea6ad commit fbd1da553f38fc9c606e30cb4fdabbcd434b89a9
Showing with 229 additions and 0 deletions.
  1. +58 −0 Dockerfile
  2. +68 −0 scripts/docker/functions.sh
  3. +26 −0 scripts/docker/healthcheck.sh
  4. +33 −0 scripts/docker/run.sh
  5. +44 −0 scripts/docker/server.cfg
@@ -0,0 +1,58 @@
# Builder image
FROM centos:7 as builder

# Install EPEL repository for cmake3
RUN yum -y install epel-release &&\
yum -y clean all

# Install build tools and libraries
RUN yum -y install gcc gcc-c++ make cmake3 \
glibc-devel libstdc++-devel libjpeg-turbo-devel libpng-devel zlib-devel \
glibc-devel.i686 libstdc++-devel.i686 libjpeg-turbo-devel.i686 libpng-devel.i686 zlib-devel.i686 &&\
yum -y clean all

# Copy sources
COPY . /usr/src/openjk

# Build i386 arch
RUN mkdir /usr/src/openjk/build.i386 &&\
cd /usr/src/openjk/build.i386 &&\
cmake3 -DCMAKE_TOOLCHAIN_FILE=CMakeModules/Toolchains/linux-i686.cmake \
-DBuildMPCGame=OFF -DBuildMPEngine=OFF -DBuildMPRdVanilla=OFF -DBuildMPUI=OFF \
-DBuildSPEngine=OFF -DBuildSPGame=OFF -DBuildSPRdVanilla=OFF \
.. &&\
make

# Build x86_64 arch
RUN mkdir /usr/src/openjk/build.x86_64 &&\
cd /usr/src/openjk/build.x86_64 &&\
cmake3 -DBuildMPCGame=OFF -DBuildMPEngine=OFF -DBuildMPRdVanilla=OFF -DBuildMPUI=OFF \
-DBuildSPEngine=OFF -DBuildSPGame=OFF -DBuildSPRdVanilla=OFF \
.. &&\
make


# Server image
FROM centos:7

# Install utilities and libraries
RUN yum -y install file iproute less socat wget which \
libstdc++ zlib \
libstdc++.i686 zlib.i686 &&\
yum -y clean all

# Copy binaries and scripts
RUN mkdir -p /opt/openjk/cdpath/base /opt/openjk/basepath /opt/openjk/homepath
COPY --from=builder /usr/src/openjk/build.i386/openjkded.i386 /opt/openjk/
COPY --from=builder /usr/src/openjk/build.i386/codemp/game/jampgamei386.so /opt/openjk/cdpath/base/
COPY --from=builder /usr/src/openjk/build.x86_64/openjkded.x86_64 /opt/openjk/
COPY --from=builder /usr/src/openjk/build.x86_64/codemp/game/jampgamex86_64.so /opt/openjk/cdpath/base/
COPY scripts/docker/*.sh /opt/openjk/
COPY scripts/docker/server.cfg /opt/openjk/cdpath/base/
RUN chmod +x /opt/openjk/openjkded.* /opt/openjk/*.sh

# Execution
ENV OJK_OPTS="+exec server.cfg"
EXPOSE 29070/udp
HEALTHCHECK --interval=10s --timeout=9s --retries=6 CMD ["/opt/openjk/healthcheck.sh"]
CMD ["/opt/openjk/run.sh"]
@@ -0,0 +1,68 @@
#!/bin/bash
#
# OpenJK server utility functions.
#

# Send and receive UDP datagrams
function sendrecv
{
local COMMAND="$*"
local HEADER="\0377\0377\0377\0377"
echo -e "${HEADER}${COMMAND}" | socat -t3 -T3 - UDP:127.0.0.1:29070 | tr -d "${HEADER}" 2>/dev/null
}

# Parse a config file and get the value for a cvar
function parseconfig
{
local FILE="$1"
local KEY="$2"
if [ -e "$FILE" ]; then
grep -E -i -m 1 "^set[usa]?\s+${KEY}\s+(.*)$" "$FILE" | sed -r 's#^set[usa]?\s+[^ ]+\s+"?([^"]*)"?\s*$#\1#g'
fi
}

# Parse an info string and get the value for a key
function parseinfo
{
local INFO="$1"
local KEY="$2"
echo "$INFO" | grep -o "\\\\${KEY}\\\\[^\\\\]*\\\\" | cut -d"\\" -f 3
}

# Get live server info
function getinfo
{
sendrecv getinfo | tail -n +2
}

# Get live server status
function getstatus
{
sendrecv getstatus | tail -n +2
}

# Get live server serverinfo
function getserverinfo
{
getstatus | head -n 1
}

# Get live server players
function getplayers
{
getstatus | tail -n +2
}

# Execute a rcon command
function rcon
{
local COMMAND="$*"
local CONFIG
for CONFIG in "$OJK_HOMEPATH/$OJK_MOD/server.cfg" "$OJK_BASEPATH/$OJK_MOD/server.cfg" "$OJK_CDPATH/$OJK_MOD/server.cfg"; do
local RCON_PASSWORD=`parseconfig "$CONFIG" rconpassword`
if [ -n "$RCON_PASSWORD" ]; then
sendrecv "rcon $RCON_PASSWORD $COMMAND"
break
fi
done
}
@@ -0,0 +1,26 @@
#!/bin/bash
#
# OpenJK server health check script.
#

# Set variables
OJK_DIR="/opt/openjk"
RET=0

# Load functions
. "$OJK_DIR/functions.sh"

# Check server status
INFO=`getinfo`
if [ -z "$INFO" ]; then
# Server didn't respond
RET=1
else
# Server is running
MAPNAME=`parseinfo "$INFO" mapname`
CUR_CLIENTS=`parseinfo "$INFO" clients`
MAX_CLIENTS=`parseinfo "$INFO" sv_maxclients`
echo "Connected players: $CUR_CLIENTS/$MAX_CLIENTS on $MAPNAME"
fi

exit $RET
@@ -0,0 +1,33 @@
#!/bin/bash -ex
#
# OpenJK server run script.
#

# Set variables
OJK_DIR="/opt/openjk"
OJK_MOD="${OJK_MOD:-base}"
OJK_ARCH="${OJK_ARCH:-i386}"
OJK_CDPATH="$OJK_DIR/cdpath"
OJK_BASEPATH="$OJK_DIR/basepath"
OJK_HOMEPATH="$OJK_DIR/homepath"
OJK_OPTS="+set dedicated 2 +set net_port 29070 +set fs_cdpath $OJK_CDPATH +set fs_basepath $OJK_BASEPATH +set fs_homepath $OJK_HOMEPATH +set fs_game $OJK_MOD $OJK_OPTS"
OJK_BIN="$OJK_DIR/openjkded.$OJK_ARCH"
OJK_LOG="$OJK_HOMEPATH/$OJK_MOD/openjk_server.log"

# Load functions
. "$OJK_DIR/functions.sh"

# Remove nav files
find "$OJK_DIR" -name '*.nav' -delete

# Register signal handler
trap 'rcon quit' SIGTERM

# Launch OpenJK
mkdir -p `dirname "$OJK_LOG"`
export HOME="$OJK_HOMEPATH"
umask 0002
$OJK_BIN $OJK_OPTS 2>&1 | tee -a "$OJK_LOG" &

# Wait for it while listening to signals
wait $!
@@ -0,0 +1,44 @@
// Server Config
seta sv_hostname "Sample OpenJK server"
//seta g_motd "woot"
//rconpassword "my secret password"

seta sv_maxclients 16
set timelimit 20
// gametypes
// 0 = FFA
// 3 = DUEL one on one tournament
// 4 = POWER DUEL
// 6 = TEAM DEATHMATCH
// 7 = SIEGE
// 8 = CTF

// below will rotate through all multiplayer maps
// found in the assets0.pk3 file and use the correct
// gametype for each map
set d1 "set g_gametype 0; map mp/ffa1 ; set nextmap vstr d2"
set d2 "set g_gametype 0; map mp/ffa2 ; set nextmap vstr d3"
set d3 "set g_gametype 0; map mp/ffa3 ; set nextmap vstr d4"
set d4 "set g_gametype 0; map mp/ffa4 ; set nextmap vstr d5"
set d5 "set g_gametype 0; map mp/ffa5 ; set nextmap vstr d6"
set d6 "set g_gametype 8; map mp/ctf1 ; set nextmap vstr d7"
set d7 "set g_gametype 8; map mp/ctf5 ; set nextmap vstr d8"
set d8 "set g_gametype 8; map mp/ctf5 ; set nextmap vstr d9"
set d9 "set g_gametype 8; map mp/ctf5 ; set nextmap vstr d10"
set d10 "set g_gametype 8; map mp/ctf5 ; set nextmap vstr d11"
set d11 "set g_gametype 3; map mp/duel1 ; set nextmap vstr d12"
set d12 "set g_gametype 3; map mp/duel2 ; set nextmap vstr d13"
set d13 "set g_gametype 3; map mp/duel3 ; set nextmap vstr d14"
set d14 "set g_gametype 3; map mp/duel4 ; set nextmap vstr d15"
set d15 "set g_gametype 3; map mp/duel5 ; set nextmap vstr d16"
set d16 "set g_gametype 3; map mp/duel6 ; set nextmap vstr d17"
set d17 "set g_gametype 3; map mp/duel7 ; set nextmap vstr d18"
set d18 "set g_gametype 3; map mp/duel8 ; set nextmap vstr d19"
set d19 "set g_gametype 3; map mp/duel9 ; set nextmap vstr d20"
set d20 "set g_gametype 3; map mp/duel10 ; set nextmap vstr d21"
set d21 "set g_gametype 7; map mp/siege_desert ; set nextmap vstr d22"
set d22 "set g_gametype 7; map mp/siege_hoth ; set nextmap vstr d23"
set d23 "set g_gametype 7; map mp/siege_korriban ; set nextmap vstr d1"

// start the first map
vstr d1

0 comments on commit fbd1da5

Please sign in to comment.
You can’t perform that action at this time.