Overview
Docmost is an open-source knowledge base and wiki — a Confluence or Notion alternative with real-time collaborative editing, spaces, and per-space permissions. This template deploys the Docmost server (web UI, REST API, and collaboration websocket on port3000) backed by a bundled PostgreSQL for documents and a bundled Redis for job queues and realtime coordination, with attachments kept on a persistent volume or in an S3 bucket you own. The default is a single replica; docmost.replicas scales out once attachments live in S3.
What Gets Created
APP_SECRET, database credentials and Redis password secrets are not created by the template — see Prerequisites.
Prerequisites
Three secrets must exist before installing: theAPP_SECRET Docmost signs sessions, invitation links, and share links with, supplied through an opaque secret, and two dictionary secrets holding the database credentials and the Redis password. The values never pass through Helm values.
Create the APP_SECRET secret
printf rather than echo so the payload carries no trailing newline:secrets.name to this name. Secrets are org-level, so no GVC flag is involved.Back the value up outside Control Plane
APP_SECRET is effectively write-once: rotating it logs out every user and invalidates every outstanding invitation and share link (stored documents are unaffected). Keep a copy somewhere safe.Create the database credentials secret
postgres.config.credentialsSecretName to this name. Secret names are org-wide, so give each Docmost release its own secret. The three values are part of Docmost’s connection URL, so use letters, digits, - and _ only. PostgreSQL reads the secret only when its data is first initialized — see Rotating the Database Password.Create the Redis password secret
password; the bundled Redis requires it and Docmost connects with it:redis.credentialsSecretName to this name. The password is part of Docmost’s Redis URL, so use letters, digits, - and _ only.- S3 attachment storage (required for more than one replica) — an existing bucket plus either an AWS cloud account and bucket-scoped IAM policy, or a static-key secret for an S3-compatible server. See Attachment Storage on S3.
- Authenticated SMTP — a dictionary secret holding
SMTP_USERNAMEandSMTP_PASSWORD. See Email. - Scheduled database backups — a bucket and cloud account for the bundled PostgreSQL. See Backing Up.
Installation
Once your three secrets exist, install from the marketplace registry, pointing the three secret-name keys at them:UI
CLI
Terraform
Pulumi
Configuration
Docmost Server
Prerequisite Secret
Attachment Storage
storage.type decides where uploaded files, images, and avatars are kept. The default local volume works for a single replica; the bucket, cloud account, and secret setup for s3 is under Attachment Storage on S3.
smtp.auth.secretName to its name. The Docmost identity is granted reveal on exactly that secret.
Access
Bundled PostgreSQL
The database is the postgres template as a subchart, so every knob of that template is available underpostgres.*. The database credentials come from your prerequisite dictionary secret (username, password and database — see Prerequisites), named by postgres.config.credentialsSecretName.
Bundled Redis
Redis is required: Docmost’s readiness check pings it alongside the database, and the workload does not become ready without it.Connecting
publicAccess.enabled: false there is no public endpoint; reach the UI from your machine through a tunnel instead and open http://localhost:3000:
First Run
Docmost ships no default account: the first person to reach the instance creates the workspace and its owner account, and that form is open to anyone who can reach the endpoint.Wait for the Docmost workload to report ready
Open the endpoint and claim the workspace
Configure email before inviting anyone
Operations
Attachment Storage on S3
Setstorage.type: s3 to keep attachments in a bucket you own. This is required for more than one replica, and nothing in the template moves existing attachments between the local volume and the bucket — choose the storage type before uploading content.
- AWS S3 (keyless)
- S3-compatible (MinIO and others)
storage.s3.endpoint is set.Create a bucket
storage.s3.bucket and storage.s3.region to match.Set up a cloud account
storage.s3.cloudAccountName to its name.Create a bucket-scoped IAM policy
YOUR_BUCKET_NAME with your bucket), then set storage.s3.policyName to the policy’s name:Leave the key secret empty
storage.s3.auth.secretName empty. The template then attaches the cloud account and your policy to the Docmost identity.Backing Up
Scheduled backups of the bundled PostgreSQL are off by default. Enablingpostgres.backup.enabled: true adds one cron workload, RELEASE_NAME-postgres-backup, that runs pg_dumpall on the schedule and uploads a gzipped dump to your bucket under the configured prefix. Pick a postgres.backup.provider and complete the matching setup before installing or upgrading with it on.
- AWS S3
- Google Cloud Storage
- MinIO / S3-compatible
Create a bucket
postgres.backup.aws.bucket and postgres.backup.aws.region to match.Set up a cloud account
postgres.backup.aws.cloudAccountName to its name.Create a bucket-scoped IAM policy
YOUR_BUCKET_NAME) and set postgres.backup.aws.policyName to its name:RELEASE_NAME-docmost-storage volume set (S3 attachments are already in your bucket), and your APP_SECRET lives in the secret you created. The PostgreSQL volume set RELEASE_NAME-pg-vs takes no scheduled snapshots; a final snapshot is taken when the volume set is deleted and kept 7 days.
Restoring a Backup
Each backup is a gzipped plain-SQLpg_dumpall archive. Restoring means replaying that SQL into the bundled PostgreSQL. The one transport that carries a dump into the container intact is cpln workload exec with --stdin and a base64 wrapper on both ends — raw binary piped through exec is corrupted:
CREATE ROLE and CREATE DATABASE statements, so a straight replay collides with the database Docmost already created and migrated on first boot; and no Docmost replica may be connected while you drop and recreate that database before the replay.
Rotating the Database Password
PostgreSQL keeps the password it was initialized with, and a running workload keeps the values it started with, so a rotation takes three steps in order:-
Change it in the database:
ALTER ROLE DB_USERNAME PASSWORD 'NEW_PASSWORD';(DB_USERNAMEis the secret’susername; connect as that user from inside the GVC). -
Update the secret — export it, change only
password, and apply it: -
Right away, redeploy Docmost, and wait until
get-deploymentsshows a higher version number, alone and ready (ready: truealone can still describe the old replica):Do not redeploy the database: PostgreSQL reads the secret only when it is first initialized, so restarting it only adds downtime.
ALTER ROLE; new ones fail until its redeploy finishes, so redeploy right away and rotate in a quiet window.
Rotating the Redis Password
Redis keeps no password on disk: it takes the password from the secret each time it starts, and so does Docmost.-
Update the secret — export it, change only
password, apply it, and check it: -
Redeploy Redis, then Docmost, and wait until
get-deploymentsshows a higher version number for each, alone and ready:
Upgrading from 1.0.0
postgres.config.username, postgres.config.password and postgres.config.database were removed. Put the values your database was initialized with into the database credentials secret under Prerequisites (keys username, password and database), set postgres.config.credentialsSecretName to its name, and remove the three keys. Then move the Redis password as described in Upgrading from 1.1.0 (1.0.0 kept it in the same RELEASE_NAME-docmost-creds secret).
Upgrading from 1.1.0
postgres.credentials was removed: the database credentials are now a prerequisite secret, the same one the postgres template requires on its own. redis.auth.password was removed too: the Redis password is now a prerequisite secret named by redis.credentialsSecretName. Carrying either old key forward fails the render.
1.1.0 created both secrets itself, so this upgrade deletes them. Before upgrading, create secrets under new names holding the values your release uses today — not new ones, or Docmost loses its database and Redis connections:
postgres.credentials and redis.auth.password of the 1.1.0 release. Then upgrade with postgres.config.credentialsSecretName and redis.credentialsSecretName set to the new names, and with postgres.credentials and redis.auth removed from your values.
The upgrade restarts the bundled PostgreSQL too (it now reads the new secret), so Docmost briefly loses its database; it reconnects by itself. The new version of a workload can also wait several minutes with is not allowed to reveal the secret in get-deployments while access to the new secret propagates; the previous version keeps serving meanwhile, and it clears by itself.
helm upgrade after an install can restart the bundled PostgreSQL even when its values are unchanged, so expect a brief interruption.Scaling and Availability
docmost.replicas sets how many Docmost replicas run. Replicas coordinate through the bundled Redis, which carries both the job queues and the collaborative-editing updates, so a document edited on one replica appears live for a reader connected to another, and no sticky sessions are needed.
Troubleshooting
Deployment never becomes ready and the logs are empty
Deployment never becomes ready and the logs are empty
cpln helm install reported success, cpln logs returns nothing, and cpln workload get-deployments RELEASE_NAME-docmost --gvc GVC_NAME -o yaml shows The secret APP_SECRET_NAME no longer exists. Workload updates are paused until the secret is added or the reference to the secret removed. under status.versions[].message.Cause: A prerequisite secret does not exist — the APP_SECRET secret named by secrets.name, the database credentials secret named by postgres.config.credentialsSecretName, or the Redis password secret named by redis.credentialsSecretName. The message names the missing one.Fix: Create it (see Prerequisites). The deployment recovers on its own once the secret exists; cpln workload force-redeployment RELEASE_NAME-docmost --gvc GVC_NAME skips the wait.Render fails because replicas above 1 require s3 storage
Render fails because replicas above 1 require s3 storage
docmost: docmost.replicas > 1 requires storage.type: s3 — local attachments live on per-replica volumesets and would scatter/404 across replicas.Cause: docmost.replicas is above 1 while storage.type is local.Fix: Complete Attachment Storage on S3 and set storage.type: s3, or keep a single replica.Render fails because static keys are only for S3-compatible servers
Render fails because static keys are only for S3-compatible servers
docmost: static keys (storage.s3.auth.secretName) are only for S3-compatible servers (storage.s3.endpoint set).Cause: storage.s3.auth.secretName is set without a storage.s3.endpoint. AWS S3 is keyless-only in this template.Fix: For AWS, clear storage.s3.auth.secretName and set storage.s3.cloudAccountName and storage.s3.policyName. For an S3-compatible server, set storage.s3.endpoint too.Upgrade from 1.0.0 fails asking you to create a dictionary secret
Upgrade from 1.0.0 fails asking you to create a dictionary secret
config.credentialsSecretName and a prerequisite dictionary secret.Cause: Your values file still carries postgres.config.username, postgres.config.password, or postgres.config.database.Fix: Put the three values into the database credentials secret and remove the keys, as described in Upgrading from 1.0.0.Member invitations never arrive
Member invitations never arrive
smtp.enabled is false. The production image sends no mail and writes no fallback link to the logs.Fix: Configure Email with smtp.enabled: true (and smtp.auth.secretName for an authenticated relay), then re-send the invitation.Uploaded attachment is incomplete
Uploaded attachment is incomplete
storage.fileUploadSizeLimit. Docmost stores the upload truncated at the limit instead of rejecting it.Fix: Raise storage.fileUploadSizeLimit (for example 200mb) and upload the file again.Important Notes
- Create the three prerequisite secrets before installing —
secrets.namemust name an existing opaque secret (plain encoding) with a random payload of at least 32 characters, andpostgres.config.credentialsSecretNameandredis.credentialsSecretNameexisting dictionary secrets. A missing secret wedges the deployment silently;status.versions[].messagefromcpln workload get-deployments RELEASE_NAME-docmost --gvc GVC_NAME -o yamlnames it. - Treat
APP_SECRETas write-once — rotating it logs out every user and invalidates outstanding invitation and share links. Back the value up outside Control Plane. - Claim the workspace right after install — the first visitor to complete the setup form becomes the workspace owner, and the form is reachable by anyone who can reach the endpoint.
- With SMTP off, member invitations cannot be delivered — configure
smtp.*before inviting anyone. docmost.replicasabove1requiresstorage.type: s3— local attachments are per-replica.- AWS S3 is keyless only — a cloud account plus a bucket-scoped IAM policy; static keys are accepted only with an S3-compatible
storage.s3.endpoint. - Uploads larger than
storage.fileUploadSizeLimitare truncated, not rejected — raise the limit before importing large attachments. - Rotating a password needs a forced redeployment — the database password also needs
ALTER ROLEfirst; see Rotating the Database Password and Rotating the Redis Password. - Give each release its own database credentials secret — secret names are org-wide.
- Uninstalling deletes the volume sets and every page and local attachment in them; your prerequisite secrets are yours and survive.
- Docmost is licensed under the AGPL — this template deploys the open-source edition.