Install Drawboard
Two ways to run it on your own servers: on Kubernetes with the Helm chart, or with Docker Compose. Either way you need an OIDC provider for sign-in.
One chart, four steps
The chart deploys the backend, the frontend and (optionally) Gotenberg, with NetworkPolicies and hardened pods. The full reference, with every value, is the chart README; this page is the short route.
Prerequisites
- Kubernetes 1.27 or newer, and Helm 3 or 4.
- An OIDC provider (Keycloak, Authelia, Authentik, Zitadel, Entra ID, …).
- An ingress controller. ingress-nginx is the default; others work too.
- A CNI that enforces NetworkPolicy (Cilium, Calico, …), otherwise the policies are silently ignored.
- The images ghcr.io/dergeorg/drawboard-backend and ghcr.io/dergeorg/drawboard-frontend (public, linux/amd64).
Create the key Secret
The backend does not start without file_url_keys and plugin_pseudonym_key, so create this Secret before the first install. The files are mounted under /run/secrets, never as environment variables.
Guest links stay off?
openssl line and the --from-file=guest_signing_keys part. You can add the key later. Create the database Secret
The database password is always a Secret, never a value in a file.
Write my-values.yaml
These are only the required values. Everything else has a default.
Prefer the chart's own PostgreSQL for a lab or a small install? Replace the postgresql block with this. For anything bigger, use an external or operator-managed database and keep backups with a tested restore.
trustedProxies must be your pod CIDR(s)
X-Forwarded-For only from the addresses listed here: the pod CIDR(s) of the ingress controller and the frontend pods. Empty means nobody is trusted and the rate limits count all users together; too wide and a client can name its own address. The chart README shows how to find them. Install
Pick a chart version from the releases of the repository and install. Every chart version names the backend and frontend releases it was checked with.
Then open publicUrl and sign in. The install prints the exact redirect URIs your OIDC client needs; they are also listed on the OIDC page.
Upgrade, rollback, uninstall
The backend keeps tickets, rooms and sequence numbers in memory and runs as one replica with the Recreate strategy. An upgrade therefore means a short outage; clients reconnect and lose nothing. helm uninstall keeps the database volume and the files volume.
Before enabling guest links
Guest links let people without an account open a board (view, comment or edit, as the link says). Every control is in the release; these conditions are yours as the operator. Do all of them before setting guests.enabled=true.
- Trusted proxies set and verified: open a guest link with a wrong token and check that the audit event library.share.exchange-failed carries your real client address, not a pod or node address.
- The signing key (guest_signing_keys) only as a Secret file, never as a value in a file in git.
- TLS and headers verified end to end: a board page answers with Referrer-Policy: no-referrer and the frontend’s Content-Security-Policy.
- Backups with a tested restore of the database and the files volume. A guest with an editor link can change and delete content like a signed-in editor.
- Know what an editor link allows: hand out viewer or comment links unless editing is the point, and revoke links you no longer need.
- Third-party plugins additionally need plugins.origin on a separate hostname. A plugin can still send what it is shown to its own servers: install only plugins you trust.
One host, one compose file
For a single server without Kubernetes. You need Docker with Compose v2, a reverse proxy that terminates TLS in front of it, and an OIDC provider for sign-in. The stack runs the frontend (nginx, the only port), the backend, PostgreSQL and Gotenberg for Office documents.
Try it in five minutes
Everything runs on your machine, with a bundled Keycloak and three users. Nothing to configure.
Open http://localhost:8080 and sign in as anna / anna (admin), ben / ben or chris / chris. Open a second browser or a private window as another user to see live collaboration.
Local only
Stop it again:
Install on a server
Prerequisites
- A Linux server with Docker and Compose v2.
- A domain, and a reverse proxy that terminates TLS in front of the stack (nginx, Caddy, ...).
- An OIDC provider (Keycloak, Authelia, Authentik, ...).
Get the files
Take the compose folder of the repository onto the server. Three files matter: docker-compose.yml, .env.example and generate-keys.sh.
Generate the keys
The script creates keys/file_url_keys, keys/plugin_pseudonym_key and keys/guest_signing_keys. It never overwrites existing ones.
Keep the keys
Configure .env
Copy the example and set at least PUBLIC_URL, OIDC_ISSUER_URI and DB_PASSWORD.
.env.example has more options with comments. The identity provider is described below.
Put a reverse proxy in front
Forward https://<your host> to http://127.0.0.1:8080 (the HTTP_PORT), with WebSocket upgrade allowed and X-Forwarded-For appended. For nginx:
With Caddy one line does all of that by itself:
Start it
Sign in
Open PUBLIC_URL and sign in. Users are created on their first sign-in; members of ADMIN_GROUP are instance admins.
Identity provider
Drawboard speaks plain OpenID Connect. The provider needs a public client drawboard with authorization code and PKCE (S256), the exact redirect URIs <PUBLIC_URL>/auth/callback and <PUBLIC_URL>/silent-renew.html, and signed JWT access tokens whose audience is drawboard-api. If the backend reaches the provider under another address than the issuer, set OIDC_JWK_SET_URI. The full list, with notes for Keycloak, Authelia and Authentik.
Trusted proxies
The backend believes X-Forwarded-For only from TRUSTED_PROXIES. It must list the frontend's network (WEB_SUBNET) and, if your reverse proxy runs on another host or in another Docker network, its address. Wrong values make every user look like one address, and the rate limits then count all users together. Check it once: open PUBLIC_URL/s/x (a made-up guest link) and find the audit event library.share.exchange-failed in the backend log; its ip must be your real client address. If WEB_SUBNET overlaps a network on your host, change both values.
Update and backup
Migrations run on start and there is no automatic rollback, so back up first.
Back up the database (or the volume drawboard_db-data), the volume drawboard_files, and keys/ and .env. Test a restore.
Before enabling guest links
GUESTS_ENABLED=true lets people without an account open boards through shared links. Do these first: trusted proxies verified (above); keys/guest_signing_keys kept secret; TLS and the headers Referrer-Policy: no-referrer and Content-Security-Policy checked through your reverse proxy; tested backups. Guests on editor links can change content, so hand out viewer or comment links unless editing is the point. Third-party plugins additionally need their own hostname (PLUGIN_ORIGIN, proxied to the same frontend port). The Kubernetes checklist above has the details.
Next: connect your sign-in
Drawboard speaks standard OIDC. See what your provider needs.