Self-hosted install
Studios that keep everything on their own network run the Dousen server (DousenCore) themselves with Docker Compose. One container runs the API and web portal, one runs MariaDB; artists' DousenDesktop apps and the Unreal plugin talk to it over plain HTTP/JSON on port 8080.
The deployment bundle ships in the release under deploy/self-hosted/: a docker-compose.yml, an install.sh helper, an annotated .env.example, and SELF_HOSTING.md with operational notes.
Requirements
- A Linux host with Docker and Docker Compose.
- A Dousen license — the token and its public key, issued for your studio.
- Optionally: a Perforce server, a Jira Cloud site, and an LDAP/AD directory to hook up.
Install
-
Copy the bundle and create your env file.
Copy
deploy/self-hosted/to the host and duplicate.env.exampleas.env. Every setting below lives in this file. -
Fill in the required values.
Database passwords, a
DOUSEN_JWT_SECRETof at least 32 characters (the service refuses to start with a shorter one), and your license keys. -
Start it.
SHELL
docker compose up -dThe API container waits for MariaDB to be healthy, runs its migrations, and comes up on port 8080.
-
Verify.
curl http://localhost:8080/healthshould answer, andhttp://<server>:8080/portal/serves the admin portal. From there, follow the Quick start: create users and a project, connect Jira, and roll DousenDesktop out to artists.
Configuration reference
All server configuration is environment variables in .env. The compose file wires them into the containers.
Required
| Variable | Purpose |
|---|---|
| MARIADB_ROOT_PASSWORD | Root password for the bundled MariaDB. |
| MARIADB_USER / MARIADB_PASSWORD | The service account the API uses (default user dousen). |
| DOUSEN_JWT_SECRET | Secret for signing session tokens. Minimum 32 characters. |
| DOUSEN_LICENSE_KEY | Your license token, pasted verbatim. |
| DOUSEN_LICENSE_PUBLIC_KEY_PEM | The public key issued with the license; the server verifies the license offline with it. |
Optional
| Variable | Purpose |
|---|---|
| DOUSEN_CONTROL_PLANE_URL | Where the daily license heartbeat goes. Default https://control.dousen.io. Heartbeat failures never take the server down — offline networks are fine. |
| DOUSEN_P4PORT / DOUSEN_P4USER / DOUSEN_P4CLIENT / DOUSEN_P4PASSWD | The server's Perforce service connection — used for its changelist operations. Artists' own P4 identities live in DousenDesktop, not here. See Perforce. |
| DOUSEN_WEBHOOK_SECRET | Shared secret for the Jira webhook at /webhooks/jira. |
| DOUSEN_BIND_HOST / DOUSEN_REST_PORT | Where the API port is published on the host. Defaults to 127.0.0.1:8080 — loopback only, expecting a reverse proxy in front. Set DOUSEN_BIND_HOST=0.0.0.0 to expose it directly on a trusted LAN. |
| DOUSEN_VERSION | Image tag to run. Defaults to latest; pin a version for controlled upgrades. |
| RUST_LOG | Log level, default info. |
Directory sign-in (LDAP / Active Directory)
By default users sign in with passwords stored on the instance (DOUSEN_AUTH_MODE=local). To delegate to your directory, set DOUSEN_AUTH_MODE=ldap — users are then auto-provisioned on first login, and membership in the admin group grants the admin role. See User & auth management.
| Variable | Purpose |
|---|---|
| DOUSEN_LDAP_URL | Directory server, e.g. ldaps://ad.studio.lan. |
| DOUSEN_LDAP_BIND_DN_TEMPLATE | Template for the bind DN of the signing-in user. |
| DOUSEN_LDAP_USER_SEARCH_BASE / DOUSEN_LDAP_USER_FILTER | Where and how to look users up. |
| DOUSEN_LDAP_ADMIN_GROUP | Directory group whose members become Dousen admins. |
| DOUSEN_LDAP_START_TLS | Enable StartTLS (default false; prefer an ldaps:// URL). |
Operational notes
- Database data lives in the named Docker volume
dousen-mariadb— include it in your backup routine. - Upgrades: bump
DOUSEN_VERSION, thendocker compose pull && docker compose up -d. Migrations run automatically on start. - License renewal: replace
DOUSEN_LICENSE_KEYwith the renewed token and restart. The server verifies licenses offline and keeps running for a 14-day grace window past expiry, so a renewal never has to be a fire drill. - Perforce in Docker: the compose file includes a commented-out
p4dservice if you want a self-contained evaluation stack. - Kubernetes: a Helm chart is available for studios that prefer it over Compose; the same environment variables apply.
The server binds to loopback by default. If artists can't reach it, that's the first thing to check — either front it with a reverse proxy (recommended, and where TLS should terminate) or set DOUSEN_BIND_HOST=0.0.0.0.