diff --git a/.github/workflows/images.yaml b/.github/workflows/images.yaml index c9e66927f..dc4fb6a8c 100644 --- a/.github/workflows/images.yaml +++ b/.github/workflows/images.yaml @@ -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 diff --git a/containers/README.md b/containers/README.md index 0fe0df4ea..a5967fc85 100644 --- a/containers/README.md +++ b/containers/README.md @@ -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). diff --git a/containers/games/beammp/Dockerfile b/containers/games/beammp/Dockerfile new file mode 100644 index 000000000..9b30f1774 --- /dev/null +++ b/containers/games/beammp/Dockerfile @@ -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"] diff --git a/containers/games/beammp/entrypoint.sh b/containers/games/beammp/entrypoint.sh new file mode 100755 index 000000000..f1da602fa --- /dev/null +++ b/containers/games/beammp/entrypoint.sh @@ -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 < "$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 diff --git a/containers/games/euro-truck-simulator-2/Dockerfile b/containers/games/euro-truck-simulator-2/Dockerfile new file mode 100644 index 000000000..ff7f5a7f3 --- /dev/null +++ b/containers/games/euro-truck-simulator-2/Dockerfile @@ -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"] diff --git a/containers/games/euro-truck-simulator-2/entrypoint.sh b/containers/games/euro-truck-simulator-2/entrypoint.sh new file mode 100755 index 000000000..8a8e8f3ed --- /dev/null +++ b/containers/games/euro-truck-simulator-2/entrypoint.sh @@ -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 diff --git a/containers/games/farming-simulator-25/Dockerfile b/containers/games/farming-simulator-25/Dockerfile new file mode 100644 index 000000000..4bd8bb4cf --- /dev/null +++ b/containers/games/farming-simulator-25/Dockerfile @@ -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"] diff --git a/containers/games/farming-simulator-25/entrypoint.sh b/containers/games/farming-simulator-25/entrypoint.sh new file mode 100755 index 000000000..e2d3082f7 --- /dev/null +++ b/containers/games/farming-simulator-25/entrypoint.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +set -eo pipefail + +PID_XVFB="" +PID_WEB="" +PID_GAME="" + +term_handler() { + echo "[gameplane-fs25] SIGTERM/SIGINT received, initiating graceful shutdown..." + if [ -n "$PID_GAME" ]; then + echo "[gameplane-fs25] Stopping game process $PID_GAME..." + kill -TERM "$PID_GAME" 2>/dev/null || true + fi + if [ -n "$PID_WEB" ]; then + echo "[gameplane-fs25] Stopping web portal process $PID_WEB..." + kill -TERM "$PID_WEB" 2>/dev/null || true + fi + if [ -n "$PID_XVFB" ]; then + echo "[gameplane-fs25] Stopping virtual display $PID_XVFB..." + kill -TERM "$PID_XVFB" 2>/dev/null || true + fi + wait + echo "[gameplane-fs25] Clean shutdown complete." + exit 0 +} + +trap term_handler SIGTERM SIGINT + +echo "[gameplane-fs25] Initializing headless Wine environment..." + +# Initialize Wine prefix if needed +if [ ! -d "$WINEPREFIX/drive_c" ]; then + wineboot --init >/dev/null 2>&1 || true +fi + +# Edge case: Isolated X11 dummy display setup +export DISPLAY="${DISPLAY:-:99}" +rm -f "/tmp/.X99-lock" "/tmp/.X11-unix/X99" 2>/dev/null || true +Xvfb "$DISPLAY" -screen 0 1024x768x16 -nolisten tcp >/dev/null 2>&1 & +PID_XVFB=$! + +# Wait briefly for X display initialization +for i in $(seq 1 10); do + if xset q >/dev/null 2>&1; then + break + fi + sleep 0.5 +done + +# Look for GIANTS dedicated server or web management portal +DEDICATED_SERVER_EXE="/serverdata/FarmingSimulator2025.exe" +WEB_SERVER_EXE="/serverdata/dedicatedServer.exe" + +# If neither executable is found, provide diagnostic instructions +if [ ! -f "$DEDICATED_SERVER_EXE" ] && [ ! -f "$WEB_SERVER_EXE" ]; then + echo "========================================================================" + echo "DIAGNOSTIC: Farming Simulator 25 server files not detected in /serverdata" + echo "The dedicated server requires the official FS25 server files to run." + echo "" + echo "Step-by-step instructions:" + echo "1. Install or copy the Farming Simulator 25 Dedicated Server files into" + echo " the persistent volume mounted at /serverdata." + echo "2. Ensure the directory contains FarmingSimulator2025.exe and" + echo " dedicatedServer.exe." + echo "3. Configure your server settings in dedicatedServer.xml." + echo "" + echo "Entering graceful idle mode. The server will not crash-loop." + echo "========================================================================" + + while true; do + sleep 3600 & + wait $! + done +fi + +# FR-012: Start web management portal alongside the dedicated server +if [ -f "$WEB_SERVER_EXE" ]; then + echo "[gameplane-fs25] Starting GIANTS web management portal on port ${WEB_PORT:-8080}..." + wine "$WEB_SERVER_EXE" & + PID_WEB=$! +fi + +# Start game process if present +if [ -f "$DEDICATED_SERVER_EXE" ]; then + echo "[gameplane-fs25] Starting Farming Simulator 25 dedicated server on port ${GAME_PORT:-10823}..." + wine "$DEDICATED_SERVER_EXE" -server -port "${GAME_PORT:-10823}" "$@" & + PID_GAME=$! + wait "$PID_GAME" 2>/dev/null || true +elif [ -n "$PID_WEB" ]; then + wait "$PID_WEB" 2>/dev/null || true +fi diff --git a/containers/games/fivem/Dockerfile b/containers/games/fivem/Dockerfile new file mode 100644 index 000000000..d018e6003 --- /dev/null +++ b/containers/games/fivem/Dockerfile @@ -0,0 +1,43 @@ +FROM alpine:3.20 + +LABEL org.opencontainers.image.title="Gameplane FiveM Dedicated Server" \ + org.opencontainers.image.description="Dedicated server container for FiveM (GTA V MP) with txAdmin and embedded database supervision" \ + 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 \ + icu-libs \ + mariadb \ + mariadb-client \ + sqlite \ + tzdata + +# 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 /opt/cfx-server /server-data && \ + chown -R gameplane:gameplane /opt/cfx-server /server-data /home/gameplane + +# Copy entrypoint script +COPY --chown=gameplane:gameplane entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +USER 1000:1000 +WORKDIR /server-data +ENV HOME=/home/gameplane \ + USER=gameplane \ + PORT=30120 \ + TXADMIN_PORT=40120 + +EXPOSE 30120/tcp 30120/udp 40120/tcp + +ENTRYPOINT ["/sbin/tini", "--", "/entrypoint.sh"] diff --git a/containers/games/fivem/entrypoint.sh b/containers/games/fivem/entrypoint.sh new file mode 100755 index 000000000..e5cce04f3 --- /dev/null +++ b/containers/games/fivem/entrypoint.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +set -eo pipefail + +# Graceful termination handler +PID_DB="" +PID_FX="" + +term_handler() { + echo "[gameplane-fivem] SIGTERM/SIGINT received, initiating graceful shutdown..." + if [ -n "$PID_FX" ]; then + echo "[gameplane-fivem] Stopping fxserver process $PID_FX..." + kill -TERM "$PID_FX" 2>/dev/null || true + fi + if [ -n "$PID_DB" ]; then + echo "[gameplane-fivem] Stopping embedded MariaDB process $PID_DB..." + kill -TERM "$PID_DB" 2>/dev/null || true + fi + wait + echo "[gameplane-fivem] Clean shutdown complete." + exit 0 +} + +trap term_handler SIGTERM SIGINT + +# Resolve CFX license key from possible environment variables +LICENSE_KEY="${CFX_LICENSE_KEY:-${SV_LICENSEKEY:-${LICENSE_KEY:-}}}" + +# FR-013: Non-crashing diagnostic idle for missing license key +if [ -z "$LICENSE_KEY" ]; then + echo "========================================================================" + echo "DIAGNOSTIC: FiveM CFX Server License Key is not configured!" + echo "The FiveM dedicated server requires a CitizenFX license key to start." + echo "" + echo "Step-by-step instructions to configure your key:" + echo "1. Sign in to the Cfx.re Keymaster portal at https://keymaster.fivem.net" + echo "2. Click 'Register a new server'." + echo "3. Enter a label and the public IP address of your server/cluster." + echo "4. Copy the generated license key." + echo "5. Configure the key in your GameServer specification:" + echo " spec:" + echo " env:" + echo " - name: CFX_LICENSE_KEY" + echo " value: \"your_license_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 + +# FR-012: Supervise embedded MariaDB database if enabled +if [ "${ENABLE_EMBEDDED_DB:-true}" = "true" ]; then + DB_DIR="/server-data/mysql" + if [ ! -d "$DB_DIR" ]; then + echo "[gameplane-fivem] Initializing embedded MariaDB in $DB_DIR..." + mkdir -p "$DB_DIR" + mysql_install_db --user=gameplane --datadir="$DB_DIR" >/dev/null 2>&1 || true + fi + echo "[gameplane-fivem] Starting embedded MariaDB server..." + mariadbd --datadir="$DB_DIR" --user=gameplane --socket=/tmp/mysql.sock --bind-address=127.0.0.1 --port=3306 >/dev/null 2>&1 & + PID_DB=$! + # Brief wait for socket creation + for i in $(seq 1 30); do + if [ -S /tmp/mysql.sock ]; then + break + fi + sleep 0.5 + done +fi + +# Ensure txAdmin data directory exists +mkdir -p /server-data/txData + +echo "[gameplane-fivem] Starting FiveM dedicated server with txAdmin on port ${TXADMIN_PORT:-40120}..." + +# If fxserver binaries are mounted or installed at /opt/cfx-server +if [ -f "/opt/cfx-server/run.sh" ]; then + /opt/cfx-server/run.sh \ + +set serverProfile default \ + +set txAdminPort "${TXADMIN_PORT:-40120}" \ + +set sv_licenseKey "$LICENSE_KEY" \ + +set net_tcpConnLimit 64 \ + "$@" & + PID_FX=$! +elif [ -f "/opt/cfx-server/FXServer" ]; then + /opt/cfx-server/FXServer \ + +set serverProfile default \ + +set txAdminPort "${TXADMIN_PORT:-40120}" \ + +set sv_licenseKey "$LICENSE_KEY" \ + "$@" & + PID_FX=$! +else + echo "[gameplane-fivem] Note: fxserver binary not found at /opt/cfx-server/run.sh." + echo "[gameplane-fivem] Running in managed txAdmin supervisor mode..." + # Keep supervisor running and monitoring + while true; do + sleep 60 & + wait $! + done +fi + +wait "$PID_FX" 2>/dev/null || true diff --git a/specs/015-top-steam-game-modules/OPEN-DECISIONS.md b/specs/015-top-steam-game-modules/OPEN-DECISIONS.md index 957f63c58..3af399eb3 100644 --- a/specs/015-top-steam-game-modules/OPEN-DECISIONS.md +++ b/specs/015-top-steam-game-modules/OPEN-DECISIONS.md @@ -308,3 +308,5 @@ Open for maintainer ruling: (a) widen research.md Decision 1 to the six extra ga | `hell-let-loose` | *Pending maintainer card* (recommended: keep the module, mark it blocked) | The server files go only to Team17's licensed hosting partners; there is no public SteamCMD download, so no image can install it. | Build location (maintainer ruling 2026-10-09): the Gameplane-built images live in this repo's `containers/games//` on the shared SteamCMD base (UID 10000) and are built by `.github/workflows/images.yaml`, which checks each build on PRs and publishes and signs to `ghcr.io/gameplanepanel/gameplane` on merge to `master`, as Nuclear Option does. This supersedes the "`modules//` + `modules/build-images.sh`" wording of the ruling above. `modules/.github/workflows/build-images.yml` still gets the lowercase registry-owner fix for its four existing images. + +Build location for the four original images (maintainer ruling 2026-10-10): `fivem`, `beammp`, `farming-simulator-25` and `euro-truck-simulator-2` move unchanged from `modules//` to this repo's `containers/games//` and join the `images.yaml` matrix, because the module repo's `build-images.yml` has no signing key and only ever built them without pushing. The module repo drops its copies, `build-images.sh` and `build-images.yml`.