8.6 KiB
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.
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 selection remains a separate per-instance setting.
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, because game-container UID/GID remains a per-instance choice. 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:
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:
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.