From 368ae918a8b2e96d1c2c0449f606607fc18cd471 Mon Sep 17 00:00:00 2001 From: codex Date: Tue, 25 Aug 2026 22:57:23 +0200 Subject: [PATCH] feat(runtime): add configurable game server uid gid --- catalog/vrising/template.yaml | 4 ++ docs/PROJECT-STATE.md | 5 +- docs/architecture/docker-agent.md | 3 +- docs/domain/data-model.md | 2 +- docs/domain/instance-lifecycle.md | 2 +- docs/operations/deployment-and-release.md | 4 +- docs/operations/instance-operations.md | 2 +- internal/agent/agent_plan.go | 10 ++++ internal/catalog/template.go | 32 +++++++++++-- internal/instance/configuration.go | 2 + internal/instance/configuration_resolver.go | 13 ++--- internal/instance/container_config.go | 26 ++++++++++ internal/instance/container_config_test.go | 13 +++++ internal/instance/preview.go | 38 +++++++++------ internal/instance/preview_test.go | 37 +++++++++++++- internal/instance/process_identity_unix.go | 9 ---- internal/instance/process_identity_windows.go | 8 ---- internal/instance/runtime_user.go | 28 +++++++++++ internal/persistence/sqlite/configuration.go | 47 ++++++++++++++++++ .../sqlite/runtime_identity_test.go | 37 ++++++++++++++ internal/persistence/sqlite/schema.sql | 4 ++ internal/web/i18n.go | 1 + internal/web/server.go | 26 +++++++++- internal/web/server_test.go | 10 +++- internal/web/templates/settings.html | 14 ++++++ internal/web/web_settings.go | 48 +++++++++++++++++++ specs/template.schema.json | 10 ++++ 27 files changed, 382 insertions(+), 53 deletions(-) delete mode 100644 internal/instance/process_identity_unix.go delete mode 100644 internal/instance/process_identity_windows.go create mode 100644 internal/instance/runtime_user.go create mode 100644 internal/persistence/sqlite/runtime_identity_test.go diff --git a/catalog/vrising/template.yaml b/catalog/vrising/template.yaml index 943b363..d40a607 100644 --- a/catalog/vrising/template.yaml +++ b/catalog/vrising/template.yaml @@ -31,6 +31,10 @@ container: image: didstopia/vrising-server tag: latest user_mode: image + runtime_user: + mode: environment + uid_env: PUID + gid_env: PGID stop_timeout_seconds: 120 capabilities: add: diff --git a/docs/PROJECT-STATE.md b/docs/PROJECT-STATE.md index f8d38e5..668b358 100644 --- a/docs/PROJECT-STATE.md +++ b/docs/PROJECT-STATE.md @@ -26,6 +26,7 @@ Read this compact operational baseline before starting a milestone. Open detaile - Backup scheduling/retention, safe imports, export and restore with safety backups. - Sandboxed WASM runtime and normalized module API with Palworld reference adapter. - Game-container configuration: global and per-instance labels, safe label variables, derived instance slug, immutable Docker-user selection, tracked/pinned image tags, immediate or deferred container recreation, and public game-logo/artwork routes. +- Administration stores persistent game-container UID/GID defaults (1000:1000) with decimal uint32 validation. Managed templates use them as Docker `User`; `user_mode: image` is authoritative and omits Docker `User`. Templates can map the values to declared runtime environment variables; V Rising uses `PUID`/`PGID` while retaining its root entrypoint and capabilities. - Controlled digest-aware game updates with confirmation, policy-driven pre-update backups, readiness verification, mod warnings and automatic container-plan rollback. - Redacted configuration history retained to the latest 10 revisions, with pinned-template revalidation and immediate or deferred rollback. - Declarative Steam Workshop item configuration with numeric-ID validation, stable ordering and backend `mods.manage` enforcement. @@ -46,7 +47,7 @@ Read this compact operational baseline before starting a milestone. Open detaile - Service-owned persistent secrets: the agent atomically creates and validates its mode-`0640` shared token in the internal `agent_auth` volume; the application mounts only that secret directory read-only and independently creates and validates its mode-`0600` master key below the application data path. The application tolerates concurrent first start by waiting up to 60 seconds for the token and authenticated agent health. - The agent token is exactly 32 opaque random bytes. Readers preserve terminal carriage-return and newline byte values instead of treating the secret as text. - Two service networks: an administrator-named application/reverse-proxy network plus a private Compose control network. The agent safely ensures the fixed `DOGAMA_GAMES_NETWORK` exists and applies it to every game-container create or replacement; it is not caller-selectable through the lifecycle API. -- Portable fresh bind-mount startup uses root identities inside the read-only, capability-free container namespaces and a private process umask. No recursive ownership change is performed; game-container UID/GID remains per-instance configuration. +- Portable fresh bind-mount startup uses root identities inside the read-only, capability-free container namespaces and a private process umask. No recursive ownership change is performed; game-container UID/GID is controlled by Administration only for managed templates. - Gitea CI for pull requests and `main`, plus tag-only multi-architecture image publication and Gitea Release creation. ## Durable decisions @@ -60,7 +61,7 @@ Read this compact operational baseline before starting a milestone. Open detaile - Template game artwork contains separate required local `logo` and horizontal `image` assets; template validation rejects missing files. Deployment previews expose distinct logo and artwork URLs while retaining `icon_url` as a compatible logo alias. Palworld template `1.1.0` is the first snapshot with this contract. - Embedded catalog validation is collection-based: every discovered template is schema- and cross-field-validated, including referenced assets, declared template-local integration modules and ports/configuration. A module bundle lives at `