Files
2026-08-06 19:21:08 +02:00

86 lines
3.7 KiB
Markdown

# System architecture
## Components
### Main application
A statically deployable Go service owns the HTTP API, embedded web UI, authentication, authorization, SQLite data, catalog, workflows, scheduler, backups, notifications, audit and WebAssembly runtime. It has access only to configured DoGaMa data, server-data roots and backup roots. It does not mount the Docker socket.
### Restricted Docker agent
A separate Go service is the only DoGaMa component with Docker socket access. It is not published on the host. It accepts a small typed operation set, validates every plan against approved roots and signed/registered instance state, and never exposes a generic Docker proxy.
### Managed game servers
Each instance is a Docker container created from an approved template snapshot. Persistent data uses bind mounts below administrator-approved roots. Game ports may be published; management API ports remain private whenever the game permits it.
### WebAssembly adapters
Optional modules translate game-specific APIs to DoGaMa's normalized game API. Modules run inside the main application under a deny-by-default sandbox. They do not orchestrate Docker or files.
## Trust boundaries
```text
Untrusted browser and uploads
|
v
[Main application boundary]
AuthN/AuthZ, workflows, DB, archive validation, WASM runtime
|
| authenticated, private, typed plans
v
[Agent privilege boundary]
plan verification, path/image/port/label enforcement
|
v
[Docker daemon / host boundary]
|
v
[Game container boundary] <--- instance-scoped WASM host networking
```
Templates, manifests, modules, catalog artwork, webhooks, imports and game API responses are untrusted data even when an administrator supplied them.
## Dependency direction
- HTTP and scheduled jobs call application use cases.
- Use cases depend on domain interfaces, not Docker, SQLite or WASM implementations.
- Infrastructure adapters implement persistence, agent client, archive, notification and WASM interfaces.
- The agent has its own domain model and does not import main-application persistence code.
- Game-specific behavior crosses only the normalized module contract.
## Persistence and filesystem layout
Suggested container paths:
```text
/var/lib/dogama/
dogama.db
catalog/
modules/
imports/staging/
cache/
/srv/game-servers/<instance-slug>/
config/
player-data/
mods/
logs/
/srv/game-backups/<instance-id>/
```
Paths stored in SQLite use stable instance and mount identifiers. User-supplied display names never become paths without normalized slug generation and collision checks.
## Communication
- Browser to main application: HTTP(S), JSON API, secure cookie session.
- Main application to agent: private Docker network, request authentication, timestamp/nonce replay protection and bounded request bodies. Same-host V1 may use a shared secret; mTLS is reserved for later multi-host work.
- Main application to game API: only through the WebAssembly host networking interface bound to the instance.
- Main application to notification endpoints: controlled egress with SSRF protections.
## Concurrency and jobs
Long-running operations are durable jobs in SQLite. A per-instance lock serializes mutually exclusive actions. Jobs use explicit phases and checkpoints so a restart can resume, retry safely or mark manual intervention required. UI requests enqueue work and return an operation identifier rather than keeping a long HTTP request open.
The scheduler is internal for V1 and handles cron backups, retention, audit purge, optional start/stop schedules, module/catalog update checks and queued notifications. Only one scheduler leader exists because V1 runs one main-application replica.