diff --git a/ark-survival-evolved/README.md b/ark-survival-evolved/README.md index f0ec546..976ebf7 100644 --- a/ark-survival-evolved/README.md +++ b/ark-survival-evolved/README.md @@ -2,6 +2,8 @@ ARK: Survival Evolved dedicated server package for Gameplane. Runs on Linux with persistent world state, Steam A2S server browser discovery, Source RCON console, and multi-server cluster transfer support. +The module runs the community image [`hermsi/ark-server`](https://github.com/Hermsi1337/docker-ark-server), pinned by digest. The image installs and updates the server with SteamCMD on start and runs it under [arkmanager](https://github.com/arkmanager/ark-server-tools). + ## Install ```sh @@ -10,7 +12,7 @@ kubectl apply -f modules/ark-survival-evolved/template.yaml ## Console & RCON -Remote management uses standard Source RCON on port 27020 TCP. The operator injects the password via `RCON_PASSWORD`. Console actions include `ServerChat` (broadcast), `SaveWorld` (world flush), and `KickPlayer` (moderation). +Remote management uses standard Source RCON on port 27020 TCP. The operator generates the password and injects it as `ADMIN_PASSWORD`, which the image uses as the server admin and RCON password. Console actions include `ServerChat` (broadcast), `SaveWorld` (world flush), and `KickPlayer` (moderation). The server stops cleanly by issuing `SaveWorld` and `DoExit` prior to container termination. @@ -19,14 +21,27 @@ The server stops cleanly by issuing `SaveWorld` and `DoExit` prior to container | Name | Port | Protocol | Advertised | Purpose | | ---- | ---- | -------- | ---------- | ------- | | `game` | 7777 | UDP | yes | Primary gameplay traffic | +| `raw` | 7778 | UDP | yes | Raw UDP socket (always game port + 1) | | `query` | 27015 | UDP | yes | Steam A2S browser query | | `rcon` | 27020 | TCP | no | Source RCON administration | ## Storage & Cluster Travel -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. +The data volume is mounted at `/app` (35 GiB default). The game is installed in `/app/server` on first start, and map saves, tribe data and player profiles persist under `/app/server/ShooterGame/Saved`. arkmanager keeps its configuration in `/app/arkmanager` and its logs in `/app/log`. + +Cluster transfer data (uploaded survivors, dinos and items) lives in a second 1 GiB volume at `/cluster`. To enable cluster travel between multiple ARK servers, supply the same `CLUSTER_ID` in each server's configuration and share or synchronize the `/cluster` folder. + +## Security + +The image starts as root and drops to the `steam` user (UID/GID 1000) in its entrypoint, so the template sets only `fsGroup: 1000`. It does not run when the operator enforces restricted workloads (`enforceRestricted: true`), which needs a non-root image. + +## Upgrading from 1.x + +Version 1.x ran a Gameplane-built image with the volume at `/data`. Version 2.0.0 changes three things: -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. +- **Data layout.** The install and saves move from the volume root to `server/` inside it. Before you start an existing server on 2.0.0, stop it and move everything at the root of its data volume into a new `server/` subfolder. If you skip this, the server installs again and starts a new world. +- **Cluster data.** It moves from `ShooterGame/Saved/clusters` to the new `/cluster` volume. Copy the folder contents over if you use cluster travel. +- **Config keys.** `MAP_NAME` is now `SERVER_MAP`, and `RCON_PASSWORD` is gone because the operator manages the RCON password. Rename or remove those keys in each GameServer, or the operator rejects it as having unknown config keys. ## Sample diff --git a/ark-survival-evolved/module.yaml b/ark-survival-evolved/module.yaml index 139d8fb..8fe6eed 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.1.0 +version: 2.0.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/samples/gameserver.yaml b/ark-survival-evolved/samples/gameserver.yaml index 2af3188..f57e696 100644 --- a/ark-survival-evolved/samples/gameserver.yaml +++ b/ark-survival-evolved/samples/gameserver.yaml @@ -10,9 +10,8 @@ spec: config: SESSION_NAME: "Gameplane ARK Server" SERVER_PASSWORD: "" - RCON_PASSWORD: "secret-rcon-password" MAX_PLAYERS: "70" - MAP_NAME: "TheIsland" + SERVER_MAP: "TheIsland" CLUSTER_ID: "cluster-alpha" networking: @@ -20,6 +19,8 @@ spec: portOverrides: - name: game nodePort: 30777 + - name: raw + nodePort: 30778 - name: query nodePort: 32015 diff --git a/ark-survival-evolved/specs.md b/ark-survival-evolved/specs.md index fe46080..8f8e1d1 100644 --- a/ark-survival-evolved/specs.md +++ b/ark-survival-evolved/specs.md @@ -11,11 +11,11 @@ ## 2. Container Image & Architecture -- **Base Image**: `ghcr.io/gameplanepanel/gameplane/ark-survival-evolved:latest@sha256:2a4298f8055dbff4107c49c961cace1f2bed42809e6b93fb4924371ae4484e58` +- **Base Image**: `hermsi/ark-server:latest@sha256:ce291990613e76f7019be31b96fe247188ce4957724c913c0e30097042c44bf5` - **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 10000, GID 10000, working directory `/data`. +- **Image Source**: Community image from https://github.com/Hermsi1337/docker-ark-server, rebuilt weekly on `cm2network/steamcmd`. Chosen over a Gameplane-built image on 2026-11-11 (maintainer ruling: use a maintained public image when one exists). +- **Runtime Model**: SteamCMD Linux dedicated server (`ShooterGameServer`), installed, updated and run by arkmanager (`arkmanager run`). +- **User & Execution Context**: Starts as root, then drops to `steam` (UID/GID 1000) with gosu. Working directory `/app`. --- @@ -26,6 +26,7 @@ Declared ports under `spec.ports`: | Port Name | Container Port | Protocol | Usage / Purpose | |---|---|---|---| | `game` | 7777 | UDP | Primary gameplay traffic | +| `raw` | 7778 | UDP | Raw UDP socket, always game port + 1 | | `query` | 27015 | UDP | Steam A2S browser discovery | | `rcon` | 27020 | TCP | Remote administrative console (Source RCON) | @@ -33,13 +34,15 @@ Declared ports under `spec.ports`: ## 4. Storage & Persistence Layout -- **Mount Path**: `/data` +- **Mount Path**: `/app` (the image's declared volume) - **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 volume holds the whole install, so nothing in the image is shadowed (the image ships only SteamCMD and the entrypoint). + - Game install (`/app/server`) + - Saved worlds, tribe data, and dinosaur entities (`/app/server/ShooterGame/Saved/SavedArks/`) + - Server configuration files (`/app/server/ShooterGame/Saved/Config/LinuxServer/GameUserSettings.ini`) + - arkmanager configuration, logs and update staging (`/app/arkmanager`, `/app/log`, `/app/staging`) +- **Extra Volume**: `cluster`, `1Gi`, mounted at `/cluster` for cross-server cluster transfers (the image sets `-ClusterDirOverride=/cluster` when `CLUSTER_ID` is set). +- **Non-Shadowing Invariant**: The image's entrypoints live in `/`, outside both mounts, and `/app` holds no baked game content. --- @@ -47,7 +50,7 @@ Declared ports under `spec.ports`: - **Protocol**: `source` - **Console Mode**: `rcon` -- **Authentication**: Password supplied via `RCON_PASSWORD`. +- **Authentication**: The operator-generated password is supplied via `ADMIN_PASSWORD` (`rcon.passwordEnv`), which arkmanager writes as `ServerAdminPassword` with `RCONEnabled=True`. - **Command Support**: In-game moderation (`KickPlayer`, `BanPlayer`), world saving (`SaveWorld`), broadcasts (`ServerChat`). --- @@ -69,15 +72,15 @@ Declared ports under `spec.ports`: - "SaveWorld" - "DoExit" ``` -- **Signal Handling**: Server cleanly saves before terminating on `SIGINT`/`SIGTERM`. +- **Signal Handling**: The image traps `SIGTERM`/`SIGINT` and stops the server through arkmanager, which saves first. --- ## 8. Key Invariants & Security -- **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. +- **No runAsUser**: the image must start as root so its entrypoint can drop to `steam`. It therefore cannot run with the operator's restricted workloads enabled. +- **Filesystem Permissions**: `spec.security.fsGroup: 1000` gives the dropped `steam` user write access to both volumes. +- **Image Defaults Overridden in `spec.env`**: `SERVER_PASSWORD=""` (the image default is `YouShallNotPass`), `UPDATE_ON_START=true` (update on every start, as 1.x did), `PRE_UPDATE_BACKUP=false` (Gameplane runs its own backups), and the four port variables. --- diff --git a/ark-survival-evolved/template.yaml b/ark-survival-evolved/template.yaml index 9630c08..f59dc04 100644 --- a/ark-survival-evolved/template.yaml +++ b/ark-survival-evolved/template.yaml @@ -1,8 +1,12 @@ # yaml-language-server: $schema=../.schema/gametemplate.schema.json # Gameplane GameTemplate for ARK: Survival Evolved (dedicated server). # -# Dedicated server for ARK: Survival Evolved running on Linux. -# The whole ARK install lives under /data; persistent world state and cluster directory live under /data/ShooterGame/Saved. +# Runs the community image hermsi/ark-server +# (https://github.com/Hermsi1337/docker-ark-server), which installs and +# updates the server with SteamCMD and runs it under arkmanager. +# The volume is mounted at /app, the image's own data root: the game install +# lives in /app/server, with saves under /app/server/ShooterGame/Saved. +# Cluster transfer data lives in its own volume at /cluster. # # Cluster-scoped; apply once per cluster: # kubectl apply -f modules/ark-survival-evolved/template.yaml @@ -16,32 +20,62 @@ metadata: spec: displayName: "ARK: Survival Evolved" game: ark-survival-evolved - version: 1.1.0 + version: 2.0.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 `/data/ShooterGame/Saved`, on the same volume as the game install. + and server actions. The game install and world saves live under `/app/server`; + cross-shard cluster transfers live in their own volume at `/cluster`. - image: ghcr.io/gameplanepanel/gameplane/ark-survival-evolved:latest@sha256:2a4298f8055dbff4107c49c961cace1f2bed42809e6b93fb4924371ae4484e58 + image: hermsi/ark-server:latest@sha256:ce291990613e76f7019be31b96fe247188ce4957724c913c0e30097042c44bf5 versions: - id: latest displayName: "Latest" - image: ghcr.io/gameplanepanel/gameplane/ark-survival-evolved:latest@sha256:2a4298f8055dbff4107c49c961cace1f2bed42809e6b93fb4924371ae4484e58 + image: hermsi/ark-server:latest-1794213856@sha256:ce291990613e76f7019be31b96fe247188ce4957724c913c0e30097042c44bf5 default: true + # The image starts as root: its entrypoint fixes volume ownership, loads + # the crontab, then drops to the `steam` user (UID/GID 1000) with gosu. + # Do NOT set runAsUser here, or the entrypoint cannot drop privileges. + # fsGroup lets the dropped user write the PVCs. security: - runAsUser: 10000 - runAsGroup: 10000 - fsGroup: 10000 + fsGroup: 1000 + + env: + # Without these the image's own defaults apply: a server password of + # "YouShallNotPass" and no update on start. An empty SERVER_PASSWORD + # here means an open server; the config field below overrides it. + - name: SERVER_PASSWORD + value: "" + # Update the server through SteamCMD on every start, as 1.x did. + - name: UPDATE_ON_START + value: "true" + # Gameplane runs its own backups; arkmanager's pre-update backup would + # only fill the volume. + - name: PRE_UPDATE_BACKUP + value: "false" + # Gameplane advertises the game port and the raw socket port separately. + - name: GAME_CLIENT_PORT + value: "7777" + - name: UDP_SOCKET_PORT + value: "7778" + - name: SERVER_LIST_PORT + value: "27015" + - name: RCON_PORT + value: "27020" ports: - name: game containerPort: 7777 protocol: UDP advertise: true + # Raw UDP socket, always game port + 1. ARK clients need it to join. + - name: raw + containerPort: 7778 + protocol: UDP + advertise: true - name: query containerPort: 27015 protocol: UDP @@ -53,7 +87,13 @@ spec: storage: size: 35Gi - mountPath: /data + mountPath: /app + extra: + # The image keeps cluster transfer data (uploaded survivors, dinos + # and items) in /cluster, outside /app. + - name: cluster + mountPath: /cluster + size: 1Gi resources: requests: {cpu: "2", memory: 8Gi} @@ -62,7 +102,7 @@ spec: rcon: protocol: source port: 27020 - passwordEnv: RCON_PASSWORD + passwordEnv: ADMIN_PASSWORD consoleMode: rcon @@ -123,15 +163,11 @@ spec: displayName: Server Password type: password default: "" - - name: RCON_PASSWORD - displayName: RCON Password - type: password - default: "" - name: MAX_PLAYERS displayName: Max Players type: int default: 70 - - name: MAP_NAME + - name: SERVER_MAP displayName: Map Name type: string default: "TheIsland"