Self-host with Helm
This article will walk you through the procedure to install and deploy Bitwarden in different Kubernetes deployments using a Helm chart.
This article will describe the generic steps for hosting Bitwarden on Kubernetes. Provider-specific guides are available to dive into how you might alter a deployment based on each provider's specific offerings:
Before proceeding with the installation, ensure the following requirements are met:
kubectl is installed.
Helm 3 is installed.
You have an SSL certificate and key or access to creating one via a certificate provider.
You have a SMTP server or access to a cloud SMTP provider.
A storage class that supports ReadWriteMany.
You have an installation id and key retrieved from https://bitwarden.com/host.
Add the repo to Helm using the following commands:
Bashhelm repo add bitwarden https://charts.bitwarden.com/ helm repo update
Create a namespace to deploy Bitwarden to. Our documentation assumes a namespace called bitwarden
, so be sure to modify commands if you choose a different name.
Bashkubectl create namespace bitwarden
Create a my-values.yaml
configuration file, which you will use to customize your deployment, using the following command:
Bashhelm show values bitwarden/self-host > my-values.yaml
At a minimum, you must configure the following values in your my-values.yaml
file:
Value | Description |
---|---|
| The domain that will point to your cluster's public IP address. |
| Whether to use the nginx ingress controller defined in the chart (see an example using a non-included ingress controller). |
| For example, |
| Annotations to add to the ingress controller. If you're using the included nginx controller, defaults are provided that you must uncomment and can customize as needed. |
| If you're using the default nginx controller, defaults are provided that you can customize as needed. |
| The name of your TLS certificate. We will walk through an example later, so enter it now if you have it or circle back later. |
| The name of your TLS certificate issuer. We will walk through an example later, so enter it now if you have it or circle back later. |
| Email address used for invitations, typically |
| Your SMTP server hostname or IP address. |
| The SMTP port used by the SMTP server. |
| Whether your SMTP server uses an encryption protocol ( |
| Set to |
| By default, |
| The name of the shared storage class, which you will need to provide and must support ReadWriteMany (see an example using Azure File Storage) unless it's a single-node cluster. |
| The name of your Kubernetes secret object. You will create this object in the next step, so decide on a name now or circle back to this value. |
| Whether to use the SQL pod included in the chart. Only set to |
| The SCIM pod is disabled by default. To enable the SCIM pod, set value |
| While not required, we recommend setting to |
Create a Kubernetes secret object to set, at a minimum, the following values:
Value | Description |
---|---|
| A valid installation id retrieved from https://bitwarden.com/host. For more information, see what are my installation id and installation key used for? |
| A valid installation key retrieved from https://bitwarden.com/host. For more information, see what are my installation id and installation key used for? |
| A valid username for your SMTP server. |
| A valid password for the entered SMTP server username. |
| Client ID for YubiCloud Validation Service or self-hosted Yubico Validation Server. If YubiCloud, get your client ID and secret key here. |
| Secret key for YubiCloud Validation Service or self-hosted Yubico Validation Server. If YubiCloud, get your client ID and secret key here. |
| Your HaveIBeenPwned (HIBP) API Key, available here. This key allows users to run the Data Breach report and to check their master password for presence in breaches when they create an account. |
If you're using the Bitwarden SQL pod, If you're using your own SQL server, | Credentials for the database connected to your Bitwarden instance. What is required will depend on whether you're using the included SQL pod or an external SQL server. |
For example, using the kubectl create secret
command to set these values would look like the following:
warning
This example will record commands to your shell history. Other methods may be considered to securely set a secret.
Bashkubectl create secret generic custom-secret -n bitwarden \
--from-literal=globalSettings__installation__id="REPLACE" \
--from-literal=globalSettings__installation__key="REPLACE" \
--from-literal=globalSettings__mail__smtp__username="REPLACE" \
--from-literal=globalSettings__mail__smtp__password="REPLACE" \
--from-literal=globalSettings__yubico__clientId="REPLACE" \
--from-literal=globalSettings__yubico__key="REPLACE" \
--from-literal=globalSettings__hibpApiKey="REPLACE" \
--from-literal=SA_PASSWORD="REPLACE"
Don't forget to set the secrets.secretName:
value in my-values.yaml
to the name of the created secret, in this case custom-secret
.
Deployment requires a TLS certificate and key, or access to a creating one via certificate provider. The following example will walk you through using cert-manager to generate a certificate with Let's Encrypt:
Install cert-manager on the cluster using the following command:
Bashkubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml
Define a certificate issuer. Bitwarden recommends using the Staging configuration in this example until your DNS records have been pointed to your cluster. Be sure to replace the
email:
placeholder with a valid value:Bashcat <<EOF | kubectl apply -n bitwarden -f - apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-staging spec: acme: server: https://acme-staging-v02.api.letsencrypt.org/directory email: me@example.com privateKeySecretRef: name: tls-secret solvers: - http01: ingress: class: nginx #use "azure/application-gateway" for Application Gateway ingress EOF
Bashcat <<EOF | kubectl apply -n bitwarden -f - apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-production spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: me@example.com privateKeySecretRef: name: tls-secret solvers: - http01: ingress: class: nginx #use "azure/application-gateway" for Application Gateway ingress EOF
If you haven't already, be sure to set the
general.ingress.cert.tls.name:
andgeneral.ingress.cert.tls.clusterIssuer:
values inmy-values.yaml
. In this example, you would set:general.ingress.cert.tls.name: tls-secret
general.ingress.cert.tls.clusterIssuer: letsencrypt-staging
The Bitwarden self-host Helm Chart allows you to include other Kubernetes manifest files either pre- or post-install. To do this, update the rawManifests
section of the chart (learn more). This is useful, for example, in scenarios where you want to use an ingress controller other than the nginx controller defined by default.
To install Bitwarden with the configuration setup in my-values.yaml
, run the following command:
Bashhelm upgrade bitwarden bitwarden/self-host --install --namespace bitwarden --values my-values.yaml
Congratulations! Bitwarden is now up and running at https://your.domain.com
, as defined in my-values.yaml
. Visit the web vault in your web browser to confirm that it's working. You may now register a new account and log in.
You will need to have setup an SMTP configuration and related secrets in order to verify the email for your new account.
In this repository, we have provided two illustrative example jobs for backing up and restoring the database in the Bitwarden database pod. If you are using your own SQL Server instance that is not deployed as part of this Helm chart, please follow your corporate backup and restore policies.
Database backups and backup policies are ultimately up to the implementor. The backup could be scheduled outside of the cluster to run at a regular interval, or it could be modified to create a CronJob object within Kubernetes for scheduling purposes.
The backup job will create timestamped versions of the previous backups. The current backup is simply called vault.bak
. These files are placed in the MS SQL backups persistent volume. The restore job will look for vault.bak
in the same persistent volume.
Suggest changes to this page
How can we improve this page for you?
For technical, billing, and product questions, please contact support