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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions ark-survival-evolved/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.

Expand All @@ -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

Expand Down
2 changes: 1 addition & 1 deletion ark-survival-evolved/module.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down
5 changes: 3 additions & 2 deletions ark-survival-evolved/samples/gameserver.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ 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:
expose: NodePort
portOverrides:
- name: game
nodePort: 30777
- name: raw
nodePort: 30778
- name: query
nodePort: 32015

Expand Down
31 changes: 17 additions & 14 deletions ark-survival-evolved/specs.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

---

Expand All @@ -26,28 +26,31 @@ 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) |

---

## 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.

---

## 5. Administration & Remote Console (RCON)

- **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`).

---
Expand All @@ -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.

---

Expand Down
70 changes: 53 additions & 17 deletions ark-survival-evolved/template.yaml
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand All @@ -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}
Expand All @@ -62,7 +102,7 @@ spec:
rcon:
protocol: source
port: 27020
passwordEnv: RCON_PASSWORD
passwordEnv: ADMIN_PASSWORD

consoleMode: rcon

Expand Down Expand Up @@ -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"
Expand Down
Loading