Self Hosting Bitwarden on the Raspberry Pi

In this project, we are going to show you how to self-host Bitwarden on your Raspberry Pi.

Raspberry Pi Bitwarden RS

Bitwarden is an entirely free and open-source password management service. It allows you to retain complete control over how your passwords are stored.

The software is widely considered to be the best free solution for those wanting a secure password manager.

A Raspberry Pi makes an excellent self-hosted solution for Bitwarden as it consumes relatively low power. This helps make it cheap to have running all the time.

Your Bitwarden clients can connect to this server to synchronize your password data.

As the Raspberry Pi isn’t the most powerful device, we will need to use a non-official version of the server software.

This version is a re-implementation of the Bitwarden server API but entirely written in Rust. It has been written to minimize the amount of resources it consumes, which is perfect for our Raspberry Pi.

Table of Contents

Equipment

Below is a list of the equipment that you need for self-hosting Bitwarden on the Raspberry Pi.

Recommended

Optional

We tested this tutorial on a Raspberry Pi 400 running on the latest release of Raspberry Pi OS Buster.

Preparing your Raspberry Pi for Bitwarden

There are a few things we must do before we can self host our Bitwarden server. One of these steps includes installing Docker.

1. First, as Bitwarden will be running within a Docker container, you need to install it.

We have a guide that walks you through the process of setting up Docker on the Raspberry Pi.

Once you complete this guide, you can safely move on to the next step.

2. You can also choose whether you want to use Portainer to manage your Docker container.

You can either run it directly using the command line or add it to Portainer. Portainer will allow you to manage your Bitwarden container using its straightforward web interface.

Follow our guide on installing Portainer to the Raspberry Pi if you choose to go down that route.

3. After you have Docker installed and chosen whether you want to use Portainer, we can update our operating system.

Updating our Raspberry Pi helps ensure we have an optimized system to run Bitwarden on.

You can update your system by running the following two commands.

sudo apt update
sudo apt upgrade

Installing Bitwarden to the Raspberry Pi

Now that we have prepared our Raspberry Pi, we can move on to installing the Bitwarden software.

As Bitwarden RS is available as a Docker container, the installation process is straightforward.

We have written two guides, one that will show you how to use Portainer to install Bitwarden and one on how to install it using Docker directly.

Using Portainer to Install Bitwarden

For our first section, we will show you how to install Bitwarden on your Raspberry Pi by using the Portainer web interface.

As we mentioned earlier, Portainer is an excellent solution as it will allow you to manage Bitwarden without having to SSH into your Raspberry Pi.

Prepare for the Bitwarden Container

Let us now prepare Portainer so that we can install our Bitwarden container. There are a few steps involved in this process, but they don’t take very long.

1. Start by loading up the Portainer web interface.

This should be accessible by going to your Raspberry Pi’s IP address, followed by port 9000.

https://[PIIPADDRESS]:9000

Ensure that you replace “[PIIPADDRESS]” with your Raspberry Pi’s IP.

2. When you load up the interface, you need to change to the local Docker endpoint.

Click this endpoint so that we can manage the containers available on it.

Open Docker Endpoint in Portainer

3. Before we can create the Bitwarden container, we need to make a volume for it.

In the sidebar, you should see the “Volumes” option, click it.

Change to Volumes Tab

4. Within this menu, you should see a list of volumes you have created already.

At the top of this list, there should be an “Add volume” button. Click the button to switch to the volumes menu.

Change to Add New Bitwarden Volume Screen

5. We need to choose a name to give this new volume. For our tutorial, we will be sticking with “Bitwarden” (1.).

Once you have chosen a name for your Raspberry Pi Bitwarden’s volume, click the “Create the volume” button (2.).

Create Volume for Raspberry Pi Bitwarden

6. With the volume created, we need to change to the “Containers” menu.

You can switch to this by clicking the “Containers” option in the sidebar.

Switch to Containers Tab

7. Below, you should see a list of containers available on your Raspberry Pi.

At the top of this page, click the “Add container” button.

Add new Container to Raspberry Pi

Creating the Bitwarden RS Container for the Raspberry Pi

Now that we have done the initial preparatory work, we can now deploy the Bitwarden container onto our Raspberry Pi.

1. The first thing you need to do for your container is give it a name (1.). We will be calling our own container “Bitwarden“.

Next, we need to specify the image that we want to pull from the Docker hub. In our case, this will be the Bitwarden container for the Raspberry Pi.

Make sure you enter “vaultwarden/server:latest" in the text box next to “Image” (2.)

Set Container Name and Image

2. Next, we need to set the network settings for our container. Look for the “Network ports configuration” header.

Underneath this header, you will need to click the “publish a new network port” button (1.) twice.

You should now have two sets of boxes on the screen that will allow us to set the ports we want to expose from Bitwarden.

2) In the first box, you will need to set both the host to “127.0.0.1:8080“.

You will also need to set the container port to 80 (2.). This is the port that Bitwarden’s web interface will be accessible from.

3) For the second step, you will be required to set the host to “127.0.0.1:3012“.

The “container” port should be set to 3012 (3.). Bitwarden utilizes this port for web socket connections.

We should note that we have bound both of the host ports to the local device.

The reason for this is that we don’t need external devices to access these. Instead, these will be exposed using an NGINX reverse proxy.

Assign Bitwarden Container Ports

3. Scroll down to the bottom of the page till you find the “Advanced container settings” header.

In this section, change to the “Volumes” tab by clicking it (1.).

Next, you need to click the “map additional volume” button so that we can add our Raspberry Pi’s volume to the container (2.).

For the “container” option, make sure you set this to “/data” (3.).

Finally, we need to set the volume to the one we created in the previous section. This should be called “Bitwarden-local” (4.).

Map Volume for Bitwarden

4. Next, we want to make sure Bitwarden is kept online on our Raspberry Pi. We can do this by setting the restart policy.

On this page, click the “Restart policy” option to change the tab (1.).

We want to change the restart policy to “Always“. This will ensure Docker tries to keep the container online when it fails for some reason (2.).

Set Docker Restart Policy

5. Once we have finished configuring the Bitwarden container, we can finally deploy it.

Under the “actions” header on this page, you need to click the “Deploy the container” button.

Deploy Bitwarden Container on the Raspberry Pi

6. Once Portainer finished pulling the Bitwarden docker image to your Raspberry Pi, it will become available in the containers list.

Below, we have a screenshot of our container list after it finished setting up Bitwarden.

Container List with Bitwarden

Installing Bitwarden using the Docker CLI

If you would prefer not to install and utilize Portainer to use Bitwarden on your Raspberry Pi, using the CLI is easy.

Following the steps below, we will get you to pull the Bitwarden image to your device then run it.

1. Our first step is to pull the latest version of Bitwarden RS using Docker.

These steps will download that latest version of the server and make it available to run.

docker pull vaultwarden/server:latest

2. Once Docker finishes downloaded Bitwarden RS to your Raspberry Pi, you can now continue.

Our next step is to run the image itself. We can do this by running the following command.

sudo docker run -d --name bitwarden \
    --restart=always \
    -v /bw-data/:/data/ \
    -p 127.0.0.1:8080:80 \
    -p 127.0.0.1:3012:3012 \
    vaultwarden/server:latest

This command will launch the Bitwarden RS server that we downloaded the image for.

We then define the ports that we want Docker to forward from the Bitwarden image.

In our case, we are exposing the webserver on port “8080“.

We then expose port “3012“, which is the port Bitwarden’s web sockets use to communicate on.

Both of these ports will be locked to the Raspberry Pi’s localhost (127.0.0.1). The proxy server we create in the next section will allow outside access to Bitwarden by setting up HTTPS.

Setting up an NGINX Proxy for Bitwarden

Even though we have Bitwarden up and running now, it isn’t possible to use it until we set up HTTPS.

This is because Bitwarden’s web interface uses certain JavaScript functions that browsers only allow when running on an HTTPS connection.

To achieve support for HTTPS, we are going to have to set up a proxy using NGINX.

NGINX will sit in front of our Raspberry Pi’s Bitwarden server and proxy the requests.

Preparing NGINX on the Pi

Before we can use Bitwarden, we are required to set up NGINX. .

To do that, you need to install the webserver software then generate an SSL certificate for us to use for the HTTPS connection.

1. Before starting this section, we require you to have NGINX already installed.

Follow our guide that shows you how to install NGINX to your Raspberry Pi. You only need to follow the first section as PHP is not required to operate a proxy server.

2. Once you have NGINX installed, we need to generate an SSL certificate for it.

There are two different ways you generate a certificate on your Raspberry Pi.

a) If you plan on using a domain name, you can utilize Lets Encrypt to create a signed SSL certificate.

You can’t generate a signed certificate if only use an IP address as the domain name is used as part of the issuance.

If you choose to go down this route, you will need to note the directory your cert is stored. Once done, skip to step 5 of this section.

b) The alternative is to generate a self-signed certificate. While these are still secure, you will receive a warning that the browser can’t guarantee its authenticity from a certificate authority.

We can generate this cert on the Raspberry Pi by using a single command making it simple to use.

3. If you choose to Let’s Encrypt, you can skip to step 5 of this section. Otherwise, you can continue.

You can use the following command to generate a self-signed certificate.

sudo openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/ssl/private/nginx-bitwarden.key -out /etc/ssl/certs/nginx-bitwarden.crt

This self-signed certificate will last for 365 days and will be stored in the “/etc/ssl/private/” and “/etc/ssl/certs/” directories.

4. During the SSL generation process, you will be asked to provide some additional details.

OpenSSL will write these details to the certificate to help you identify whether or not it’s a forgery.

Country Name (2 letter code) [AU]: AU
State or Province Name (full name) [Some-State]: Tasmania
Locality Name (eg, city) []: Hobart
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Pi My Life Up 
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []: raspberrypi_ip_address
Email Address []: youremail@yourdomain.com

Answer all of the required questions to finish generating the certificate for your Raspberry Pi’s Bitwarden installation.

5. Our final bit of preparation task is to create a strong Diffie-Hellman group.

This is used to help improve the security of your device’s SSL connections.

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Please note that this process can take a little while to complete.

Configuring NGINX to act as Proxy

We can now create a virtual host for NGINX that will allow it to proxy connections to Bitwarden.

Luckily for us, configuring NGINX to act as a proxy is a very straightforward process.

1. First, let us remove the default config file for NGINX.

You don’t need to do this if you are planning on using Bitwarden alongside a domain name.

sudo rm /etc/nginx/sites-enabled/default

2. We need to create a new configuration file for NGINX.

Begin writing this new config file by using the nano text editor by running the command below.

sudo nano /etc/nginx/sites-enabled/bitwarden.conf

3. Within this file, type in the following lines of text.

This first block that we are adding will redirect any traffic from http (port 80) to https (port 443).

server {
    listen 80;
    listen [::]:80;
    server_name _; #Change this to your domain name
    return 301 https://$host$request_uri;
}

4. Next, we need to add our server block that will handle the proxying and the HTTPS connection.

Additionally, if you used Lets Encrypt to generate the certificate, you will need to swap out the paths for both “ssl_certifcate” and “ssl_certificate_key“.

server {
  listen 443 ssl http2;
  server_name _; #Change this to your domain name
  
  ssl_certificate      /etc/ssl/certs/nginx-bitwarden.crt;   #Swap these out with Lets Encrypt Path if using signed cert
  ssl_certificate_key  /etc/ssl/private/nginx-bitwarden.key; #Swap these out with Lets Encrypt Path if using signed cert

  ssl_dhparam /etc/ssl/certs/dhparam.pem;

  # Allow large attachments
  client_max_body_size 128M;

  location / {
    proxy_pass http://0.0.0.0:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
  
  location /notifications/hub {
    proxy_pass http://0.0.0.0:3012;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
  
  location /notifications/hub/negotiate {
    proxy_pass http://0.0.0.0:8080;
  }
}

5. You may need to change a few things depending on how you plan on using your Raspberry Pi Bitwarden server.

If you are using a domain name, you need to replace servername _; to include it.

For example, our server name would be the following “server_name bitwarden.pimylifeup.com“.

6. Once done, your file should end up looking like what we have below.

server {
    listen 80;
    listen [::]:80;
    server_name _; #Change this to your domain name
    return 301 https://$host$request_uri;
}

server {
  listen 443 ssl http2;
  server_name _; #Change this to your domain name
  
  ssl_certificate      /etc/ssl/certs/nginx-bitwarden.crt;   #Swap these out with Lets Encrypt Path if using signed cert
  ssl_certificate_key  /etc/ssl/private/nginx-bitwarden.key; #Swap these out with Lets Encrypt Path if using signed cert

  ssl_dhparam /etc/ssl/certs/dhparam.pem;

  # Allow large attachments
  client_max_body_size 128M;

  location / {
    proxy_pass http://0.0.0.0:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
  
  location /notifications/hub {
    proxy_pass http://0.0.0.0:3012;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
  
  location /notifications/hub/negotiate {
    proxy_pass http://0.0.0.0:8080;
  }
}

7. Once done, you can save this file by pressing CTRL + X, followed by Y, then the ENTER key.

8. Now, all we need to do is restart the NGINX service.

Without restarting the service, it will not be aware of any of our recent changes.

On your Raspberry Pi, run the following command to restart NGINX.

sudo systemctl restart nginx

Accessing the Bitwarden Web Interface

With a proxy server setup, we can now access and use the Bitwarden web interface running on our Raspberry Pi.

1. To access your Bitwarden interface, you need to go to the following address in your favorite web browser.

Make sure that you replace “YOURPIIPADDRESS” with the IP for your Raspberry Pi.

Alternatively, if you are using a domain name, you will need to use that instead.

https://YOURPIIPADDRESS

If you are using a self-signed certificate, you will receive a warning message.

As you know that you generated this certificate yourself and know that you are connecting to your Raspberry Pi, you can ignore this message.

2. Before you can start using Bitwarden, you will need to create an account.

On the login screen, you should see the “Create Account” button. Once you find this button click it.

Choose Create Account for Bitwarden on the Raspberry Pi

3. You can now start to fill out the information for your new account.

The first thing you need to do is enter the email for this Bitwarden account (1.). This email address is what you will use to login.

Next, you need to give a name for Bitwarden to use within its interfaces (2.).

Then you will need to set a password for this account. Make sure that you set this to something secure and not easy to guess (3.).

Before you can finalize the account’s creation, you will be required to agree to Bitwarden’s terms of save and privacy policy (4.).

Once you are happy with all your settings, you can create the account by clicking the “Submit” button (5.).

Creating an Account for Bitwarden

4. As you have now created your account, you can log in to your new Bitwarden vault.

First, you need to fill out the email address you assigned to your account (1.).

Next, you need to enter the password that you set for your new account (2.).

Finally, you can log in by clicking the “Log In” button (3.).

Login to your new Bitwarden Account

5. You can now start storing information in your brand new Raspberry Pi Bitwarden vault.

Raspberry Pi Bitwarden Vault Web Interface

Enabling the Bitwarden Admin Panel

Now that you have created an account, we can now generate the admin token.

The admin token is what you will be using to access the Bitwarden admin panel. This will require us to make changes to our Docker containers configuration.

Within the admin panel, you will be able to view all registered users and delete them. You can even generate invites for new users even if you have disabled the functionality.

This interface is also used to configure the numerous Bitwarden options. Such as whether you want people to be able to sign up.

Generate the Admin Token

Our first step is to generate a new admin token for Bitwarden to utilize.

As this token needs to be a relatively long string of strong randomly generated characters, we will be using openssl.

To generate this secure string, you can run the following command on your Raspberry Pi.

openssl rand -base64 48

Ensure you keep this token secret as this will let anyone have full access to the Bitwarden RS server.

Accessing the Admin Page

We now need to feed this new admin token into our Raspberry Pi’s Bitwarden Docker container.

It is possible to do this using the Portainer web interface or by modifying the command line to feed it in.

Setting the Admin Token using Portainer

To set the admin token, you will need to fire up the Portainer interface and return to the container list.

1. Within the container list, you need to identify the Bitwarden container.

Once you have found it click it to go into its information page.

Select Bitwarden Container to Modify

2. At the top of this next page, there should be a “Duplicate/Edit” button.

You need to click this button to begin editing the the settings of the container.

Edit Existing Container

3. Scroll down this page until you find the “Advanced container settings” heading.

Underneath this heading, you will need to change tabs by clicking the “ENV” option (1.).

You need to click the “add environment variable” so that we can add the admin token (2.).

Clicking this button should add two new text boxes to the bottom of the page.

In the “name” text box, you need to type in “ADMIN_TOKEN” (3.).

For the “value” box, you will need to enter the admin token you want to use (4.).

Finally, once you have the admin token created, you can now click the “Deploy the container” button (5.).

Add the Admin Token

4. Before Portainer will update your Raspberry Pi’s Bitwarden container, you will see the message below.

This message is warning you that it will replace the existing container as the name matches.

You need to click the “Replace” button.

Replace Existing Container

Setting the Admin Token within the Command Line

Updating a container is slightly more complicated when using the command line, as you have to delete the existing container manually.

1. Before we can delete our Raspberry Pi’s Bitwarden container, we will need to take it offline.

You can stop a currently running container by using the following command.

sudo docker stop bitwarden

2. Next, we need to remove the existing container.

Docker will not let us recreate the container if one already exists using the same ports and name.

Remove the existing Bitwarden container by running the command below.

sudo docker rm bitwarden

3. Finally, we need to re-run the docker command.

This time we will be passing in the admin token that we generated earlier.

sudo docker run -d --name bitwarden \
    -e ADMIN_TOKEN=EXAMPLEPIMYLIFEUPADMINTOKEN \
    --restart=always \
    -v /bw-data/:/data/ \
    -p 127.0.0.1:8080:80 \
    -p 127.0.0.1:3012:3012 \
    vaultwarden/server:latest

When you run this new command, make sure that you replace “EXAMPLEPIMYLIFEUPADMINTOKEN” with the token you generated earlier.

Accessing the Bitwarden Admin Panel

Once you have finally gotten your Raspberry Pi’s Bitwarden installation to accept your newly generated admin token, you can now access the admin page.

1. In your web browser, you need to go to the following address.

Make sure that you replace “YOURPIIPADDRESS” with the address to your Raspberry Pi.

https://YOURPIIPADDRESS/admin

Going to this address will take you to the Bitwarden admin panel.

2. On this page, you will need to enter the admin token you generated (1.).

Once you have the token entered, you can log in by clicking the “Enter” button (2.).

Login to Bitwarden Admin Panel

3. You will now have access to the Bitwarden admin panel.

Using these pages, you can manage your users as well as configure Bitwarden’s settings.

Bitwarden Admin Panel

Disable New User Creation

Once you have created an account and set up access to the admin panel, you can choose to disable the user registration menu.

This means that only users you invite personally will be able to create users on your Bitwarden vault.

1. To disable new user creation on your Raspberry Pi’s Bitwarden menu, you will need to load up the admin panel.

Once you are within the admin panel, you can proceed.

2. The option for disabling new user signups is located within the general settings page.

Click the “General settings” menu to reveal all the options hidden under that panel.

Open General Settings Panel

3. Within the “General settings” list of options, you should find one named “Allow new signups“.

You need to click the checkbox next to this option to disable it.

Disable New Signups

4. To confirm the setting changes, you need to scroll to the bottom of the page.

At the bottom, you should see a blue button with the word “Save” on it. Click this button to save these changes.

Save Admin Settings Changes

Conclusion

You should now have Bitwarden up and running on your Raspberry Pi.

Bitwarden is an open-source and free password management software that has clients on most devices.

You can run your own Bitwarden cloud server on your Pi by utilizing a port of the official client that is aimed at not being as resource intensive.

If you have issues with running the server on your device, feel free to leave a comment below.

Be sure to check out some of our other Raspberry Pi server projects or our IoT guides.

48 Comments

  1. Avatar for Peter
    Peter on

    Thanks Emmet for such a great guide which I just setup.

    Is it safe to keep ports 80 & 443 open? I just looked at my Cloudflare dns dashboard and it shows there’s traffic on my domain from Russia, China, USA & Singapore but I’m the only user located in Qld. This traffic is only present when I forward those two ports on my Pi. Is this normal or should I keep these ports closed? Thanks.

    1. Avatar for Emmet
      Emmet on
      Editor

      Hi Peter,

      There is always going to be a potential risk with leaving any ports open on your network. There are bots that will continually attempt to breach any open ports using known vulnerabilities.

      As long as there isn’t any vulnerabilities with the software you have running on those ports, you should hopefully be fine.

      It is possible to use a service like Cloudflare to lock down access to those ports if you are using their proxy (Not using it as a plain DNS). You can for example, block countries where you don’t expect any connections to be coming from. Cloudflare is a very powerful tool with some very useful security features that are worth exploring.

      Please let me know if I can help you further.

      Kind Regards,
      Emmet

  2. Avatar for Rod
    Rod on

    Is it possible to add the nginx proxy manager docker container with this setup?
    Can the proxy be applied to other services that require https?

    1. Avatar for Emmet
      Emmet on
      Editor

      Hi Rod,

      Yes, you should be able to follow both of our guides. The operate on different ports so there should be no conflicts there.

      You can put the NGINX proxy in front of any web service, including Bitwarden.

      Kind regards,
      Emmet

  3. Avatar for vagenthar
    vagenthar on

    Hi many thanks for this tutorial. Is there any way to connect to my pi server via the app on iphone? App throws error about certificates. I used the Diffie-Hellman group method.

    1. Avatar for Emmet
      Emmet on
      Editor

      Hi Vagenthar,

      To connect the app from your iPhone to your pi server you will need to be using a signed certificate. The reason for this is that the app blocks any certificate it can’t verify.

      The only other work around would be to manually add the self-generated SSL certificate to your iPhone.

      Cheers,
      Emmet

Leave a Reply

Your email address will not be published. Required fields are marked *