Overview
Vaultwarden is a lightweight, self-hosted password manager server (AGPL-3.0) that is compatible with all official Bitwarden clients: browser extensions, desktop apps, and mobile apps. This template deploys one stateful Vaultwarden workload with its SQLite database on a persistent volume, serving the web vault, the client APIs, and live sync over HTTPS on the canonical*.cpln.app endpoint. Vault contents are end-to-end encrypted with each user’s master password, so the server never holds readable passwords.
Registration is open on a fresh install so you can create your first accounts immediately; turn it off once your users are on board.
What Gets Created
Prerequisites
None for a default install. The two secrets below are optional, each enables one feature, and each must exist before you set its values key. Secrets are org-level, so no GVC flag is involved.Optional - admin panel token
/admin panel stays disabled unless you provide an opaque secret holding the argon2 hash of an admin token you choose. Generate the hash with the Vaultwarden binary itself; it prompts for the token twice and prints a string starting with $argon2:$ signs; that escaping is for docker-compose files only and breaks the login here. The single quotes below keep the shell from expanding them:admin.tokenSecretName to this name.Optional - SMTP authentication
smtp.host and your mail server requires a login. Create a dictionary secret with exactly two keys, username and password:smtp.authSecretName to this name.Installation
A default install needs no values at all:UI
CLI
Terraform
Pulumi
Configuration
Vaultwarden Instance
resources block exposes both a reservation and a limit, so the limit is named maxCpu / maxMemory. A values file that still carries the bare cpu or memory keys is refused at render with a message telling you to rename them (see Upgrading from 1.0.0). Size volumeset.capacity for your attachments and sends as well as the database.
Backup
backup.enabled: false removes the schedule only; backup.retention still applies, and a final snapshot is taken when the release is uninstalled either way. See Backing Up.
Sign-ups and Invitations
signups.allowed: true, anyone who can reach the public endpoint can create an account. After your first accounts exist, set signups.allowed: false, or keep self-service registration for your own company with signups.domainsWhitelist. signups.verify: true is refused at render unless smtp.host is set.
Admin Panel
admin.tokenSecretName to the opaque secret from Prerequisites to enable /admin. Empty (the default) leaves the panel disabled. Settings saved in the panel take precedence over Helm values from then on; see Important Notes.
SMTP
smtp.host is set without smtp.from, or when smtp.authSecretName is set without smtp.host.
Privacy
Domain
DOMAIN to the workload’s canonical endpoint at boot, so attachment links, email links, and passkeys bind to the right URL with no configuration. Set customDomain only when you serve the vault on your own domain, and decide before users register passkeys; see Important Notes.
Access
publicAccess.enabled: true unless you front the vault another way. With it disabled, external requests are refused at the edge.
Connecting
The web vault, the client APIs, and the admin panel are all served on the Vaultwarden workload’s canonical endpoint, which is public by default (publicAccess.enabled: true). Read it from status.canonicalEndpoint:
200 means Vaultwarden is serving. With publicAccess.enabled: false, Bitwarden clients cannot reach the server, because they need an HTTPS URL. You can still check the server from your machine through a port-forward:
curl -s http://localhost:8080/alive in a second terminal.
First Run
There is no setup wizard; the first user simply registers.Create your account
https://CANONICAL_ENDPOINT, choose Create account, and set a strong master password. The master password encrypts your vault and cannot be reset by anyone; without SMTP configured, password-hint emails are off too.Connect your Bitwarden clients
https://CANONICAL_ENDPOINT as the server URL, then sign in with the account you just created.Lock down registration
signups.allowed set to false, or restrict registration with signups.domainsWhitelist. While registration is open, anyone who can reach the public endpoint can create an account. See the CLI guide for upgrading a release.Operations
Backing Up
On the cron schedule inbackup.schedule (default daily at 03:00 UTC), the platform takes a crash-consistent snapshot of RELEASE_NAME-vaultwarden-data; SQLite recovers cleanly from one through its write-ahead log. Snapshots are pruned after backup.retention (default 7 days), and a final snapshot is always taken when the release is uninstalled. A snapshot covers everything on the volume: the database, attachments, sends, and the session-signing key.
Restoring a Backup
Restore is in place on the release’s own volume set: the platform provisions a fresh volume from the chosen snapshot and swaps it in, and the single replica restarts to remount it. An in-place snapshot restore recovered an intact vault when this template was tested; the command flags below are taken from the CLI help and have not been exercised against a live install since. Rehearse on a throwaway release before you depend on it.Find the snapshot
name and location of the one you want:Restore it in place
0:Verify
Rotating the Admin Token
The admin token is read from your opaque secret when the replica starts. To change it, generate a new hash as in Prerequisites, apply the whole secret with the new value, then force a redeployment:SMTP_AUTH_SECRET_NAME.
Upgrading from 1.0.0
Version 1.1.0 renames the resource limit keys:resources.cpu is now resources.maxCpu and resources.memory is now resources.maxMemory, so it is no longer ambiguous which number is the limit. Rename those two keys in your values before upgrading. An upgrade that still carries the old names is refused at render, before any resource is touched. Nothing else changed, and the volume and its data are unaffected.
Scaling and Availability
Vaultwarden runs as exactly one replica on SQLite, and there is deliberately noreplicas knob. Upstream does not support running multiple instances: replicas cannot share the data volume or notify each other of changes, and on this platform each stateful replica would get its own volume, so a second replica would serve a different, empty vault. Scale vertically by raising resources.maxCpu and resources.maxMemory, keeping maxCpu within 4:1 of minCpu.
Any restart, from an upgrade that changes the container, a forced redeployment, or a replica being rescheduled, is a short full outage while the new replica starts and the volume reattaches. Data is not at risk, because the same volume reattaches. Bitwarden apps keep a local copy of the vault, so users can still read their items during the outage.
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-vaultwarden --gvc GVC_NAME -o yaml shows The secret ADMIN_TOKEN_SECRET_NAME no longer exists. Workload updates are paused until the secret is added or the reference to the secret removed. (or the same for your SMTP secret) under status.versions[].message.Cause: admin.tokenSecretName or smtp.authSecretName names a secret that does not exist.Fix: Create it (see Prerequisites), or clear the value and upgrade the release. The deployment recovers on its own once the secret exists; cpln workload force-redeployment RELEASE_NAME-vaultwarden --gvc GVC_NAME skips the wait.Render fails saying resources.cpu was RENAMED to resources.maxCpu
Render fails saying resources.cpu was RENAMED to resources.maxCpu
vaultwarden: resources.cpu was RENAMED to resources.maxCpu. (or the same for resources.memory).Cause: Your values use the 1.0.0 key names.Fix: Rename them to resources.maxCpu and resources.maxMemory (see Upgrading from 1.0.0).Render fails saying smtp.from is required when smtp.host is set
Render fails saying smtp.from is required when smtp.host is set
vaultwarden: smtp.from is required when smtp.host is set — the sender address for outgoing mail, or vaultwarden: signups.verify requires smtp.host, or vaultwarden: smtp.authSecretName is set but smtp.host is empty.Cause: The SMTP settings are incomplete.Fix: Set smtp.host and smtp.from together; set signups.verify and smtp.authSecretName only when smtp.host is set.The admin panel rejects the token
The admin panel rejects the token
/admin says the token is invalid.Cause: Either the hash was stored with doubled $ signs (docker-compose escaping), or you typed the hash instead of the plaintext token.Fix: Sign in with the plaintext token you chose when generating the hash. If that still fails, re-apply the secret with the raw $argon2... string and force a redeployment (see Rotating the Admin Token).A values change does not take effect
A values change does not take effect
signups.allowed: false) and Vaultwarden still behaves the old way.Cause: Saving settings in the admin panel writes /data/config.json, which takes precedence over the environment the chart sets from values.Fix: Change the setting in the admin panel instead, or remove the file and restart to return control to values:Passkey logins fail after changing the domain
Passkey logins fail after changing the domain
customDomain.Cause: WebAuthn credentials are bound to the exact URL they were registered on.Fix: Users re-register their passkeys on the new URL. Choose the final domain before users register passkeys.Important Notes
- Turn off open registration after onboarding. Sign-ups are open by default; set
signups.allowed: falseor usesignups.domainsWhitelist. - Master passwords are unrecoverable. Vault contents are end-to-end encrypted; a forgotten master password means a lost vault.
- Admin panel settings override Helm values. Saving in
/adminwrites/data/config.json, which wins over values from then on. - Store the admin token hash raw. No doubled
$signs, and sign in with the plaintext token, not the hash. - Do not change the domain casually. Passkeys are bound to the exact URL and break until re-registered.
- Rotating a secret needs a forced redeployment. The old admin token or SMTP password keeps working until the replica restarts.
- Single instance only. Every restart is a short outage; see Scaling and Availability.
- Snapshots are not an off-platform copy. Uninstalling deletes the volume set after a final snapshot; your own secrets survive.