Vaultwarden


PhotoprismVaultwarden is a password management system. It is feature compatible with Bitwarden, but rewritten in Rust to make it lighter weight and better for homelab use. Since it is feature compatible with Bitwarden you can take advantage of the Bitwarden mobile apps on your device to access your private vault. Below is how I've implemented Vaultwarden into my Kubernetes cluster.

Product: Vaultwarden
Install Type: Helm (Chart)
Container Image: Docker

Installation Details

For Helm charts, I generally pull the values to a file and modify that file for my specific needs:

 helm show values oci://ghcr.io/gabe565/charts/vaultwarden > values.yaml

This allows me to modify different settings, such as the details of the Postgresql vaules, and environment specific configurations such as persistent storage and others. Please configure as appropriate for your environment.

First I set the default storageClass I'll use:

...

global:
  imageRegistry: ""
  ## E.g.
  ## imagePullSecrets:
  ##   - myRegistryKeySecretName
  ##
  imagePullSecrets: []
  storageClass: longhorn

  ...

I use Longhorn as my preferred storageClass, but please adjust to your needs.

Also be sure to adjust the ingress settings to your needs:

...

ingress:
  ## @param ingress.enabled Enable ingress record generation for vaultwarden
  ##
  enabled: true
  ## @param ingress.ingressClassName IngressClass that will be be used to implement the Ingress (Kubernetes 1.18+)
  ## This is supported in Kubernetes 1.18+ and required if you have more than one IngressClass marked as the default for your cluster .
  ## ref: https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/
  ##
  ingressClassName: "nginx"
  ## @param ingress.pathType Ingress path type
  ##
  pathType: ImplementationSpecific
  ## @param ingress.apiVersion Force Ingress API version (automatically detected if not set)
  ##
  apiVersion: ""
  ## @param ingress.hostname Default host for the ingress record (evaluated as template)
  ##
  hostname: your.host.name
  ## @param ingress.path Default path for the ingress record
  ##
  path: /
  ## @param ingress.pathWs Path for the websocket ingress
  ##
  pathWs: "/notifications/hub"
  ## @param ingress.servicePort Backend service port to use
  ## Default is http. Alternative is https.
  ##
  servicePort: http
  ## @param ingress.annotations [object] Additional annotations for the Ingress resource. To enable certificate autogeneration, place here your cert-manager annotations.
  ## Use this parameter to set the required annotations for cert-manager, see
  ## ref: https://cert-manager.io/docs/usage/ingress/#supported-annotations
  ## e.g:
  ## annotations:
  ##   kubernetes.io/ingress.class: nginx
  ##   cert-manager.io/cluster-issuer: cluster-issuer-name
  ##
  annotations: 
    cert-manager.io/cluster-issuer: letsencrypt

  ## @param ingress.tls Enable TLS configuration for the host defined at 'ingress.hostname' parameter
  ## You can:
  ##   - Use the `ingress.secrets` parameter to create this TLS secret
  ##   - Rely on cert-manager to create it by setting the corresponding annotations
  ##   - Rely on Helm to create self-signed certificates by setting 'ingress.selfSigned=true'
  ##
  tls: 
    # - secretName: wildcard-cert-secret
    - secretName: vaultwarden-tls
      hosts:
        - your.host.name

...

The above configuration does require you to have an Nginx Ingress and Cert Manager with an ACME certificate provider like Let's Encrypt already configured in your cluster.

I prefer to not use SQLite for all but the simplest deployments. Vaultwarden supports the use of a PostgreSQL database. I prefer to use a central PostgreSQL Server for all my deployments that require it. Fortunately the Helm chart supports this:

...

database:
  ## @param database.type Database type, either default or postgresql
  ## Default is a sqlite database.
  ##
  type: "postgresql"

...

postgresql:
  enabled: false

...

externalDatabase:
  host: "YourPostgresServer"
  port: 5432
  user: vaultwarden
  database: vaultwarden
  password: "YourSuperSecretPasswor"
  existingSecret: "vaultwarden-externaldb"
  existingSecretPasswordKey: "password"

...

Also, if you have configured SMTP (server or mail relay) for your homelab, don't forget to enable your Vaultwarden to support it:

...

## @section SMTP Configuration
##
smtp:
  ## @param smtp.host SMTP host
  ##
  host: "your.smtp.server"
  ## @param smtp.security SMTP Encryption method
  ## Possible values:
  ##  - starttls: explicit TLS using ports 587 or 25
  ##  - force_tls: implicit TLS using port 465
  ##  - off: no encryption, using port 25, unless using STARTTLS
  ##
  security: starttls
  ## @param smtp.port SMTP port
  ##
  port: 587
  ## @param smtp.from SMTP sender email address
  ## Example: juan.delacruz@gmail.com
  ##
  from: "sending.email.address@your.domain.name"
  ## @param smtp.username Username for the SMTP authentication.
  ## Example: juan
  ##
  username: "smtp.username"
  ## @param smtp.password Password for the SMTP service.
  ##
  password: 'YourSuperSecretPassword'
  ## @param smtp.authMechanism SMTP authentication mechanism
  ## Possible values: "Plain", "Login", "Xoauth2"
  ## Multiple options need to be separated by a comma. (not tested)
  ##
  authMechanism: "Plain"
  ## @param smtp.acceptInvalidHostnames Accept Invalid Hostnames
  ##
  acceptInvalidHostnames: "false"
  ## @param smtp.acceptInvalidCerts Accept Invalid Certificates
  ##
  acceptInvalidCerts: "false"
  ## @param smtp.debug SMTP debugging
  ##
  debug: false

...

Once you have made you changes, deploy with the following:

helm upgrade --install --namespace security --create-namespace \
             -f values.yaml vaultwarden oci://ghcr.io/gabe565/charts/vaultwarden