70 lines
8.6 KiB
Markdown
70 lines
8.6 KiB
Markdown
# Deployment and release
|
|
|
|
## Production deployment
|
|
|
|
DoGaMa V1 targets one Linux Docker host with the Compose plugin. The root `compose.yaml` deliberately contains only `dogama` and `agent`; it does not include a reverse proxy. Place its published HTTP service behind the trusted Traefik, Caddy, Nginx, HAProxy, NAS proxy, or other reverse proxy operated by the administrator. Never publish the agent port.
|
|
|
|
```sh
|
|
cp .env.example .env
|
|
docker compose config --quiet
|
|
docker compose pull
|
|
docker compose up -d
|
|
```
|
|
|
|
The deployment has exactly two services: `dogama` and `agent`. On first start, the agent creates its shared token in the internal `agent_auth` volume and the application creates its master encryption key below `DOGAMA_DATA_PATH`. Both use the operating system cryptographic random source, atomic create-without-replacement behavior and restrictive modes. Existing files are validated and reused; an invalid file stops the owning service and is never silently replaced. Secret values never enter `.env`, Compose values, logs, APIs or the UI.
|
|
|
|
The services may start in either order. The application waits up to 60 seconds for the token and an authenticated agent health response. Compose restart policy provides a clean subsequent attempt if the agent or Docker daemon takes longer. An interrupted atomic write leaves no installed partial secret; the next start retries creation. No initializer, setup command or host permission repair is part of this workflow.
|
|
|
|
The application data path contains SQLite, import staging and the application-only master key. The internal `agent_state` volume contains the authenticated container-binding registry; the separate internal `agent_auth` volume contains only the shared token and is mounted read-only at the application's token directory. Both volumes are durable security state: losing either makes existing containers unknown rather than silently adopting them. The application cannot read the registry and the agent never receives the master key.
|
|
|
|
Only host-side storage locations, image version, web port, timezone and the two Docker network names are public Compose settings. `DOGAMA_NETWORK` names the application-facing network used by a reverse proxy. `DOGAMA_GAMES_NETWORK` names the sole network that the restricted agent attaches to created and recreated game containers. API plans contain no caller-selectable network. Container paths and allowed agent roots remain fixed internal contracts. Back up the application data, game servers, backups, `agent_state` and `agent_auth` together.
|
|
|
|
Both services use root inside their container namespaces so Docker-created bind directories and ordinary administrator-selected paths work without knowledge of an image-specific UID/GID. They keep read-only root filesystems, `no-new-privileges`, an empty Linux capability set and a `0077` process umask for new files. The main application never receives the Docker socket. DoGaMa creates only directories it needs below the configured roots and never performs an automatic recursive `chown` of application, server or backup data. Game-container UID/GID defaults are Administration settings and apply only to templates that opt into managed identity; image-defined templates retain their native user.
|
|
|
|
For NAS or server-style paths, set ordinary writable locations in `.env`, for example `/srv/apps/dogama/data`, `/srv/games` and `/srv/backups`, then run `docker compose up -d`. `/var/lib/dogama/templates` is inside `DOGAMA_DATA_PATH`, so it persists as `${DOGAMA_DATA_PATH}/templates` and stays available to Catalog Scan. No `/etc` or host `/var/lib` setup, system user, systemd unit or bootstrap script is required.
|
|
|
|
The containers intentionally run as root only inside their own namespaces so fresh bind mounts work without host-specific UID/GID settings. Their root filesystems are read-only, all capabilities are dropped, and their private `0077` umask makes newly created data private by default. Host paths must be writable by the Docker daemon; do not recursively change ownership. Set `TZ` once to a valid IANA timezone (the example uses `Europe/Paris`); it is used by both services and by Audit rendering.
|
|
|
|
`docker compose down` removes containers and Compose networks while preserving bind mounts and named volumes. `docker compose down -v` also destroys the `agent_state` and `agent_auth` named volumes; it can make existing managed containers impossible to manage safely and must not be used for a retained installation.
|
|
|
|
## Upgrade and rollback
|
|
|
|
The two-service deployment validates and reuses secrets created by its normal first-start contract. The v0.1.0 initializer used a different application-image identity, so do not claim an unverified in-place migration for a v0.1.0 deployment where initialization completed; preserve all five stores and validate that case on a copy before changing production. For normal updates after this correction, stop DoGaMa, take a filesystem-consistent backup of all five persistent stores, replace the canonical `compose.yaml`, change only `DOGAMA_VERSION`, then run `docker compose pull` and `docker compose up -d`. A rollback is a recovery action: restore a backup when required, repin `DOGAMA_VERSION` to the preceding image, and run `docker compose up -d`. Do not assume SQLite schema compatibility in the downgrade direction.
|
|
|
|
Startup initializes a new SQLite database directly from the current schema before serving requests. Development databases from older revisions are intentionally unsupported for now: schema changes can require starting again with an empty application database. Versioned migrations will be introduced before production stabilization. Never remove or recreate `agent_state` or `agent_auth`, and never replace an existing master key: doing so would invalidate the agent registry or make encrypted notification data unreadable.
|
|
|
|
## Backup scope
|
|
|
|
Back up DoGaMa itself as one consistent set: `DOGAMA_DATA_PATH` (SQLite, templates, import staging and the master key), `agent_state`, and `agent_auth`. Back up `DOGAMA_SERVERS_PATH` for game configuration/player data and `DOGAMA_BACKUPS_PATH` for game backup archives separately according to the retention policy. The game-server stores do not replace a backup of DoGaMa's database and security state.
|
|
|
|
## Release pipeline
|
|
|
|
Normal CI runs for pull requests and pushes to `main`; it does not publish images. `.gitea/workflows/release.yml` runs only for tags matching `v*.*.*`, validates the exact tag commit, then publishes the `dogama` and `dogama-agent` images for Linux `amd64` and `arm64`.
|
|
|
|
The external tag keeps its `v` (`v0.1.0`), while container images use `0.1.0`. Stable releases also update `latest`; prerelease tags containing a hyphen never do. Images are published to:
|
|
|
|
```text
|
|
git.zaynet.fr/dogama/dogama:<version>
|
|
git.zaynet.fr/dogama/dogama-agent:<version>
|
|
```
|
|
|
|
The workflow uses the protected Gitea Actions secret `REGISTRY_TOKEN` for registry login and Gitea Release creation. After all validations and both image pushes succeed, it creates `DoGaMa <tag>` against the exact tagged commit with notes derived from actual commit subjects. Tokens are never stored in the repository or printed.
|
|
|
|
The repository owner should protect the Gitea tag pattern `v*` so only authorized accounts can trigger production publication. Do not create a release tag until the candidate commit has passed the full disposable-host verification below.
|
|
|
|
## Release verification
|
|
|
|
Run the complete validation gate in `AGENTS.md`, then verify the release artifacts and both image targets:
|
|
|
|
```sh
|
|
make release VERSION=v0.1.0
|
|
(cd dist/dogama-v0.1.0 && sha256sum -c SHA256SUMS)
|
|
make images VERSION=v0.1.0
|
|
```
|
|
|
|
On an isolated Docker host, start with empty application paths and no `agent_state` or `agent_auth`, then run only `docker compose up -d`. Confirm automatic secret initialization and reuse, authenticated agent health, application bootstrap, Palworld draft/install, lifecycle operations, backup/restore, failed-update rollback, configured game-network attachment and denial against unrelated containers or caller-selected networks. Confirm that only the web port is published, the main application lacks the Docker socket and agent registry, the agent cannot access the master key, and player/backup data survive `docker compose down` followed by `docker compose up -d` without `-v`.
|
|
|
|
## Web access policy
|
|
|
|
HTTP is supported by default for LAN and first-install use. Deploy a trusted TLS reverse proxy for production, then enable Require HTTPS in Settings / Web access if the UI must be HTTPS-only. A canonical base URL is an optional validated HTTP(S) origin without a path. Safe navigation to a noncanonical origin redirects to that origin; mutating requests are refused. Restrict direct backend access when relying on proxy-provided X-Forwarded-Proto.
|