From 40c4c0294d139bf01d0df5cf3203d3fb38c78698 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Oct 2026 19:10:21 +0000 Subject: [PATCH 1/6] fix(ci): lowercase the registry owner in build-images github.repository_owner is GameplanePanel, and OCI references must be lowercase, so a signed push to ghcr.io/GameplanePanel/gameplane was an invalid reference. Co-Authored-By: Claude Opus 5.5 (1M context) Signed-off-by: Claude --- .github/workflows/build-images.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-images.yml b/.github/workflows/build-images.yml index eacf92a..de850f8 100644 --- a/.github/workflows/build-images.yml +++ b/.github/workflows/build-images.yml @@ -40,8 +40,10 @@ jobs: COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} run: | + # OCI references must be lowercase; repository_owner keeps the org's casing. + owner_lc="$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')" if [ -n "$COSIGN_PRIVATE_KEY" ]; then - ./build-images.sh push --registry ghcr.io/${{ github.repository_owner }}/gameplane --sign + ./build-images.sh push --registry "ghcr.io/${owner_lc}/gameplane" --sign else ./build-images.sh build fi From 1d69132f291e342d52e6733625736cbe5c8f1587 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Oct 2026 19:10:21 +0000 Subject: [PATCH 2/6] =?UTF-8?q?feat(arma-reforger):=201.1.0=20=E2=80=94=20?= =?UTF-8?q?ACE=20community=20image,=20pinned?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use ghcr.io/acemod/arma-reforger pinned by digest instead of a Gameplane image that was never built (spec 015 T133/T135). - The image runs as root for SteamCMD: drop spec.security and the HOME override. - Mount /reforger (install, Configs, profile, workshop); ARMA_PROFILE and ARMA_WORKSHOP_DIR point inside it; mods path is workshop. - Config keys follow the image: GAME_NAME, GAME_PASSWORD, GAME_PASSWORD_ADMIN, GAME_MAX_PLAYERS. Co-Authored-By: Claude Opus 5.5 (1M context) Signed-off-by: Claude --- arma-reforger/README.md | 4 +++- arma-reforger/module.yaml | 2 +- arma-reforger/samples/gameserver.yaml | 8 +++---- arma-reforger/specs.md | 17 +++++++------- arma-reforger/template.yaml | 34 +++++++++++++-------------- 5 files changed, 32 insertions(+), 33 deletions(-) diff --git a/arma-reforger/README.md b/arma-reforger/README.md index 3764447..7968e8c 100644 --- a/arma-reforger/README.md +++ b/arma-reforger/README.md @@ -2,6 +2,8 @@ Arma Reforger dedicated server package for Gameplane. Runs on Bohemia Interactive's Enfusion engine with interactive PTY stdin console, persistent profile and saves, and Steam Workshop modding support. +Image: `ghcr.io/acemod/arma-reforger` (https://github.com/acemod/docker-reforger), the ACE team's community image. It runs as root by design, and SteamCMD installs the server into `/reforger` on every start. + ## Install ```sh @@ -25,7 +27,7 @@ Most dedicated servers allow anonymous SteamCMD download. If an authenticated St ## Storage -Persistent storage is mounted at `/home/steam/.local/share/ArmaReforgerServer` (30 GiB default). All world state, player profiles, and downloaded Workshop mods persist across container restarts. +Persistent storage is mounted at `/reforger` (30 GiB default). The server install, `Configs/`, `profile/`, and `workshop/` all live on the volume, so world state, player profiles, and downloaded Workshop mods persist across container restarts. ## Sample diff --git a/arma-reforger/module.yaml b/arma-reforger/module.yaml index 5dd6757..9093872 100644 --- a/arma-reforger/module.yaml +++ b/arma-reforger/module.yaml @@ -2,7 +2,7 @@ apiVersion: gameplane.local/module/v1 name: arma-reforger displayName: Arma Reforger -version: 1.0.0 +version: 1.1.0 game: arma-reforger categories: [Shooter, Tactical, Military, Simulation] summary: Arma Reforger dedicated server (Enfusion Engine) with stdin PTY console, persistent profile/world saves, and Steam Workshop support. diff --git a/arma-reforger/samples/gameserver.yaml b/arma-reforger/samples/gameserver.yaml index 12a05ca..a2f01e3 100644 --- a/arma-reforger/samples/gameserver.yaml +++ b/arma-reforger/samples/gameserver.yaml @@ -8,10 +8,10 @@ spec: name: arma-reforger config: - SERVER_NAME: "Gameplane Arma Reforger Server" - SERVER_PASSWORD: "" - ADMIN_PASSWORD: "secret-admin-pass" - MAX_PLAYERS: "64" + GAME_NAME: "Gameplane Arma Reforger Server" + GAME_PASSWORD: "" + GAME_PASSWORD_ADMIN: "secret-admin-pass" + GAME_MAX_PLAYERS: "64" networking: expose: NodePort diff --git a/arma-reforger/specs.md b/arma-reforger/specs.md index 8e12446..cdb71b4 100644 --- a/arma-reforger/specs.md +++ b/arma-reforger/specs.md @@ -11,10 +11,11 @@ ## 2. Container Image & Architecture -- **Base Image**: `ghcr.io/valgulnecron/gameplane/arma-reforger:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` +- **Base Image**: `ghcr.io/acemod/arma-reforger:latest@sha256:beb50bcaebbc3b3124363ed1c0a5729b514493d72b3cadd52a204ade6105fecd` - **Architecture**: `linux/amd64` +- **Image Source**: `ghcr.io/acemod/arma-reforger` (https://github.com/acemod/docker-reforger), the ACE team's community image. - **Runtime Model**: SteamCMD Linux dedicated server (`ArmaReforgerServer`). -- **User & Execution Context**: UID 1000, GID 1000, working directory `/home/steam`. +- **User & Execution Context**: root (UID 0), by the upstream image's design; working directory `/reforger`. --- @@ -31,13 +32,13 @@ Declared ports under `spec.ports`: ## 4. Storage & Persistence Layout -- **Mount Path**: `/home/steam/.local/share/ArmaReforgerServer` +- **Mount Path**: `/reforger` - **Default Sizing**: `30Gi` - **Persisted Content**: - Profile state and saved game sessions - Server configs (`ArmaReforgerServer.json`) - - Downloaded Workshop addons (`addons/`) -- **Non-Shadowing Invariant**: The mount path isolates server state under `.local/share/ArmaReforgerServer`. + - Downloaded Workshop addons (`workshop/`) +- **Non-Shadowing Invariant**: The mount path holds the server install and its state under `/reforger`. --- @@ -53,7 +54,7 @@ Declared ports under `spec.ports`: ## 6. Modding & Workshop Integration - **Modding Framework**: Bohemia Interactive Workshop / addons. -- **Mod Directory Path**: `addons` +- **Mod Directory Path**: `workshop` --- @@ -72,9 +73,7 @@ Declared ports under `spec.ports`: ## 8. Key Invariants & Security -- **User Matching**: `spec.security.runAsUser: 1000` matches image user (`steam`). -- **Environment**: `spec.env` contains `HOME=/home/steam`. -- **Filesystem Permissions**: `spec.security.fsGroup: 1000` configured for volume ownership. +- **No `spec.security` override**: the ACE image runs as root and owns its directories. --- diff --git a/arma-reforger/template.yaml b/arma-reforger/template.yaml index 4dd0479..f71471b 100644 --- a/arma-reforger/template.yaml +++ b/arma-reforger/template.yaml @@ -1,9 +1,10 @@ # yaml-language-server: $schema=../.schema/gametemplate.schema.json # Gameplane GameTemplate for Arma Reforger (dedicated server). +# Image: ghcr.io/acemod/arma-reforger (ACE team). Runs as root by design: SteamCMD installs the server into /reforger on every start. # # Runs Bohemia Interactive's Enfusion-engine dedicated server. Console access # is provided via container PTY (stdin/stdout). World saves, profile settings, -# and downloaded Workshop mods persist under /home/steam/.local/share/ArmaReforgerServer. +# and downloaded Workshop mods persist under /reforger. # # Cluster-scoped; apply once per cluster: # kubectl apply -f modules/arma-reforger/template.yaml @@ -17,30 +18,27 @@ metadata: spec: displayName: Arma Reforger game: arma-reforger - version: 1.0.0 + version: 1.1.0 categories: [Shooter, Tactical, Military, Simulation] accentColor: "#3a5a40" description: | Arma Reforger dedicated server running Bohemia Interactive's Enfusion engine. Console access is available via container PTY stdin/stdout. Persistent server - saves and Workshop mods reside under `/home/steam/.local/share/ArmaReforgerServer`. + saves and Workshop mods reside under `/reforger`, together with the server install. - image: ghcr.io/valgulnecron/gameplane/arma-reforger:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 + image: ghcr.io/acemod/arma-reforger:latest@sha256:beb50bcaebbc3b3124363ed1c0a5729b514493d72b3cadd52a204ade6105fecd versions: - id: latest displayName: "Latest (Enfusion)" - image: ghcr.io/valgulnecron/gameplane/arma-reforger:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 + image: ghcr.io/acemod/arma-reforger:latest@sha256:beb50bcaebbc3b3124363ed1c0a5729b514493d72b3cadd52a204ade6105fecd default: true env: - - name: HOME - value: /home/steam - - security: - runAsUser: 1000 - runAsGroup: 1000 - fsGroup: 1000 + - name: ARMA_PROFILE + value: /reforger/profile + - name: ARMA_WORKSHOP_DIR + value: /reforger/workshop ports: - name: game @@ -54,7 +52,7 @@ spec: storage: size: 30Gi - mountPath: /home/steam/.local/share/ArmaReforgerServer + mountPath: /reforger resources: requests: {cpu: "2", memory: 8Gi} @@ -87,7 +85,7 @@ spec: transport: stdin command: "save" mods: - path: addons + path: workshop extensions: [".pak", ".bin"] install: allowedHosts: @@ -100,19 +98,19 @@ spec: steamAppID: 1874880 configSchema: - - name: SERVER_NAME + - name: GAME_NAME displayName: Server Name type: string default: "Gameplane Arma Reforger Server" - - name: SERVER_PASSWORD + - name: GAME_PASSWORD displayName: Server Password type: password default: "" - - name: ADMIN_PASSWORD + - name: GAME_PASSWORD_ADMIN displayName: Admin Password type: password default: "" - - name: MAX_PLAYERS + - name: GAME_MAX_PLAYERS displayName: Max Players type: int default: 64 From 39abb6b931cdf73b203658f53f63423de7b481e7 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Oct 2026 19:10:21 +0000 Subject: [PATCH 3/6] =?UTF-8?q?feat(modules):=201.1.0=20=E2=80=94=20squad,?= =?UTF-8?q?=20the-isle,=20ark-se,=20bannerlord=20on=20Gameplane-built=20im?= =?UTF-8?q?ages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These four run on images built from images/games/ in the main repo on the shared SteamCMD base (spec 015 T134/T136/T137/T139): - runAsUser/runAsGroup/fsGroup 10000 to match the base's gameserver user; HOME comes from the image. - The volume mounts at /data and holds the whole install, which SteamCMD downloads on first start. - Squad mods path is SquadGame/Plugins/Mods. Image refs still hold placeholders until the images are published and pinned (T141). Co-Authored-By: Claude Opus 5.5 (1M context) Signed-off-by: Claude --- ark-survival-evolved/README.md | 2 +- ark-survival-evolved/module.yaml | 2 +- ark-survival-evolved/specs.md | 13 +++++++------ ark-survival-evolved/template.yaml | 18 +++++++----------- mount-and-blade-2-bannerlord/README.md | 2 +- mount-and-blade-2-bannerlord/module.yaml | 2 +- mount-and-blade-2-bannerlord/specs.md | 13 +++++++------ mount-and-blade-2-bannerlord/template.yaml | 14 +++++--------- squad/README.md | 2 +- squad/module.yaml | 2 +- squad/specs.md | 17 +++++++++-------- squad/template.yaml | 21 +++++++++------------ the-isle/README.md | 2 +- the-isle/module.yaml | 2 +- the-isle/specs.md | 13 +++++++------ the-isle/template.yaml | 19 ++++++++----------- 16 files changed, 67 insertions(+), 77 deletions(-) diff --git a/ark-survival-evolved/README.md b/ark-survival-evolved/README.md index 6a0c89f..f0ec546 100644 --- a/ark-survival-evolved/README.md +++ b/ark-survival-evolved/README.md @@ -24,7 +24,7 @@ The server stops cleanly by issuing `SaveWorld` and `DoExit` prior to container ## Storage & Cluster Travel -Storage is mounted at `/serverdata/ShooterGame/Saved` (35 GiB default). All map saves, tribe data, player profiles, and cross-shard cluster transfers (`clusters/` subfolder) persist across container restarts. +Storage is mounted at `/data` (35 GiB default). The game is installed there on first start, and all map saves, tribe data, player profiles, and cross-shard cluster transfers (`clusters/` subfolder, under `/data/ShooterGame/Saved`) persist across container restarts. To enable cluster travel between multiple ARK servers, supply the same `CLUSTER_ID` in each server's configuration and configure a shared volume or synchronize the cluster folder. diff --git a/ark-survival-evolved/module.yaml b/ark-survival-evolved/module.yaml index 50b7c05..139d8fb 100644 --- a/ark-survival-evolved/module.yaml +++ b/ark-survival-evolved/module.yaml @@ -2,7 +2,7 @@ apiVersion: gameplane.local/module/v1 name: ark-survival-evolved displayName: "ARK: Survival Evolved" -version: 1.0.0 +version: 1.1.0 game: ark-survival-evolved categories: [Survival, Open World, Multiplayer, Dinosaurs] summary: "ARK: Survival Evolved dedicated server with Source RCON console, cluster travel support, and persistent world state." diff --git a/ark-survival-evolved/specs.md b/ark-survival-evolved/specs.md index 13293c0..18d4951 100644 --- a/ark-survival-evolved/specs.md +++ b/ark-survival-evolved/specs.md @@ -13,8 +13,9 @@ - **Base Image**: `ghcr.io/valgulnecron/gameplane/ark-survival-evolved:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` - **Architecture**: `linux/amd64` +- **Image Source**: Built from `images/games/ark-survival-evolved/` in the main Gameplane repository on the shared SteamCMD base. - **Runtime Model**: SteamCMD Linux dedicated server (`ShooterGameServer`). -- **User & Execution Context**: UID 1000, GID 1000, working directory `/serverdata`. +- **User & Execution Context**: UID 10000, GID 10000, working directory `/data`. --- @@ -32,13 +33,13 @@ Declared ports under `spec.ports`: ## 4. Storage & Persistence Layout -- **Mount Path**: `/serverdata/ShooterGame/Saved` +- **Mount Path**: `/data` - **Default Sizing**: `35Gi` - **Persisted Content**: - Saved worlds, tribe data, and dinosaur entities (`SavedArks/`) - Server configuration files (`Config/LinuxServer/GameUserSettings.ini`) - Cross-server cluster transfers (`clusters/`) -- **Non-Shadowing Invariant**: The mount path isolates the `Saved/` directory without shadowing the server binaries in `/serverdata`. +- **Non-Shadowing Invariant**: The volume holds the whole install, so nothing in the image is shadowed (the image ships only SteamCMD and the entrypoint). --- @@ -74,9 +75,9 @@ Declared ports under `spec.ports`: ## 8. Key Invariants & Security -- **User Matching**: `spec.security.runAsUser: 1000` matches image user. -- **Environment**: `spec.env` contains `HOME=/serverdata`. -- **Filesystem Permissions**: `spec.security.fsGroup: 1000` ensures volume read/write permissions. +- **User Matching**: `spec.security.runAsUser: 10000` matches image user. +- **Environment**: `HOME=/home/gameserver` is baked into the image (no `spec.env` entry needed). +- **Filesystem Permissions**: `spec.security.fsGroup: 10000` ensures volume read/write permissions. --- diff --git a/ark-survival-evolved/template.yaml b/ark-survival-evolved/template.yaml index 87055a5..ec8c046 100644 --- a/ark-survival-evolved/template.yaml +++ b/ark-survival-evolved/template.yaml @@ -2,7 +2,7 @@ # Gameplane GameTemplate for ARK: Survival Evolved (dedicated server). # # Dedicated server for ARK: Survival Evolved running on Linux. -# Persistent world state and cluster directory live under /serverdata/ShooterGame/Saved. +# The whole ARK install lives under /data; persistent world state and cluster directory live under /data/ShooterGame/Saved. # # Cluster-scoped; apply once per cluster: # kubectl apply -f modules/ark-survival-evolved/template.yaml @@ -16,13 +16,13 @@ metadata: spec: displayName: "ARK: Survival Evolved" game: ark-survival-evolved - version: 1.0.0 + version: 1.1.0 categories: [Survival, Open World, Multiplayer, Dinosaurs] accentColor: "#00b2e2" description: | ARK: Survival Evolved dedicated server. Source RCON powers remote administration and server actions. Persistent world state and cross-shard cluster transfers live - under `/serverdata/ShooterGame/Saved`. + under `/data/ShooterGame/Saved`, on the same volume as the game install. image: ghcr.io/valgulnecron/gameplane/ark-survival-evolved:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 @@ -32,14 +32,10 @@ spec: image: ghcr.io/valgulnecron/gameplane/ark-survival-evolved:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 default: true - env: - - name: HOME - value: /serverdata - security: - runAsUser: 1000 - runAsGroup: 1000 - fsGroup: 1000 + runAsUser: 10000 + runAsGroup: 10000 + fsGroup: 10000 ports: - name: game @@ -57,7 +53,7 @@ spec: storage: size: 35Gi - mountPath: /serverdata/ShooterGame/Saved + mountPath: /data resources: requests: {cpu: "2", memory: 8Gi} diff --git a/mount-and-blade-2-bannerlord/README.md b/mount-and-blade-2-bannerlord/README.md index 912a073..930fcc9 100644 --- a/mount-and-blade-2-bannerlord/README.md +++ b/mount-and-blade-2-bannerlord/README.md @@ -25,7 +25,7 @@ Bannerlord dedicated servers run an interactive CLI on standard input. The Gamep ## Storage -Storage is mounted at `/serverdata` (20 GiB default) to hold the server binaries, configuration templates, and custom module XMLs. +Storage is mounted at `/data` (20 GiB default). The game is installed there on first start, along with the server binaries, configuration templates, and custom module XMLs. ## Sample diff --git a/mount-and-blade-2-bannerlord/module.yaml b/mount-and-blade-2-bannerlord/module.yaml index 5516c06..111da67 100644 --- a/mount-and-blade-2-bannerlord/module.yaml +++ b/mount-and-blade-2-bannerlord/module.yaml @@ -2,7 +2,7 @@ apiVersion: gameplane.local/module/v1 name: mount-and-blade-2-bannerlord displayName: "Mount & Blade II: Bannerlord" -version: 1.0.0 +version: 1.1.0 game: mount-and-blade-2-bannerlord categories: [Action, RPG, Medieval, Multiplayer] summary: "Mount & Blade II: Bannerlord dedicated multiplayer server with PTY console and match-based skirmish hosting." diff --git a/mount-and-blade-2-bannerlord/specs.md b/mount-and-blade-2-bannerlord/specs.md index df45c7e..b339771 100644 --- a/mount-and-blade-2-bannerlord/specs.md +++ b/mount-and-blade-2-bannerlord/specs.md @@ -13,8 +13,9 @@ - **Base Image**: `ghcr.io/valgulnecron/gameplane/mount-and-blade-2-bannerlord:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` - **Architecture**: `linux/amd64` +- **Image Source**: Built from `images/games/mount-and-blade-2-bannerlord/` in the main Gameplane repository on the shared SteamCMD base. - **Runtime Model**: Linux-native / Wine .NET 6 TaleWorlds dedicated server binary. -- **User & Execution Context**: UID `1000`, GID `1000`, working directory `/serverdata`. +- **User & Execution Context**: UID `10000`, GID `10000`, working directory `/data`. --- @@ -31,13 +32,13 @@ Declared ports under `spec.ports`: ## 4. Storage & Persistence Layout -- **Mount Path**: `/serverdata` +- **Mount Path**: `/data` - **Default Sizing**: `20Gi` - **Persisted Content**: - Downloaded server binaries and TaleWorlds modules - Match configuration files (`tdm_config.txt`, `siege_config.txt`) - Server tokens and authentication credentials -- **Non-Shadowing Invariant**: Dedicated server install root resides within `/serverdata`. +- **Non-Shadowing Invariant**: The volume holds the whole install, so nothing in the image is shadowed (the image ships only SteamCMD and the entrypoint). --- @@ -67,9 +68,9 @@ Declared ports under `spec.ports`: ## 8. Key Invariants & Security -- **User Matching**: `spec.security.runAsUser: 1000` matches image user. -- **Environment**: `spec.env` defines `HOME: /serverdata`. -- **Filesystem Permissions**: `spec.security.fsGroup: 1000` ensures write permission on `/serverdata`. +- **User Matching**: `spec.security.runAsUser: 10000` matches image user. +- **Environment**: `HOME=/home/gameserver` is baked into the image (no `spec.env` entry needed). +- **Filesystem Permissions**: `spec.security.fsGroup: 10000` ensures write permission on `/data`. --- diff --git a/mount-and-blade-2-bannerlord/template.yaml b/mount-and-blade-2-bannerlord/template.yaml index 5c64077..54740bc 100644 --- a/mount-and-blade-2-bannerlord/template.yaml +++ b/mount-and-blade-2-bannerlord/template.yaml @@ -16,7 +16,7 @@ metadata: spec: displayName: "Mount & Blade II: Bannerlord" game: mount-and-blade-2-bannerlord - version: 1.0.0 + version: 1.1.0 categories: [Action, RPG, Medieval, Multiplayer] accentColor: "#b45309" description: | @@ -26,14 +26,10 @@ spec: image: ghcr.io/valgulnecron/gameplane/mount-and-blade-2-bannerlord:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 - env: - - name: HOME - value: /serverdata - security: - runAsUser: 1000 - runAsGroup: 1000 - fsGroup: 1000 + runAsUser: 10000 + runAsGroup: 10000 + fsGroup: 10000 ports: - name: game @@ -47,7 +43,7 @@ spec: storage: size: 20Gi - mountPath: /serverdata + mountPath: /data resources: requests: {cpu: "2", memory: 4Gi} diff --git a/squad/README.md b/squad/README.md index f2e9370..aa974bb 100644 --- a/squad/README.md +++ b/squad/README.md @@ -24,7 +24,7 @@ Gameplay is match-based, and server shutdown does not require a pre-shutdown sav ## Storage -Persistent storage is mounted at `/serverdata/Squad/Saved` (40 GiB default). Server settings, admin lists, and map rotation history persist across container restarts. +Storage is mounted at `/data` (40 GiB default). The game is installed there on first start, and server settings (`/data/SquadGame/ServerConfig`), admin lists, and map rotation history persist across container restarts. ## Sample diff --git a/squad/module.yaml b/squad/module.yaml index 806ad5a..c4aad39 100644 --- a/squad/module.yaml +++ b/squad/module.yaml @@ -2,7 +2,7 @@ apiVersion: gameplane.local/module/v1 name: squad displayName: Squad -version: 1.0.0 +version: 1.1.0 game: squad categories: [Shooter, Tactical, Military, Multiplayer] summary: Squad dedicated server (Unreal Engine 4) with Source-family RCON console, match-based rotation, and Steam Workshop modding support. diff --git a/squad/specs.md b/squad/specs.md index f369404..b1d0dce 100644 --- a/squad/specs.md +++ b/squad/specs.md @@ -13,8 +13,9 @@ - **Base Image**: `ghcr.io/valgulnecron/gameplane/squad:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` - **Architecture**: `linux/amd64` +- **Image Source**: Built from `images/games/squad/` in the main Gameplane repository on the shared SteamCMD base. - **Runtime Model**: SteamCMD Linux dedicated server (`SquadServer.sh`). -- **User & Execution Context**: UID 1000, GID 1000, working directory `/serverdata`. +- **User & Execution Context**: UID 10000, GID 10000, working directory `/data`. --- @@ -32,13 +33,13 @@ Declared ports under `spec.ports`: ## 4. Storage & Persistence Layout -- **Mount Path**: `/serverdata/Squad/Saved` +- **Mount Path**: `/data` - **Default Sizing**: `40Gi` - **Persisted Content**: - Server configuration files (`Server.cfg`, `Admins.cfg`, `LayerRotation.cfg`) - Server bans and player licenses - Match history and performance logs -- **Non-Shadowing Invariant**: The mount path isolates the `Saved/` directory without shadowing the server binaries in `/serverdata`. +- **Non-Shadowing Invariant**: The volume holds the whole install, so nothing in the image is shadowed (the image ships only SteamCMD and the entrypoint). --- @@ -53,8 +54,8 @@ Declared ports under `spec.ports`: ## 6. Modding & Workshop Integration -- **Modding Framework**: Steam Workshop (`Plugins/Mods`). -- **Mod Directory Path**: `Plugins/Mods` +- **Modding Framework**: Steam Workshop (`SquadGame/Plugins/Mods`). +- **Mod Directory Path**: `SquadGame/Plugins/Mods` --- @@ -68,9 +69,9 @@ Declared ports under `spec.ports`: ## 8. Key Invariants & Security -- **User Matching**: `spec.security.runAsUser: 1000` matches image user. -- **Environment**: `spec.env` contains `HOME=/serverdata`. -- **Filesystem Permissions**: `spec.security.fsGroup: 1000` configured for volume ownership. +- **User Matching**: `spec.security.runAsUser: 10000` matches image user. +- **Environment**: `HOME=/home/gameserver` is baked into the image (no `spec.env` entry needed). +- **Filesystem Permissions**: `spec.security.fsGroup: 10000` configured for volume ownership. --- diff --git a/squad/template.yaml b/squad/template.yaml index 0081da6..4d95919 100644 --- a/squad/template.yaml +++ b/squad/template.yaml @@ -2,7 +2,7 @@ # Gameplane GameTemplate for Squad (dedicated server). # # Runs Unreal Engine 4 dedicated server with Source-family RCON on TCP 21114. -# Match-based rotation with persistent configurations under /serverdata/Squad/Saved. +# Match-based rotation. The whole Squad install lives under /data; persistent configurations are in /data/SquadGame/ServerConfig. # # Cluster-scoped; apply once per cluster: # kubectl apply -f modules/squad/template.yaml @@ -16,13 +16,14 @@ metadata: spec: displayName: Squad game: squad - version: 1.0.0 + version: 1.1.0 categories: [Shooter, Tactical, Military, Multiplayer] accentColor: "#2d3748" description: | Squad dedicated multiplayer server. Source-family RCON powers remote console moderation, map rotation, and server administration on TCP port 21114. - Server configuration and match logs persist under `/serverdata/Squad/Saved`. + The whole game install lives on the `/data` volume, so server configuration + (`/data/SquadGame/ServerConfig`) and match logs persist there. image: ghcr.io/valgulnecron/gameplane/squad:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 @@ -32,14 +33,10 @@ spec: image: ghcr.io/valgulnecron/gameplane/squad:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 default: true - env: - - name: HOME - value: /serverdata - security: - runAsUser: 1000 - runAsGroup: 1000 - fsGroup: 1000 + runAsUser: 10000 + runAsGroup: 10000 + fsGroup: 10000 ports: - name: game @@ -57,7 +54,7 @@ spec: storage: size: 40Gi - mountPath: /serverdata/Squad/Saved + mountPath: /data resources: requests: {cpu: "2", memory: 8Gi} @@ -121,7 +118,7 @@ spec: type: string required: true mods: - path: Plugins/Mods + path: SquadGame/Plugins/Mods extensions: [".pak"] install: allowedHosts: diff --git a/the-isle/README.md b/the-isle/README.md index ed94621..89de807 100644 --- a/the-isle/README.md +++ b/the-isle/README.md @@ -24,7 +24,7 @@ Graceful stop triggers the `save` command prior to container termination. ## Storage -Storage is mounted at `/serverdata/TheIsle/Saved` (25 GiB default). All world state, player profiles, and server configuration files persist across pod restarts. +Storage is mounted at `/data` (25 GiB default). The game is installed there on first start, and all world state, player profiles, and server configuration files persist under `/data/TheIsle/Saved` across pod restarts. ## Sample diff --git a/the-isle/module.yaml b/the-isle/module.yaml index 15541d8..f4472bf 100644 --- a/the-isle/module.yaml +++ b/the-isle/module.yaml @@ -2,7 +2,7 @@ apiVersion: gameplane.local/module/v1 name: the-isle displayName: The Isle -version: 1.0.0 +version: 1.1.0 game: the-isle categories: [Survival, Dinosaurs, Open World, Multiplayer] summary: The Isle dedicated server (Unreal Engine 4) with Source RCON remote administration and persistent world save management. diff --git a/the-isle/specs.md b/the-isle/specs.md index dd177bc..5ebfad5 100644 --- a/the-isle/specs.md +++ b/the-isle/specs.md @@ -13,8 +13,9 @@ - **Base Image**: `ghcr.io/valgulnecron/gameplane/the-isle:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` - **Architecture**: `linux/amd64` +- **Image Source**: Built from `images/games/the-isle/` in the main Gameplane repository on the shared SteamCMD base. - **Runtime Model**: SteamCMD / Unreal Engine Linux dedicated server. -- **User & Execution Context**: UID 1000, GID 1000, working directory `/serverdata`. +- **User & Execution Context**: UID 10000, GID 10000, working directory `/data`. --- @@ -32,13 +33,13 @@ Declared ports under `spec.ports`: ## 4. Storage & Persistence Layout -- **Mount Path**: `/serverdata/TheIsle/Saved` +- **Mount Path**: `/data` - **Default Sizing**: `25Gi` - **Persisted Content**: - Saved dinosaur entities and world maps - Configuration files (`Game.ini`, `Engine.ini`) - Admin rosters and ban lists -- **Non-Shadowing Invariant**: The mount path isolates the `Saved/` directory without shadowing the server binaries in `/serverdata`. +- **Non-Shadowing Invariant**: The volume holds the whole install, so nothing in the image is shadowed (the image ships only SteamCMD and the entrypoint). --- @@ -73,9 +74,9 @@ Declared ports under `spec.ports`: ## 8. Key Invariants & Security -- **User Matching**: `spec.security.runAsUser: 1000` matches image user. -- **Environment**: `spec.env` contains `HOME=/serverdata`. -- **Filesystem Permissions**: `spec.security.fsGroup: 1000` configured for volume ownership. +- **User Matching**: `spec.security.runAsUser: 10000` matches image user. +- **Environment**: `HOME=/home/gameserver` is baked into the image (no `spec.env` entry needed). +- **Filesystem Permissions**: `spec.security.fsGroup: 10000` configured for volume ownership. --- diff --git a/the-isle/template.yaml b/the-isle/template.yaml index 4cf6272..c868a47 100644 --- a/the-isle/template.yaml +++ b/the-isle/template.yaml @@ -2,7 +2,7 @@ # Gameplane GameTemplate for The Isle (dedicated server). # # Runs Unreal Engine 4 dedicated server with Source RCON on TCP 8888. -# World state, dinosaurs, and configs persist under /serverdata/TheIsle/Saved. +# The whole The Isle install lives under /data; world state, dinosaurs, and configs persist under /data/TheIsle/Saved. # # Cluster-scoped; apply once per cluster: # kubectl apply -f modules/the-isle/template.yaml @@ -16,13 +16,14 @@ metadata: spec: displayName: The Isle game: the-isle - version: 1.0.0 + version: 1.1.0 categories: [Survival, Dinosaurs, Open World, Multiplayer] accentColor: "#22543d" description: | The Isle dedicated multiplayer server running on Unreal Engine. Source RCON powers remote console administration on port 8888 TCP; - saves and server configurations persist under `TheIsle/Saved`. + the game is installed on the `/data` volume, and saves and server configurations + persist under `/data/TheIsle/Saved`. image: ghcr.io/valgulnecron/gameplane/the-isle:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 @@ -32,14 +33,10 @@ spec: image: ghcr.io/valgulnecron/gameplane/the-isle:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 default: true - env: - - name: HOME - value: /serverdata - security: - runAsUser: 1000 - runAsGroup: 1000 - fsGroup: 1000 + runAsUser: 10000 + runAsGroup: 10000 + fsGroup: 10000 ports: - name: game @@ -57,7 +54,7 @@ spec: storage: size: 25Gi - mountPath: /serverdata/TheIsle/Saved + mountPath: /data resources: requests: {cpu: "2", memory: 4Gi} From b00bb560552e14956d30bd3a15470338ca8ac8e6 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 10 Oct 2026 05:51:19 +0000 Subject: [PATCH 4/6] fix(modules): pin squad, the-isle, ark-se, bannerlord to published images Repoint the four Gameplane-built images to ghcr.io/gameplanepanel/gameplane (published and cosign-signed by GameplanePanel/Gameplane#638) and replace the placeholder digest with the real one (T141). Co-Authored-By: Claude Opus 5.5 (1M context) Signed-off-by: Claude --- ark-survival-evolved/specs.md | 2 +- ark-survival-evolved/template.yaml | 4 ++-- mount-and-blade-2-bannerlord/specs.md | 2 +- mount-and-blade-2-bannerlord/template.yaml | 2 +- squad/specs.md | 2 +- squad/template.yaml | 4 ++-- the-isle/specs.md | 2 +- the-isle/template.yaml | 4 ++-- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ark-survival-evolved/specs.md b/ark-survival-evolved/specs.md index 18d4951..fe46080 100644 --- a/ark-survival-evolved/specs.md +++ b/ark-survival-evolved/specs.md @@ -11,7 +11,7 @@ ## 2. Container Image & Architecture -- **Base Image**: `ghcr.io/valgulnecron/gameplane/ark-survival-evolved:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` +- **Base Image**: `ghcr.io/gameplanepanel/gameplane/ark-survival-evolved:latest@sha256:2a4298f8055dbff4107c49c961cace1f2bed42809e6b93fb4924371ae4484e58` - **Architecture**: `linux/amd64` - **Image Source**: Built from `images/games/ark-survival-evolved/` in the main Gameplane repository on the shared SteamCMD base. - **Runtime Model**: SteamCMD Linux dedicated server (`ShooterGameServer`). diff --git a/ark-survival-evolved/template.yaml b/ark-survival-evolved/template.yaml index ec8c046..9630c08 100644 --- a/ark-survival-evolved/template.yaml +++ b/ark-survival-evolved/template.yaml @@ -24,12 +24,12 @@ spec: and server actions. Persistent world state and cross-shard cluster transfers live under `/data/ShooterGame/Saved`, on the same volume as the game install. - image: ghcr.io/valgulnecron/gameplane/ark-survival-evolved:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 + image: ghcr.io/gameplanepanel/gameplane/ark-survival-evolved:latest@sha256:2a4298f8055dbff4107c49c961cace1f2bed42809e6b93fb4924371ae4484e58 versions: - id: latest displayName: "Latest" - image: ghcr.io/valgulnecron/gameplane/ark-survival-evolved:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 + image: ghcr.io/gameplanepanel/gameplane/ark-survival-evolved:latest@sha256:2a4298f8055dbff4107c49c961cace1f2bed42809e6b93fb4924371ae4484e58 default: true security: diff --git a/mount-and-blade-2-bannerlord/specs.md b/mount-and-blade-2-bannerlord/specs.md index b339771..8cb1189 100644 --- a/mount-and-blade-2-bannerlord/specs.md +++ b/mount-and-blade-2-bannerlord/specs.md @@ -11,7 +11,7 @@ ## 2. Container Image & Architecture -- **Base Image**: `ghcr.io/valgulnecron/gameplane/mount-and-blade-2-bannerlord:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` +- **Base Image**: `ghcr.io/gameplanepanel/gameplane/mount-and-blade-2-bannerlord:latest@sha256:ac4796548429fce3bf1990839b75002f08ee8d6c11260bc4a26329f5a7d93717` - **Architecture**: `linux/amd64` - **Image Source**: Built from `images/games/mount-and-blade-2-bannerlord/` in the main Gameplane repository on the shared SteamCMD base. - **Runtime Model**: Linux-native / Wine .NET 6 TaleWorlds dedicated server binary. diff --git a/mount-and-blade-2-bannerlord/template.yaml b/mount-and-blade-2-bannerlord/template.yaml index 54740bc..11db2e5 100644 --- a/mount-and-blade-2-bannerlord/template.yaml +++ b/mount-and-blade-2-bannerlord/template.yaml @@ -24,7 +24,7 @@ spec: skirmish, battle, and siege match hosting. Interactive console connects via container PTY stdin/stdout. - image: ghcr.io/valgulnecron/gameplane/mount-and-blade-2-bannerlord:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 + image: ghcr.io/gameplanepanel/gameplane/mount-and-blade-2-bannerlord:latest@sha256:ac4796548429fce3bf1990839b75002f08ee8d6c11260bc4a26329f5a7d93717 security: runAsUser: 10000 diff --git a/squad/specs.md b/squad/specs.md index b1d0dce..21956a7 100644 --- a/squad/specs.md +++ b/squad/specs.md @@ -11,7 +11,7 @@ ## 2. Container Image & Architecture -- **Base Image**: `ghcr.io/valgulnecron/gameplane/squad:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` +- **Base Image**: `ghcr.io/gameplanepanel/gameplane/squad:latest@sha256:c96561c975b1cd049668da930582181de7ac8d74e5d8d2251080423ec2ee2748` - **Architecture**: `linux/amd64` - **Image Source**: Built from `images/games/squad/` in the main Gameplane repository on the shared SteamCMD base. - **Runtime Model**: SteamCMD Linux dedicated server (`SquadServer.sh`). diff --git a/squad/template.yaml b/squad/template.yaml index 4d95919..464acdc 100644 --- a/squad/template.yaml +++ b/squad/template.yaml @@ -25,12 +25,12 @@ spec: The whole game install lives on the `/data` volume, so server configuration (`/data/SquadGame/ServerConfig`) and match logs persist there. - image: ghcr.io/valgulnecron/gameplane/squad:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 + image: ghcr.io/gameplanepanel/gameplane/squad:latest@sha256:c96561c975b1cd049668da930582181de7ac8d74e5d8d2251080423ec2ee2748 versions: - id: latest displayName: "Latest (UE4)" - image: ghcr.io/valgulnecron/gameplane/squad:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 + image: ghcr.io/gameplanepanel/gameplane/squad:latest@sha256:c96561c975b1cd049668da930582181de7ac8d74e5d8d2251080423ec2ee2748 default: true security: diff --git a/the-isle/specs.md b/the-isle/specs.md index 5ebfad5..8be40f5 100644 --- a/the-isle/specs.md +++ b/the-isle/specs.md @@ -11,7 +11,7 @@ ## 2. Container Image & Architecture -- **Base Image**: `ghcr.io/valgulnecron/gameplane/the-isle:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` +- **Base Image**: `ghcr.io/gameplanepanel/gameplane/the-isle:latest@sha256:229ec85c92f8f722beb0b7c735cfdb5dbe40e6782d537a6c56b32c6baa57d5a8` - **Architecture**: `linux/amd64` - **Image Source**: Built from `images/games/the-isle/` in the main Gameplane repository on the shared SteamCMD base. - **Runtime Model**: SteamCMD / Unreal Engine Linux dedicated server. diff --git a/the-isle/template.yaml b/the-isle/template.yaml index c868a47..2d03003 100644 --- a/the-isle/template.yaml +++ b/the-isle/template.yaml @@ -25,12 +25,12 @@ spec: the game is installed on the `/data` volume, and saves and server configurations persist under `/data/TheIsle/Saved`. - image: ghcr.io/valgulnecron/gameplane/the-isle:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 + image: ghcr.io/gameplanepanel/gameplane/the-isle:latest@sha256:229ec85c92f8f722beb0b7c735cfdb5dbe40e6782d537a6c56b32c6baa57d5a8 versions: - id: evrima displayName: "The Isle (Evrima / UE)" - image: ghcr.io/valgulnecron/gameplane/the-isle:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 + image: ghcr.io/gameplanepanel/gameplane/the-isle:latest@sha256:229ec85c92f8f722beb0b7c735cfdb5dbe40e6782d537a6c56b32c6baa57d5a8 default: true security: From 49a68d9ef9a6f7470d3a888f6b4bd06e06b09fe0 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 10 Oct 2026 23:40:09 +0000 Subject: [PATCH 5/6] chore(modules): move fivem, beammp, fs25, ets2 image sources to the main repo Their Dockerfiles and entrypoints now live in GameplanePanel/Gameplane containers/games/, which publishes and signs them. Drop the local copies, build-images.sh and the build-images workflow (it had no signing key and never pushed), and point the four templates at ghcr.io/gameplanepanel/gameplane. Digests are pinned once the images are published. Co-Authored-By: Claude Opus 5.5 (1M context) Signed-off-by: Claude --- .github/workflows/build-images.yml | 49 ---------- beammp/Dockerfile | 39 -------- beammp/entrypoint.sh | 89 ------------------ beammp/specs.md | 2 +- beammp/template.yaml | 2 +- build-images.sh | 134 --------------------------- euro-truck-simulator-2/Dockerfile | 49 ---------- euro-truck-simulator-2/entrypoint.sh | 72 -------------- euro-truck-simulator-2/specs.md | 2 +- euro-truck-simulator-2/template.yaml | 2 +- farming-simulator-25/Dockerfile | 51 ---------- farming-simulator-25/entrypoint.sh | 91 ------------------ farming-simulator-25/specs.md | 2 +- farming-simulator-25/template.yaml | 2 +- fivem/Dockerfile | 43 --------- fivem/entrypoint.sh | 106 --------------------- fivem/specs.md | 2 +- fivem/template.yaml | 2 +- 18 files changed, 8 insertions(+), 731 deletions(-) delete mode 100644 .github/workflows/build-images.yml delete mode 100644 beammp/Dockerfile delete mode 100644 beammp/entrypoint.sh delete mode 100755 build-images.sh delete mode 100644 euro-truck-simulator-2/Dockerfile delete mode 100644 euro-truck-simulator-2/entrypoint.sh delete mode 100644 farming-simulator-25/Dockerfile delete mode 100644 farming-simulator-25/entrypoint.sh delete mode 100644 fivem/Dockerfile delete mode 100644 fivem/entrypoint.sh diff --git a/.github/workflows/build-images.yml b/.github/workflows/build-images.yml deleted file mode 100644 index de850f8..0000000 --- a/.github/workflows/build-images.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: build and sign gameplane images - -on: - push: - branches: [main] - paths: - - 'fivem/**' - - 'farming-simulator-25/**' - - 'euro-truck-simulator-2/**' - - 'beammp/**' - - 'build-images.sh' - workflow_dispatch: - -permissions: - contents: read - packages: write - id-token: write - -jobs: - build-and-sign: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Install Cosign - uses: sigstore/cosign-installer@v3.5.0 - - - name: Log in to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Build, push, and cosign-sign Gameplane images - env: - COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} - COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} - run: | - # OCI references must be lowercase; repository_owner keeps the org's casing. - owner_lc="$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')" - if [ -n "$COSIGN_PRIVATE_KEY" ]; then - ./build-images.sh push --registry "ghcr.io/${owner_lc}/gameplane" --sign - else - ./build-images.sh build - fi diff --git a/beammp/Dockerfile b/beammp/Dockerfile deleted file mode 100644 index 9b30f17..0000000 --- a/beammp/Dockerfile +++ /dev/null @@ -1,39 +0,0 @@ -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/beammp/entrypoint.sh b/beammp/entrypoint.sh deleted file mode 100644 index f1da602..0000000 --- a/beammp/entrypoint.sh +++ /dev/null @@ -1,89 +0,0 @@ -#!/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/beammp/specs.md b/beammp/specs.md index b68a0c5..562e90e 100644 --- a/beammp/specs.md +++ b/beammp/specs.md @@ -11,7 +11,7 @@ ## 2. Container Image & Architecture -- **Base Image**: `ghcr.io/valgulnecron/gameplane/beammp:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` +- **Base Image**: `ghcr.io/gameplanepanel/gameplane/beammp:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` - **Architecture**: `linux/amd64` - **Runtime Model**: Standalone C++ binary (`BeamMP-Server`) executing natively under Alpine Linux. - **User & Execution Context**: UID `1000`, GID `1000`, working directory `/serverdata`. diff --git a/beammp/template.yaml b/beammp/template.yaml index 19df81b..f34cb3f 100644 --- a/beammp/template.yaml +++ b/beammp/template.yaml @@ -24,7 +24,7 @@ spec: Interactive console connects via container PTY stdin/stdout. Mods and custom vehicle/map packages install into the Resources directory. - image: ghcr.io/valgulnecron/gameplane/beammp:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 + image: ghcr.io/gameplanepanel/gameplane/beammp:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 env: - name: HOME diff --git a/build-images.sh b/build-images.sh deleted file mode 100755 index 08b2e2b..0000000 --- a/build-images.sh +++ /dev/null @@ -1,134 +0,0 @@ -#!/usr/bin/env bash -# build-images.sh — build, push, and sign Gameplane-owned container images. -# -# Builds purpose-built Dockerfiles for games requiring auxiliary service -# supervision (FR-012) or non-crashing diagnostic idle for missing tokens (FR-013): -# - fivem (txAdmin + embedded database) -# - farming-simulator-25 (headless Wine + dummy X11 + web admin portal) -# - euro-truck-simulator-2 (ETS2 server logon token diagnostic idle) -# - beammp (BeamMP auth key diagnostic idle) -# -# Usage: -# modules/build-images.sh build # build all 4 images locally -# modules/build-images.sh build --name fivem # build only fivem -# modules/build-images.sh push --registry ghcr.io/gameplanepanel/gameplane --sign - -set -euo pipefail - -KNOWN_IMAGES=("fivem" "farming-simulator-25" "euro-truck-simulator-2" "beammp") - -usage() { - cat < [flags] - -Commands: - build Build container images locally - push Build and push container images to an OCI registry - -Flags: - --registry Registry prefix (e.g. ghcr.io/gameplanepanel/gameplane) [required for push] - --name Target a specific image (fivem, farming-simulator-25, euro-truck-simulator-2, beammp) - --tag Override image tag (default: latest or module version) - --sign cosign-sign each pushed image by manifest digest - --plain-http Use plain HTTP (for local testing registries) - --insecure Skip TLS verification - --tlog-upload Record signature in public Rekor transparency log (default: offline) -USAGE -} - -ACTION="${1:-}" -[[ -n "$ACTION" ]] || { usage; exit 1; } -shift - -REGISTRY="" -TARGET="" -OVERRIDE_TAG="" -SIGN=0 -PLAIN_HTTP="" -INSECURE="" -TLOG_UPLOAD=0 - -while [[ $# -gt 0 ]]; do - case "$1" in - --registry) REGISTRY="$2"; shift 2 ;; - --name) TARGET="$2"; shift 2 ;; - --tag) OVERRIDE_TAG="$2"; shift 2 ;; - --sign) SIGN=1; shift ;; - --plain-http) PLAIN_HTTP=1; shift ;; - --insecure) INSECURE=1; shift ;; - --tlog-upload) TLOG_UPLOAD=1; shift ;; - -h|--help) usage; exit 0 ;; - *) echo "Unknown flag: $1" >&2; exit 1 ;; - esac -done - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -if [[ "$ACTION" == "push" ]] && [[ -z "$REGISTRY" ]]; then - echo "Error: --registry is required for push" >&2 - exit 1 -fi - -build_and_push() { - local name="$1" - local dir="$SCRIPT_DIR/$name" - - if [[ ! -f "$dir/Dockerfile" ]]; then - echo "Skipping $name: no Dockerfile found at $dir/Dockerfile" >&2 - return 0 - fi - - local version="latest" - if [[ -n "$OVERRIDE_TAG" ]]; then - version="$OVERRIDE_TAG" - elif [[ -f "$dir/module.yaml" ]] && command -v python3 >/dev/null 2>&1; then - local v - v="$(python3 -c "import yaml; print(yaml.safe_load(open('$dir/module.yaml'))['version'])" 2>/dev/null || true)" - [[ -n "$v" ]] && version="$v" - fi - - local image_tag="gameplane-$name:$version" - if [[ -n "$REGISTRY" ]]; then - image_tag="$REGISTRY/$name:$version" - fi - - echo "==> Building $image_tag from $dir/Dockerfile" - docker build -t "$image_tag" -f "$dir/Dockerfile" "$dir" - - if [[ "$ACTION" == "push" ]]; then - echo "==> Pushing $image_tag" - docker push "$image_tag" - - if (( SIGN )); then - local digest - digest="$(docker inspect --format='{{index .RepoDigests 0}}' "$image_tag" 2>/dev/null | grep -o 'sha256:[a-f0-9]*' || true)" - if [[ -z "$digest" ]]; then - echo "Error: could not determine digest for $image_tag" >&2 - return 1 - fi - - echo "==> Signing $REGISTRY/$name@$digest" - local sargs=( sign --key env://COSIGN_PRIVATE_KEY --yes - --new-bundle-format=false --use-signing-config=false ) - if (( TLOG_UPLOAD )); then - echo ">> (recording signature in public Rekor transparency log)" - else - sargs+=( --tlog-upload=false ) - fi - [[ -n "$PLAIN_HTTP" ]] && sargs+=( --allow-http-registry ) - [[ -n "$INSECURE" ]] && sargs+=( --allow-insecure-registry ) - cosign "${sargs[@]}" "$REGISTRY/$name@$digest" - fi - fi -} - -TARGETS=("${KNOWN_IMAGES[@]}") -if [[ -n "$TARGET" ]]; then - TARGETS=("$TARGET") -fi - -for img in "${TARGETS[@]}"; do - build_and_push "$img" -done - -echo "==> Done." diff --git a/euro-truck-simulator-2/Dockerfile b/euro-truck-simulator-2/Dockerfile deleted file mode 100644 index ff7f5a7..0000000 --- a/euro-truck-simulator-2/Dockerfile +++ /dev/null @@ -1,49 +0,0 @@ -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/euro-truck-simulator-2/entrypoint.sh b/euro-truck-simulator-2/entrypoint.sh deleted file mode 100644 index 8a8e8f3..0000000 --- a/euro-truck-simulator-2/entrypoint.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/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/euro-truck-simulator-2/specs.md b/euro-truck-simulator-2/specs.md index ba7ba0c..04cf87f 100644 --- a/euro-truck-simulator-2/specs.md +++ b/euro-truck-simulator-2/specs.md @@ -11,7 +11,7 @@ ## 2. Container Image & Architecture -- **Base Image**: `ghcr.io/valgulnecron/gameplane/euro-truck-simulator-2:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` +- **Base Image**: `ghcr.io/gameplanepanel/gameplane/euro-truck-simulator-2:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` - **Architecture**: `linux/amd64` - **Runtime Model**: Linux 64-bit standalone dedicated server binary (`eurotrucks2_server`) managed by Gameplane supervisor script. - **User & Execution Context**: UID `1000`, GID `1000`, working directory `/serverdata`. diff --git a/euro-truck-simulator-2/template.yaml b/euro-truck-simulator-2/template.yaml index e5ff3d0..6b7828a 100644 --- a/euro-truck-simulator-2/template.yaml +++ b/euro-truck-simulator-2/template.yaml @@ -24,7 +24,7 @@ spec: connects via container PTY stdin/stdout. Server state and configs persist under the user profile directory. - image: ghcr.io/valgulnecron/gameplane/euro-truck-simulator-2:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 + image: ghcr.io/gameplanepanel/gameplane/euro-truck-simulator-2:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 env: - name: HOME diff --git a/farming-simulator-25/Dockerfile b/farming-simulator-25/Dockerfile deleted file mode 100644 index 4bd8bb4..0000000 --- a/farming-simulator-25/Dockerfile +++ /dev/null @@ -1,51 +0,0 @@ -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/farming-simulator-25/entrypoint.sh b/farming-simulator-25/entrypoint.sh deleted file mode 100644 index e2d3082..0000000 --- a/farming-simulator-25/entrypoint.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/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/farming-simulator-25/specs.md b/farming-simulator-25/specs.md index b64fd2f..43e6bf2 100644 --- a/farming-simulator-25/specs.md +++ b/farming-simulator-25/specs.md @@ -11,7 +11,7 @@ ## 2. Container Image & Architecture -- **Base Image**: `ghcr.io/valgulnecron/gameplane/farming-simulator-25:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` +- **Base Image**: `ghcr.io/gameplanepanel/gameplane/farming-simulator-25:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` - **Architecture**: `linux/amd64` - **Runtime Model**: Headless Wine and dummy X11 (Xvfb) supervising the GIANTS dedicated server and web admin portal in a single-pod architecture (FR-012). - **User & Execution Context**: UID `1000`, GID `1000`, working directory `/serverdata`. diff --git a/farming-simulator-25/template.yaml b/farming-simulator-25/template.yaml index 07c75bf..7d3c06b 100644 --- a/farming-simulator-25/template.yaml +++ b/farming-simulator-25/template.yaml @@ -25,7 +25,7 @@ spec: an integrated web management portal. Remote control and state management use the web portal REST API. - image: ghcr.io/valgulnecron/gameplane/farming-simulator-25:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 + image: ghcr.io/gameplanepanel/gameplane/farming-simulator-25:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 env: - name: HOME diff --git a/fivem/Dockerfile b/fivem/Dockerfile deleted file mode 100644 index d018e60..0000000 --- a/fivem/Dockerfile +++ /dev/null @@ -1,43 +0,0 @@ -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/fivem/entrypoint.sh b/fivem/entrypoint.sh deleted file mode 100644 index e5cce04..0000000 --- a/fivem/entrypoint.sh +++ /dev/null @@ -1,106 +0,0 @@ -#!/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/fivem/specs.md b/fivem/specs.md index 5eb3962..793d08c 100644 --- a/fivem/specs.md +++ b/fivem/specs.md @@ -11,7 +11,7 @@ ## 2. Container Image & Architecture -- **Base Image**: `ghcr.io/valgulnecron/gameplane/fivem:latest` +- **Base Image**: `ghcr.io/gameplanepanel/gameplane/fivem:latest` - **Architecture**: `linux/amd64` - **Runtime Model**: CitizenFX server supervised alongside embedded MariaDB and txAdmin in a single-pod architecture (FR-012). - **User & Execution Context**: UID `1000`, GID `1000`, working directory `/server-data`. diff --git a/fivem/template.yaml b/fivem/template.yaml index 9ed60fb..fade668 100644 --- a/fivem/template.yaml +++ b/fivem/template.yaml @@ -25,7 +25,7 @@ spec: database supervision. Remote console and commands operate via txAdmin's REST API. - image: ghcr.io/valgulnecron/gameplane/fivem:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 + image: ghcr.io/gameplanepanel/gameplane/fivem:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 env: - name: HOME From 1d72bb763e250c16caab46fc5ec0b60b1f6a19d6 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 11 Oct 2026 02:23:52 +0000 Subject: [PATCH 6/6] fix(modules): pin fivem, beammp, fs25 and ets2 to published images Replace the placeholder digest with the real one for the four images published and cosign-signed by GameplanePanel/Gameplane#651 (T141). Co-Authored-By: Claude Opus 5.5 (1M context) Signed-off-by: Claude --- beammp/specs.md | 2 +- beammp/template.yaml | 2 +- euro-truck-simulator-2/specs.md | 2 +- euro-truck-simulator-2/template.yaml | 2 +- farming-simulator-25/specs.md | 2 +- farming-simulator-25/template.yaml | 2 +- fivem/specs.md | 2 +- fivem/template.yaml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/beammp/specs.md b/beammp/specs.md index 562e90e..71311d7 100644 --- a/beammp/specs.md +++ b/beammp/specs.md @@ -11,7 +11,7 @@ ## 2. Container Image & Architecture -- **Base Image**: `ghcr.io/gameplanepanel/gameplane/beammp:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` +- **Base Image**: `ghcr.io/gameplanepanel/gameplane/beammp:latest@sha256:4c4ffee19ca8013cacbbdf8e65e0fe09109ab99c8607313daa4f688bab8b9391` - **Architecture**: `linux/amd64` - **Runtime Model**: Standalone C++ binary (`BeamMP-Server`) executing natively under Alpine Linux. - **User & Execution Context**: UID `1000`, GID `1000`, working directory `/serverdata`. diff --git a/beammp/template.yaml b/beammp/template.yaml index f34cb3f..85c32f3 100644 --- a/beammp/template.yaml +++ b/beammp/template.yaml @@ -24,7 +24,7 @@ spec: Interactive console connects via container PTY stdin/stdout. Mods and custom vehicle/map packages install into the Resources directory. - image: ghcr.io/gameplanepanel/gameplane/beammp:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 + image: ghcr.io/gameplanepanel/gameplane/beammp:latest@sha256:4c4ffee19ca8013cacbbdf8e65e0fe09109ab99c8607313daa4f688bab8b9391 env: - name: HOME diff --git a/euro-truck-simulator-2/specs.md b/euro-truck-simulator-2/specs.md index 04cf87f..33268fd 100644 --- a/euro-truck-simulator-2/specs.md +++ b/euro-truck-simulator-2/specs.md @@ -11,7 +11,7 @@ ## 2. Container Image & Architecture -- **Base Image**: `ghcr.io/gameplanepanel/gameplane/euro-truck-simulator-2:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` +- **Base Image**: `ghcr.io/gameplanepanel/gameplane/euro-truck-simulator-2:latest@sha256:170562b495bca0535830ada89d9d01b52d94e79c99a2354b2cffcb72103a19f5` - **Architecture**: `linux/amd64` - **Runtime Model**: Linux 64-bit standalone dedicated server binary (`eurotrucks2_server`) managed by Gameplane supervisor script. - **User & Execution Context**: UID `1000`, GID `1000`, working directory `/serverdata`. diff --git a/euro-truck-simulator-2/template.yaml b/euro-truck-simulator-2/template.yaml index 6b7828a..07b4112 100644 --- a/euro-truck-simulator-2/template.yaml +++ b/euro-truck-simulator-2/template.yaml @@ -24,7 +24,7 @@ spec: connects via container PTY stdin/stdout. Server state and configs persist under the user profile directory. - image: ghcr.io/gameplanepanel/gameplane/euro-truck-simulator-2:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 + image: ghcr.io/gameplanepanel/gameplane/euro-truck-simulator-2:latest@sha256:170562b495bca0535830ada89d9d01b52d94e79c99a2354b2cffcb72103a19f5 env: - name: HOME diff --git a/farming-simulator-25/specs.md b/farming-simulator-25/specs.md index 43e6bf2..463e310 100644 --- a/farming-simulator-25/specs.md +++ b/farming-simulator-25/specs.md @@ -11,7 +11,7 @@ ## 2. Container Image & Architecture -- **Base Image**: `ghcr.io/gameplanepanel/gameplane/farming-simulator-25:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000` +- **Base Image**: `ghcr.io/gameplanepanel/gameplane/farming-simulator-25:latest@sha256:a19a825612a2a77b5a27224bcd4c3362e604ec4b962d4f77e1cbb22c71f2773f` - **Architecture**: `linux/amd64` - **Runtime Model**: Headless Wine and dummy X11 (Xvfb) supervising the GIANTS dedicated server and web admin portal in a single-pod architecture (FR-012). - **User & Execution Context**: UID `1000`, GID `1000`, working directory `/serverdata`. diff --git a/farming-simulator-25/template.yaml b/farming-simulator-25/template.yaml index 7d3c06b..9839a6d 100644 --- a/farming-simulator-25/template.yaml +++ b/farming-simulator-25/template.yaml @@ -25,7 +25,7 @@ spec: an integrated web management portal. Remote control and state management use the web portal REST API. - image: ghcr.io/gameplanepanel/gameplane/farming-simulator-25:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 + image: ghcr.io/gameplanepanel/gameplane/farming-simulator-25:latest@sha256:a19a825612a2a77b5a27224bcd4c3362e604ec4b962d4f77e1cbb22c71f2773f env: - name: HOME diff --git a/fivem/specs.md b/fivem/specs.md index 793d08c..a59410f 100644 --- a/fivem/specs.md +++ b/fivem/specs.md @@ -11,7 +11,7 @@ ## 2. Container Image & Architecture -- **Base Image**: `ghcr.io/gameplanepanel/gameplane/fivem:latest` +- **Base Image**: `ghcr.io/gameplanepanel/gameplane/fivem:latest@sha256:23d65f59793e5f207c4c4ee5c320bca5aa56003fd95be259a887f4e58f3d77b1` - **Architecture**: `linux/amd64` - **Runtime Model**: CitizenFX server supervised alongside embedded MariaDB and txAdmin in a single-pod architecture (FR-012). - **User & Execution Context**: UID `1000`, GID `1000`, working directory `/server-data`. diff --git a/fivem/template.yaml b/fivem/template.yaml index fade668..41dd62c 100644 --- a/fivem/template.yaml +++ b/fivem/template.yaml @@ -25,7 +25,7 @@ spec: database supervision. Remote console and commands operate via txAdmin's REST API. - image: ghcr.io/gameplanepanel/gameplane/fivem:latest@sha256:0000000000000000000000000000000000000000000000000000000000000000 + image: ghcr.io/gameplanepanel/gameplane/fivem:latest@sha256:23d65f59793e5f207c4c4ee5c320bca5aa56003fd95be259a887f4e58f3d77b1 env: - name: HOME