From 1c28ecbb7cf03ab72e317fe6608af65da0d33dc7 Mon Sep 17 00:00:00 2001 From: jester Date: Sun, 15 Mar 2026 22:59:20 +0000 Subject: [PATCH] =?UTF-8?q?Update=20DEV=5FCONTAINER=5FSPEC=20=E2=80=94=20r?= =?UTF-8?q?emove=20Traefik=20model,=20document=20API=20proxy=20+=20Headsca?= =?UTF-8?q?le=20access?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DEV_CONTAINER_SPEC.md | 367 +++++++++++++----------------------------- 1 file changed, 109 insertions(+), 258 deletions(-) diff --git a/DEV_CONTAINER_SPEC.md b/DEV_CONTAINER_SPEC.md index 40266a0..db3b7c2 100644 --- a/DEV_CONTAINER_SPEC.md +++ b/DEV_CONTAINER_SPEC.md @@ -1,18 +1,22 @@ # ZeroLagHub Developer Container Architecture -This document describes how developer containers are provisioned and managed by the zlh-agent. - -It is intended for engineers and AI assistants working on the ZeroLagHub platform. +This document describes how developer containers are provisioned and accessed. --- ## Overview -Developer containers provide ephemeral development environments for building and testing software. +Developer containers provide ephemeral development environments. -They support multiple runtimes and optional development tooling. +Provisioning is performed by the **zlh-agent** using runtime artifacts. -Provisioning is performed by the zlh-agent using an artifact-driven runtime system. +Supported runtimes: + +- node +- python +- go +- java +- dotnet --- @@ -20,135 +24,41 @@ Provisioning is performed by the zlh-agent using an artifact-driven runtime syst Provisioning flow: -1. Portal sends dev container request -2. API builds agent provisioning payload -3. Agent validates request -4. Agent creates dev environment -5. Agent installs runtime from artifact server -6. Agent optionally installs addons -7. Agent marks container ready -8. API applies dev routing if code-server is enabled +1. Portal sends dev request +2. API builds provisioning payload +3. Agent installs runtime +4. Agent installs addons +5. Agent marks container ready -High-level architecture: +Architecture: ``` Portal ↓ -zlh-api +zpack-api ↓ zlh-agent ↓ Artifact Server ``` -If `enable_code_server=true`, the API additionally performs: - -- Cloudflare DNS record creation -- Technitium DNS record creation -- Traefik dynamic config write on `zlh-zpack-proxy` - -This routing path is additive and does not modify the game publish flow. - --- -## Dev Provisioning Payload - -The API sends configuration to the agent via: +## Dev Environment ``` -POST http://:18888/config +user: dev +home: /home/dev +workspace: /home/dev/workspace ``` -Dev payload example: - -```json -{ - "container_type": "dev", - "runtime": "node", - "version": "22", - "memory_mb": 2048, - "enable_code_server": true -} -``` - -Fields: - -| Field | Description | -|-------|-------------| -| `container_type` | must be `"dev"` | -| `runtime` | runtime id | -| `version` | runtime version | -| `memory_mb` | container memory | -| `enable_code_server` | optional addon | - ---- - -## Runtime Catalog - -All dev runtimes are defined by the artifact server catalog. - -Catalog location: - -``` -http:///devcontainer/_catalog.json -``` - -Example catalog: - -```json -{ - "runtimes": [ - { "id": "go", "versions": ["1.22", "1.25"] }, - { "id": "java", "versions": ["17", "19", "21"] }, - { "id": "node", "versions": ["20", "22", "24"] }, - { "id": "python", "versions": ["3.10", "3.11", "3.12", "3.13"] }, - { "id": "dotnet", "versions": ["8.0", "10.0"] } - ] -} -``` - -The agent validates runtime/version against this catalog before installation. - -Invalid combinations cause provisioning to fail. - ---- - -## Artifact Server Layout - -Dev runtime artifacts: - -``` -devcontainer/ - _catalog.json - go/ - node/ - python/ - java/ - dotnet/ -``` - -Example runtime artifact: - -``` -devcontainer/node/22/node-22.tar.xz -``` - -Addon artifacts: - -``` -addons/ - code-server/ -``` - -Artifacts are downloaded at provisioning time. - -Nothing is preinstalled inside containers. +Console sessions run as the dev user. --- ## Runtime Installation -Runtime install path: +Runtime path: ``` /opt/zlh/runtimes// @@ -167,110 +77,19 @@ Install guards prevent reinstall — if the directory already exists, installati --- -## Dev Environment - -Every dev container has a dedicated development user. - -``` -user: dev -home: /home/dev -workspace: /home/dev/workspace -ownership: dev:dev -``` - -The workspace is where developers store source code. - ---- - -## Console Behavior - -Dev console sessions run as the dev user. - -Shell properties: - -``` -user: dev -cwd: /home/dev/workspace -HOME=/home/dev -TERM=xterm-256color -``` - -This prevents root access in development environments. - ---- - -## File System Access - -Dev containers expose a file browser rooted at: - -``` -/home/dev/workspace -``` - -Portal displays this as `workspace/`. - -Uploads and file operations are restricted to this directory. - -Dev containers have unrestricted read/write access inside `/home/dev/workspace`. No allowlist. The only hard rule is the root sandbox — nothing can escape the workspace. - ---- - -## Dotnet Runtime - -Dotnet uses the official installer script. - -Installer source: - -``` -http://artifact-server/devcontainer/dotnet/dotnet-install.sh -``` - -Installation: - -```bash -./dotnet-install.sh --channel 8.0 -``` - -Installed to: - -``` -/opt/zlh/runtimes/dotnet/8.0 -``` - -Supported channels: `8.0`, `10.0` - ---- - ## Code Server Addon -Code-server provides a browser IDE. +Code-server provides browser IDE access. -Enabled via provisioning flag: - -```json -"enable_code_server": true -``` - -Artifact location: - -``` -http://artifact-server/addons/code-server/code-server.zip -``` - -Installed to: +Install location: ``` /opt/zlh/services/code-server ``` -Launch behavior: +Port: `6000` -- process runs inside the container -- binds to `0.0.0.0:6000` -- workspace root is `/home/dev/workspace` -- current auth mode observed in runtime is password-based - -Observed process shape: +Observed process: ```bash /opt/zlh/services/code-server/lib/node /opt/zlh/services/code-server \ @@ -281,62 +100,100 @@ Observed process shape: --- -## Dev Routing +## Dev IDE Access Model -When code-server is enabled, the API creates a dev-only routing path. - -Current implementation: - -- creates Technitium A record for `dev-.` -- creates Cloudflare A record for `dev-.` -- writes Traefik dynamic config on the proxy VM via SSH service account `zlh` -- dynamic file path: `/etc/traefik/dynamic/dev-.yml` - -Current backend target model: - -``` -Host(`dev-.`) - → Traefik (websecure) - → http://:6000 -``` - -Status: routing generation is implemented, but external browser access remains under active validation. +The previous model using Cloudflare DNS, Traefik, and per-container subdomains has been removed. --- -## Agent Status Model +### Browser IDE Access (Primary) -Status delivery model is unchanged: +IDE is accessed through the API proxy. -- API polls agent `/status` -- agent does not push state to API +``` +Browser + ↓ +Portal + ↓ +API + ↓ +container:6000 +``` -Status content now includes dev/container fields: +URL format: `/dev//ide` -- `workspaceRoot` -- `serverRoot` -- `runtimeInstallPath` -- `runtimeInstalled` -- `devProvisioned` -- `devReadyAt` -- `codeServerInstalled` -- `codeServerRunning` -- `lastCrashClassification` +code-server launch flags required: -The API now exposes this polled state back to the frontend through a server status endpoint so console and host-state UI can update correctly. +``` +--base-path /dev//ide --auth none +``` + +Portal JWT authentication gates access. The API verifies container ownership before proxying. + +WebSocket support is mandatory — code-server is heavily WebSocket-based: + +- `http-proxy-middleware` with `ws: true` +- `server.on('upgrade', proxy.upgrade)` must be wired up + +--- + +### Local Development Access (Advanced Users) + +Advanced users may connect via **Headscale/Tailscale**. + +Benefits: + +- SSH +- VS Code Remote +- full local tooling + +Implementation: + +- dev container installs `tailscaled` as an addon +- API generates Headscale auth key on provisioning +- customer joins tailnet once, gets stable container IP + +Restrictions: + +- no exit nodes +- `magic_dns: false` +- no DNS takeover on customer machine + +Headscale server: `zlh-ctl` (status to be confirmed) --- ## Security Model -Dev containers are isolated LXC containers. - -Security controls: - -- Runtime installs limited to `/opt/zlh` -- File browser limited to workspace +- Portal authentication controls IDE access +- API verifies container ownership before proxying +- Containers are never exposed directly to the public internet - Shell runs as non-root `dev` user -- Artifacts fetched only from trusted artifact server +- File browser limited to workspace root + +--- + +## File Browser + +Workspace root: `/home/dev/workspace` + +Portal displays this as `workspace/`. + +Uploads cannot escape this directory. + +--- + +## Agent Status + +Status is polled by API via `/status`. Agent does not push state. + +Dev fields in `/status`: + +- `workspaceRoot` +- `runtimeInstallPath` +- `runtimeInstalled` +- `codeServerInstalled` +- `codeServerRunning` --- @@ -347,6 +204,7 @@ Security controls: 3. Runtime catalog is the source of truth 4. Installs must be idempotent 5. Containers must remain reproducible +6. Dev services are never publicly exposed directly --- @@ -355,12 +213,5 @@ Security controls: - Runtime checksum validation - Runtime upgrades / removal - Artifact metadata support -- Service port auto-detection -- Dev service routing / proxy exposure -- IDE launch integration from portal - ---- - -## Summary - -Developer containers in ZeroLagHub provide isolated development environments with multiple runtime support, artifact-driven installs, optional browser IDE on port 6000, and consistent reproducible provisioning. +- Tailscale addon implementation +- Headscale auth key portal UI