This article is part of the series Build your very own self-hosting platform with Raspberry Pi and Kubernetes
- Install Raspbian Operating-System and prepare the system for Kubernetes
- Install and configure a Kubernetes cluster with k3s to self-host applications
- Deploy NextCloud on Kuberbetes: The self-hosted Dropbox
- Self-host your Media Center On Kubernetes with Plex, Sonarr, Radarr, Transmission and Jackett
- Self-host Pi-Hole on Kubernetes and block ads and trackers at the network level
- Self-host your password manager with Bitwarden
- Deploy Prometheus and Grafana to monitor a Kubernetes cluster
Bitwarden is a free, open-source and audited Password Manager, it provides a large range of clients (desktop, web, browser extension and mobiles) to access your password easily and safely from anywhere. While Bitwarden offers a SaaS solutions (they host your passwords in an encrypted way), because Bitwarden is open-source, you can decide to host yourself your password and this is what we are going to learn in this tutorial.
For information, we will deploy Bitwarden-rs, Unofficial Bitwarden compatible server written in Rust, ideal for self-hosting.
This is a Bitwarden server API implementation written in Rust compatible with upstream Bitwarden clients*, perfect for self-hosted deployment where running the official resource-heavy service might not be ideal. This project is not associated with the Bitwarden project nor 8bit Solutions LLC.
In order to run entirely the tutorial, we will need:
- A running Kubernetes cluster (see previous articles if you haven't set this up yet)
- A domain name in order to access our Bitwarden instance from outside our network. (replace
<domain.com>by your domain)
- Have a external static IP (usually the case by default)
- Access to your router admin console to port-forward an incoming request to our Kubernetes Ingress service.
We are going to isolate all the Kubernetes objects related to Bitwarden in the namespace
To create a namespace, run the following command:
$ kubectl create namespace bitwarden
The first step consists in setting up a volume to store Bitwarden config files and data. If you followed the previous articles to install and configure a self-hosting platform using RaspberryPi and Kubernetes, you remember we have on each worker a NFS client pointing to a SSD on
1. Deploy the Persistent Volume (PV)
The Persistent Volume specify the name, the size, the location and the access modes of the volume:
- The name of the PV is
- The size allocated is 500MB
- The location is
- The access is ReadWriteOnce
Create the following file and apply it to the k8 cluster.
# bitwarden.persistentvolume.yml --- apiVersion: v1 kind: PersistentVolume metadata: name: bitwarden-ssd labels: type: local spec: storageClassName: manual capacity: storage: 500Mi accessModes: - ReadWriteOnce hostPath: path: "/mnt/ssd/bitwarden" ---
$ kubectl apply -f bitwarden.persistentvolume.yml persistentvolume/bitwarden created
You can verify the PV exists with the following command:
$ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE bitwarden-ssd 500Mi RWO Retain Available manual 7s
2. Create the Persistent Volume Claim (PVC)
The Persistent Volume Claim is used to map a Persistent Volume to a deployment or stateful set. Unlike the PV, the PVC belongs to a namespace.
Create the following file and apply it to the k8 cluster.
# bitwarden.persistentvolumeclaim.yml --- apiVersion: v1 kind: PersistentVolumeClaim metadata: namespace: bitwarden name: bitwarden-ssd spec: storageClassName: manual accessModes: - ReadWriteOnce resources: requests: storage: 500Mi ---
$ kubectl apply -f bitwarden.persistentvolumeclaim.yml persistentvolumeclaim/bitwarden created
You can verify the PVC exists with the following command:
$ kubectl get pvc -n bitwarden NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE bitwarden-ssd Bound bitwarden-ssd 500Mi RWO manual 8s
The next part consist to enable the connections to Bitwarden from outside so you can access your passwords from anywhere.
1. Port Forwarding
First you need to go to your router setup and add a port-forwarding rule to map any incoming requests on port 80 or port 443 to be forwarded to
192.168.0.240 (the LoadBalancer IP of the Nginx).
VirginHub - Port-Forwarding
2. Map the subdomain
bitwarden.<domain.com> to your home router
First you need to find out what's your router external IP, run this command or go to whatismyip.com.
$ curl ipecho.net/plain x.x.x.x
Then, we need to configure our subdomain to make sure
bitwarden.<domain.com> resolves to our external static IP. Go to your domain provider console / DNS management add a record:
- Type: A
- Name: bitwarden (subdomain)
- Value: x.x.x.x (external static IP)
1. Clone the repo
Clone the repository
bitwarden-k8s with the following command (change
~/workspace/bitwarden-k8s by the target folder of your choice):
$ git clone https://github.com/gjeanmart/bitwarden-k8s.git ~/workspace/bitwarden-k8s
2. Download the Chart values of the chart locally
Run the following command to download the Chart values into the local file
$ helm show values ~/workspace/bitwarden-k8s >> bitwarden.values.yml
If you open the file, you will see the default configuration values to setup Bitwarden. Instead of using the flag
--set property=value like before, we will use the file
bitwarden.values.yml to make all the changes.
3. Update the values
We now need to update a few properties before installing the Helm chart. Open the file
bitwarden.values.yml and change the following properties.
First we need to change to an ARM compatible image
# bitwarden.values.yml image: repository: bitwardenrs/server # Change here tag: raspberry # Change here pullPolicy: IfNotPresent
Then we configure the environment variables.
[ADMIN_TOKEN] by the result of the command
$ openssl rand -base64 48. This token will be used to connect to the Bitwarden administration interface.
# bitwarden.values.yml env: SIGNUPS_ALLOWED: false # Disable Sign Up form (invitation only) INVITATIONS_ALLOWED: true # Enable invitation ADMIN_TOKEN: "[ADMIN_TOKEN]" # Copy/Paste the result of the command `$ openssl rand -base64 48` (admin interface password) DOMAIN: "https://bitwarden.<domain.com>" # Domain used to access Bitwarden SMTP_HOST: "smtp.gmail.com" # SMTP host (invitation) SMTP_FROM: "no-reply@<domain.com>" # From email (invitation) SMTP_PORT: 587 # SMTP Port (invitation) SMTP_SSL: true # SMTP SSL (invitation) SMTP_USERNAME: "[SMTP_USERNAME]" # SMTP username (invitation) SMTP_PASSWORD: "[SMTP_PASSWORD]" # SMTP password (invitation)
In the next step, we configure an ingress to access Bitwarden and issue a certificate (especially if we want to access from outside).
<domain.com> by your domain (same as the section "Internet access")
# bitwarden.values.yml ingress: enabled: true # Generate an Ingress while deploying annotations: kubernetes.io/ingress.class: "nginx" cert-manager.io/cluster-issuer: "letsencrypt-prod" # Cluster Issuer configured with certmanager path: / hosts: - bitwarden.<domain.com> # Domain for Bitwarden tls: - secretName: bitwarden-domain-com-tls hosts: - bitwarden.<domain.com> # Domain for Bitwarden
Finally, we want to plug Bitwarden to the persistent volume created at the beginning of the article pointing to
# bitwarden.values.yml ## Persist data to a persistent volume persistence: enabled: true # Change here existingClaim: "bitwarden-ssd" # Change here
4. Install the Chart
In the part, we will install the Helm chart under the namespace
bitwarden.values.yml as configuration file.
$ helm install bitwarden ~/workspace/bitwarden-k8s \ --namespace bitwarden \ --values bitwarden.values.yml
After a couple of minutes, check if the pod and service is up and running:
$ kubectl get pods -n bitwarden -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES bitwarden-bitwarden-k8s-58db5c445-7w7wq 1/1 Running 0 4m53s 10.42.0.105 kube-master <none> <none>
Once Bitwarden is up and running, we can start configuring our first user.
1. Access the admin interface
First, access the admin interface which should be available on https://bitwarden.
<domain.com>/admin and enter the
<ADMIN_PASSWORD> generated previously.
2. Invite your first user
Once connected, you can check and modify the different parameters of Bitwarden and invite a new user. Enter an email address to invite a new user.
After a few seconds, You should received the invitation via email. Click on "Join the Organisation".
3. Create an account and login for the first time
Click on "Create Account".
Configure the details of the user: name, master password (encryption key) and click on "Submit".
Finally, log into with the newly created user using the couple email, master password.
You now have a fully self-hosted password manager accessible via your own domain from anywhere.
You can also install and configure your custom server to easily and safely access your password: