Skip to main content

Overview

Vaultwarden is a lightweight, self-hosted password manager (AGPL-3.0) that is compatible with all official Bitwarden clients — browser extensions, desktop apps, and mobile apps. This template deploys a single stateful workload with its SQLite database on a persistent volume, served over HTTPS on the canonical *.cpln.app endpoint. Registration is open on a fresh install so you can onboard immediately; lock it down once your users are on board.

Architecture

  • Vaultwarden — A single-replica stateful workload serving the web vault, APIs, and websocket live-sync on port 80. Its public DOMAIN is derived from the canonical endpoint at boot, so clients and passkeys bind to the correct URL with no manual configuration.
  • SQLite on a persistent volume — All state (accounts, vault items, attachments, sends, and the RSA key that signs login sessions) lives in a SQLite database on the workload’s volume set; there is no external database dependency.

What Gets Created

  • Stateful Vaultwarden Workload — A single replica serving the web vault, APIs, and websocket notifications on port 80.
  • Volume Set — A 10 GiB persistent volume mounted at /data holding the SQLite database, attachments, sends, and RSA signing keys. Scheduled snapshots protect the data, and a final snapshot is kept on delete.
  • Start-Script Secret — An opaque secret whose boot script sets DOMAIN from the canonical endpoint.
  • Identity & Policy — An identity bound to the workload with a least-privilege policy granting reveal access to exactly the secrets it mounts (the start script, plus your admin and SMTP secrets only when you configure them).
This template does not create a GVC. You must deploy it into an existing GVC.

Prerequisites

None for a default install — no secrets, cloud accounts, or external resources are required. The two secrets below are optional and only needed for the corresponding features.
  • Admin panel (/admin) — Create, before installing, an opaque secret (encoding: plain) holding the argon2 hash of your admin token. Generate the hash with docker run --rm -it vaultwarden/server:1.36.0 /vaultwarden hash and store the full $argon2... output as-is — do not double the $ signs (that is docker-compose escaping and will break login here). Set the secret’s name in admin.tokenSecretName.
  • Authenticated SMTP — Create a dictionary secret with exactly two keys, username and password, for your mail server, and set its name in smtp.authSecretName. Only needed when your relay requires authentication.
Install the template using your preferred method:

UI

Browse, install, and manage templates visually

CLI

Manage templates from your terminal

Terraform

Declare templates in your Terraform configurations

Pulumi

Declare templates in your Pulumi programs

Configuration

The default values.yaml for this template:

Vaultwarden Instance

  • image — The Vaultwarden container image.
  • resources — CPU and memory for the Vaultwarden container.
  • volumeset.capacity — Volume size in GiB (minimum 10) for the SQLite database, attachments, sends, and RSA keys.

Backup

Scheduled, crash-consistent snapshots of the data volume, managed by the platform — no cloud account or bucket is required. See Backing Up for how snapshots and restores work.
  • backup.enabled — Take periodic snapshots of the data volume (default true).
  • backup.schedule — Cron expression in UTC (default 0 3 * * *, daily at 03:00). The platform does not accept schedules more frequent than hourly.
  • backup.retention — How long each snapshot is kept, e.g. 7d, 720h, 30d.

Sign-ups & Invitations

  • signups.allowed — Open registration on the public endpoint (default true so a fresh install is usable). Turn this off after onboarding — see Important Notes.
  • signups.domainsWhitelist — Email domains that may register even when signups.allowed is false, e.g. [mycompany.com]. This also gates who can be invited.
  • signups.verify — Require email verification at registration. Requires smtp.host.
  • invitations.allowed — Allow existing organization owners to invite users; invited emails may then register.

Admin Panel

  • admin.tokenSecretName — Name of a pre-created opaque secret holding the argon2 hash of your admin token (see Prerequisites). Empty (default) leaves the /admin panel disabled.

SMTP

Configure an outbound mail server to send invitations, verification, and 2FA emails.
  • smtp.host — Mail server hostname. Empty (default) disables all email features.
  • smtp.port — SMTP port (default 587).
  • smtp.securitystarttls, force_tls, or off.
  • smtp.from — Sender address; required when smtp.host is set.
  • smtp.authSecretName — Name of a pre-created dictionary secret with username and password keys (see Prerequisites). Empty means an unauthenticated relay.

Privacy

  • icons.disableDownload — Set to true to stop the server fetching site favicons. Those outbound requests reveal which sites users store; with downloads off, clients show letter placeholders instead.

Domain

  • customDomain — Full URL of a custom domain, e.g. https://vault.example.com. Empty (default) uses the canonical *.cpln.app endpoint. See the domain caution in Important Notes before changing this on a live vault.

Access

  • publicAccess.enabled — Serve Vaultwarden over HTTPS on the canonical *.cpln.app endpoint (default). Bitwarden clients require HTTPS, so keep this enabled unless you front the vault another way. When disabled, external requests are blocked at the edge and only in-GVC callers reach it per internalAccess.
  • internalAccess.type — Internal firewall scope of the Vaultwarden workload. Keep this closed (none, the default) for a password vault unless in-GVC callers need the API:

Connecting

Clients and Live Sync

Point any official Bitwarden client at the canonical endpoint via its self-hosted server URL, then log in with an account registered in the web vault. Live sync across open clients rides a websocket on the same HTTPS endpoint and works through the canonical endpoint with no extra configuration.

Backing Up

Backups are scheduled volume snapshots managed by the platform — no cloud account or bucket is required. On the configured cron schedule the platform takes a crash-consistent snapshot of the data volume; SQLite recovers cleanly from one via its write-ahead log. Snapshots are pruned automatically after backup.retention, and a final snapshot is always taken when the release is uninstalled.
  • Default schedule — Daily at 03:00 UTC (backup.schedule: "0 3 * * *"), kept for 7 days (backup.retention: 7d).
  • Minimum interval — The platform does not accept schedules more frequent than hourly.
List the snapshots for the release’s volume set:
Snapshots live in the platform storage layer alongside the volume, not off-site. They protect against data corruption and accidental changes, but losing the whole GVC would lose them too. For off-cluster durability, restore into a fresh install elsewhere or export vault data separately.

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, then the workload restarts to remount it (about 90 seconds).
Restoring reverts the volume to the exact snapshot state — any vault changes made after that snapshot are lost — and restarts the single-replica workload, so the vault is briefly unavailable during the swap.
1

Find the snapshot to restore

List snapshots and note the name, location, and volumeIndex of the one you want:
2

Restore it in place

Provision a fresh volume from the snapshot and swap it in. The workload restarts to remount it:
3

Verify

Once the workload is ready again, log in to the web vault and confirm your items are present and decrypt correctly.

Important Notes

  • Lock down registration after onboarding. Sign-ups are open by default so the install works immediately — which means anyone who can reach the public endpoint can register. Once your users are on board, set signups.allowed=false, or restrict with signups.domainsWhitelist (whitelisted domains can still register with sign-ups off).
  • Vault contents are end-to-end encrypted with each user’s master password, and master passwords are unrecoverable. Without SMTP configured, password-hint emails are off, so a forgotten master password means a lost vault.
  • Admin panel settings override Helm values. Saving settings in /admin writes /data/config.json, which silently wins over environment variables from then on. If a values change does not take effect, delete that file to return control to values.
  • Store the admin token hash raw. Put the argon2 output (starting with $argon2) into the secret as-is — do not double the $ signs; that escaping is for docker-compose only and breaks login here.
  • Do not change the domain casually. Passkey/WebAuthn logins are bound to the exact URL; switching between the canonical endpoint and a custom domain breaks them until re-registered.
  • Single instance only — upstream does not support running multiple instances, so the workload is pinned to 1 replica with no replicas knob. A restart is a short full outage (about a minute); Bitwarden apps keep a local offline copy of the vault, so users can still read their vault during it.
  • Backups are in-platform, not off-site — scheduled snapshots and the final snapshot on uninstall live in the platform storage layer next to the volume; losing the whole GVC would lose them too. See Backing Up.

External References

Vaultwarden on GitHub

Upstream source repository

Vaultwarden Wiki

Official documentation wiki

Enabling the Admin Page

How to configure and secure the /admin panel

SMTP Configuration

Configure outbound email for invites and verification

Hardening Guide

Upstream recommendations for locking down an instance

Vaultwarden Template

View the source files, default values, and chart definition