Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/images.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,14 @@ jobs:
context: containers/games/ark-survival-evolved
- game: mount-and-blade-2-bannerlord
context: containers/games/mount-and-blade-2-bannerlord
- game: fivem
context: containers/games/fivem
- game: beammp
context: containers/games/beammp
- game: farming-simulator-25
context: containers/games/farming-simulator-25
- game: euro-truck-simulator-2
context: containers/games/euro-truck-simulator-2
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
# Signing is mandatory when publishing to a registry: fail before anything
Expand Down
16 changes: 15 additions & 1 deletion containers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,25 @@ containers/
├── ark-survival-evolved/
│ ├── Dockerfile
│ └── entrypoint.sh
└── mount-and-blade-2-bannerlord/
├── mount-and-blade-2-bannerlord/
│ ├── Dockerfile
│ └── entrypoint.sh
├── fivem/ # standalone base (alpine), not on common-steamcmd
│ ├── Dockerfile
│ └── entrypoint.sh
├── beammp/ # standalone base (alpine)
│ ├── Dockerfile
│ └── entrypoint.sh
├── farming-simulator-25/ # standalone base (debian + Wine)
│ ├── Dockerfile
│ └── entrypoint.sh
└── euro-truck-simulator-2/ # standalone base (debian)
├── Dockerfile
└── entrypoint.sh
```

`fivem`, `beammp`, `farming-simulator-25` and `euro-truck-simulator-2` moved here from the `GameplanePanel/module` repo unchanged. They do not build on the SteamCMD base and run as UID/GID 1000 with `HOME=/home/gameplane`; the `STEAMCMD_BASE_IMAGE` build arg CI passes is unused by them.

### `common/` — reusable base images

Common bases are built first and used by multiple game images. Today: **`steamcmd/`** — an Ubuntu 26.04 LTS image with the official SteamCMD client at `/usr/bin/steamcmd` and the `steam-install.sh` helper on PATH. The base runs as a non-root user `gameserver` (UID 10000, GID 10000 by default; both are customizable via `GAMESERVER_UID` and `GAMESERVER_GID` build-args).
Expand Down
39 changes: 39 additions & 0 deletions containers/games/beammp/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
FROM alpine:3.20

LABEL org.opencontainers.image.title="Gameplane BeamMP Dedicated Server" \
org.opencontainers.image.description="Dedicated server container for BeamNG.drive (BeamMP) with diagnostic idle support for missing auth keys" \
org.opencontainers.image.authors="Gameplane Maintainers" \
org.opencontainers.image.source="https://github.com/GameplanePanel/Gameplane"

RUN apk add --no-cache \
bash \
curl \
ca-certificates \
tini \
procps \
libstdc++ \
libgcc \
openssl \
zlib

# Create gameplane runtime user with fixed UID/GID 1000
RUN addgroup -g 1000 gameplane && \
adduser -u 1000 -G gameplane -h /home/gameplane -s /bin/bash -D gameplane

# Prepare directories
RUN mkdir -p /serverdata /opt/beammp /server && \
ln -s /serverdata /server/Root && \
chown -R gameplane:gameplane /serverdata /opt/beammp /home/gameplane /server

COPY --chown=gameplane:gameplane entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

USER 1000:1000
WORKDIR /serverdata
ENV HOME=/home/gameplane \
USER=gameplane \
PORT=30814

EXPOSE 30814/udp 30814/tcp

ENTRYPOINT ["/sbin/tini", "--", "/entrypoint.sh"]
89 changes: 89 additions & 0 deletions containers/games/beammp/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/usr/bin/env bash
set -eo pipefail

PID_GAME=""

term_handler() {
echo "[gameplane-beammp] SIGTERM/SIGINT received, initiating graceful shutdown..."
if [ -n "$PID_GAME" ]; then
echo "[gameplane-beammp] Stopping BeamMP-Server process $PID_GAME..."
kill -TERM "$PID_GAME" 2>/dev/null || true
fi
wait
echo "[gameplane-beammp] Clean shutdown complete."
exit 0
}

trap term_handler SIGTERM SIGINT

# Resolve auth key from environment
BEAM_KEY="${BEAMMP_AUTH_KEY:-${AUTH_KEY:-}}"

# FR-013: Non-crashing diagnostic idle for missing auth key
if [ -z "$BEAM_KEY" ]; then
echo "========================================================================"
echo "DIAGNOSTIC: BeamMP Server AuthKey is not configured!"
echo "The BeamMP dedicated server requires a valid authentication key from"
echo "the BeamMP community portal to register on the master list."
echo ""
echo "Step-by-step instructions to obtain and configure your key:"
echo "1. Sign in to the BeamMP server portal at https://beammp.com"
echo "2. Navigate to the 'Keys' management section."
echo "3. Generate a new server authentication key."
echo "4. Copy the generated key."
echo "5. Configure the key in your GameServer specification:"
echo " spec:"
echo " env:"
echo " - name: BEAMMP_AUTH_KEY"
echo " value: \"your_beammp_key_here\""
echo ""
echo "Entering graceful idle mode. The server will not crash-loop."
echo "Update your manifest and restart the server once configured."
echo "========================================================================"

while true; do
sleep 3600 &
wait $!
done
fi

CONFIG_FILE="/serverdata/ServerConfig.toml"

# Generate or update ServerConfig.toml with auth key and port
if [ ! -f "$CONFIG_FILE" ]; then
cat <<EOF > "$CONFIG_FILE"
[General]
AuthKey = "$BEAM_KEY"
Port = ${PORT:-30814}
Name = "Gameplane BeamMP Server"
Description = "BeamMP Server powered by Gameplane"
MaxPlayers = 10
Private = false
Debug = false
Map = "/levels/gridmap_v2/info.json"
ResourceFolder = "Resources"
EOF
else
# Update AuthKey in existing configuration
sed -i "s/^AuthKey = .*/AuthKey = \"$BEAM_KEY\"/" "$CONFIG_FILE"
fi

SERVER_BIN="/opt/beammp/BeamMP-Server"
if [ ! -f "$SERVER_BIN" ] && [ -f "/serverdata/BeamMP-Server" ]; then
SERVER_BIN="/serverdata/BeamMP-Server"
fi

echo "[gameplane-beammp] Starting BeamMP dedicated server on port ${PORT:-30814}..."

if [ -f "$SERVER_BIN" ]; then
"$SERVER_BIN" "$@" &
PID_GAME=$!
wait "$PID_GAME" 2>/dev/null || true
else
echo "[gameplane-beammp] Note: BeamMP-Server binary not found at $SERVER_BIN."
echo "[gameplane-beammp] Entering diagnostic wait mode..."
while true; do
sleep 60 &
wait $!
done
fi
49 changes: 49 additions & 0 deletions containers/games/euro-truck-simulator-2/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
FROM debian:bookworm-slim

LABEL org.opencontainers.image.title="Gameplane Euro Truck Simulator 2 Dedicated Server" \
org.opencontainers.image.description="Dedicated server container for Euro Truck Simulator 2 with diagnostic idle support for missing logon tokens" \
org.opencontainers.image.authors="Gameplane Maintainers" \
org.opencontainers.image.source="https://github.com/GameplanePanel/Gameplane"

ENV DEBIAN_FRONTEND=noninteractive

RUN dpkg --add-architecture i386 && \
apt-get update && \
apt-get install -y --no-install-recommends \
bash \
curl \
ca-certificates \
tini \
procps \
lib32gcc-s1 \
libstdc++6 \
libstdc++6:i386 \
locales && \
sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
locale-gen && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Create gameplane runtime user with fixed UID/GID 1000
RUN groupadd -g 1000 gameplane && \
useradd -u 1000 -g gameplane -m -s /bin/bash gameplane

# Prepare directories
RUN mkdir -p /serverdata /home/gameplane/.local/share/Euro\ Truck\ Simulator\ 2 && \
ln -s /home/gameplane /home/steam && \
chown -R gameplane:gameplane /serverdata /home/gameplane

COPY --chown=gameplane:gameplane entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

USER 1000:1000
WORKDIR /serverdata
ENV HOME=/home/gameplane \
USER=gameplane \
LANG=en_US.UTF-8 \
GAME_PORT=27015 \
QUERY_PORT=27016

EXPOSE 27015/udp 27016/udp

ENTRYPOINT ["/usr/bin/tini", "--", "/entrypoint.sh"]
72 changes: 72 additions & 0 deletions containers/games/euro-truck-simulator-2/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env bash
set -eo pipefail

PID_GAME=""

term_handler() {
echo "[gameplane-ets2] SIGTERM/SIGINT received, initiating graceful shutdown..."
if [ -n "$PID_GAME" ]; then
echo "[gameplane-ets2] Stopping server process $PID_GAME..."
kill -TERM "$PID_GAME" 2>/dev/null || true
fi
wait
echo "[gameplane-ets2] Clean shutdown complete."
exit 0
}

trap term_handler SIGTERM SIGINT

# Resolve logon token from environment
LOGON_TOKEN="${SERVER_LOGON_TOKEN:-${ETS2_SERVER_LOGON_TOKEN:-${LOGON_TOKEN:-}}}"

# FR-013: Non-crashing diagnostic idle for missing logon token
if [ -z "$LOGON_TOKEN" ]; then
echo "========================================================================"
echo "DIAGNOSTIC: Euro Truck Simulator 2 Server Logon Token is not configured!"
echo "The dedicated server requires an authenticated Steam server logon token."
echo ""
echo "Step-by-step instructions to obtain and configure your logon token:"
echo "1. Visit the Steam Game Server Account Management page:"
echo " https://steamcommunity.com/dev/managegameservers"
echo "2. Enter App ID '1948400' (Euro Truck Simulator 2 Dedicated Server)."
echo "3. Enter a memo/label for your server and click 'Create'."
echo "4. Copy the generated Login Token."
echo "5. Configure the token in your GameServer specification:"
echo " spec:"
echo " env:"
echo " - name: SERVER_LOGON_TOKEN"
echo " value: \"your_logon_token_here\""
echo ""
echo "Entering graceful idle mode. The server will not crash-loop."
echo "Update your manifest and restart the server once configured."
echo "========================================================================"

while true; do
sleep 3600 &
wait $!
done
fi

SERVER_BIN="/serverdata/bin/linux_x64/eurotrucks2_server"
CONFIG_DIR="/home/gameplane/.local/share/Euro Truck Simulator 2"
mkdir -p "$CONFIG_DIR"

# Configure server_config.sii if token is available
if [ -f "$CONFIG_DIR/server_config.sii" ]; then
sed -i "s/server_logon_token: .*/server_logon_token: \"$LOGON_TOKEN\"/" "$CONFIG_DIR/server_config.sii"
fi

echo "[gameplane-ets2] Starting Euro Truck Simulator 2 dedicated server..."

if [ -f "$SERVER_BIN" ]; then
"$SERVER_BIN" -server "$@" &
PID_GAME=$!
wait "$PID_GAME" 2>/dev/null || true
else
echo "[gameplane-ets2] Server binary not yet installed at $SERVER_BIN."
echo "[gameplane-ets2] Entering diagnostic wait mode..."
while true; do
sleep 60 &
wait $!
done
fi
51 changes: 51 additions & 0 deletions containers/games/farming-simulator-25/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
FROM debian:bookworm-slim

LABEL org.opencontainers.image.title="Gameplane Farming Simulator 25 Dedicated Server" \
org.opencontainers.image.description="Dedicated server container for Farming Simulator 25 with headless Wine, dummy X11, and web admin portal supervision" \
org.opencontainers.image.authors="Gameplane Maintainers" \
org.opencontainers.image.source="https://github.com/GameplanePanel/Gameplane"

ENV DEBIAN_FRONTEND=noninteractive

RUN dpkg --add-architecture i386 && \
apt-get update && \
apt-get install -y --no-install-recommends \
bash \
curl \
ca-certificates \
tini \
procps \
xvfb \
xauth \
wine \
wine32 \
wine64 \
libwine \
libwine:i386 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Create gameplane runtime user with fixed UID/GID 1000
RUN groupadd -g 1000 gameplane && \
useradd -u 1000 -g gameplane -m -s /bin/bash gameplane

# Prepare directories
RUN mkdir -p /serverdata /home/gameplane/.wine && \
chown -R gameplane:gameplane /serverdata /home/gameplane

COPY --chown=gameplane:gameplane entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

USER 1000:1000
WORKDIR /serverdata
ENV HOME=/home/gameplane \
USER=gameplane \
WINEPREFIX=/home/gameplane/.wine \
WINEDEBUG=-all \
DISPLAY=:99 \
GAME_PORT=10823 \
WEB_PORT=8080

EXPOSE 10823/udp 8080/tcp

ENTRYPOINT ["/usr/bin/tini", "--", "/entrypoint.sh"]
Loading
Loading