Self Hosted Password Manager Using Docker

Published by

on

Time to read:

3 minutes

In this post we are going to cover how to use Docker compose to build a self hosted password manager. I will be using VaultWarden as the password manager in container form with Nginx acting as a reverse proxy in front of the password manager again in container form.

NOTE: You will need some form of web certificate. This can be self-signed locally on the box you are using or if you have a home certificate authority. If you go this route you need to make sure the CA certificate is installed on any devices you want to connect to the Vault Warden server because the mobile BitWarden application and some web bowers will not allow you to connect if you have an untrusted certificate. Alternatively, you can get a certificate signed by a 3rd party certificate authority that is already trusted on your devices.

NOTE: In my example I will be using Redhat based Linux so adjust any command as needed if you are working on the Debian side.


  1. Section I – Docker Installation
  2. Section II – Pre-Configuration
  3. Section III – Docker-Compose Configuration
    1. Example 1 – docker-compose.yml
  4. Section IV – Nginx Configuration
    1. Example 2 – nginx.conf
  5. Section V – Starting and Stopping Services
  6. Section VI – Accessing

Section I – Docker Installation

Install docker on your machine, using the following command:

dnf install docker

Install docker compose on your machine, use the following command: NOTE: depending on your Linux version you may have to follow a guide like this.

dnf install docker-compose

Section II – Pre-Configuration

You need to create a working directory for Vault Warden. In my case I want to make the Vault Warden database accessible on my host system along with my Nginx configuration file and certificate. You can just as easily set up a persistent volume for the containers rather than creating mount points to the host system.

Create VaultWarden directory, in my case it is /mnt/VaultWarden.

Create the docker network for VaultWarden and Nginx to communicate on:

docker network create vaultwarden_network

Set up a temporary VaultWarden instance to get the Admin Password hash using the following command:

docker run --rm -it vaultwarden/server /vaultwarden hash

Take the hash output from inside the single quotes and will use Stream EDitor (SED) to manipulate it:

echo 'AUTHENTICATION_TOKEN' | sed 's#\$#\$\$#g'

Section III – Docker-Compose Configuration

Within the VaultWarden directory create the ‘docker-compose.yml’ file:

version: '3'

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: always
    labels:
      nginx.reverse_proxy: "{{upstreams}}"
    environment:
      - WEBSOCKET_ENABLED=true
      - SIGNUPS_ALLOWED=true
      - INVITATIONS_ALLOWED=false
      - ADMIN_TOKEN=$$ADMIN-TOKEN
      - DOMAIN=https://<IP or Hostname>
    volumes:
      - /mnt/VaultWarden:/data
    networks:
      - vaultwarden_network
    depends_on:
      - nginx
  nginx:
    image: nginx
    container_name: reverse_proxy
    restart: always
    ports:
      - 80:80
      - 443:443
    volumes:
      - /mnt/VaultWarden/nginx.conf:/etc/nginx/nginx.conf
      - /mnt/VaultWarden/ssl:/etc/nginx/certs
    networks:
      - vaultwarden_network
networks:
  vaultwarden_network:
    external: true

Example 1 – docker-compose.yml

Make sure that the admin token does not have quotes around it!

Section IV – Nginx Configuration

Make sure that the certificate and key file are in the location stated in the docker compose file. In my case they are stored in ‘/mnt/VaultWarden/ssl’.

Create a file within the VaultWarden directory for the Nginx configuration called ‘nginx.conf’. Again, like the certificates this needs to match what was in the docker compose file.

events {
  worker_connections  1024;
}

http {
  server {
    listen 80;
    server_name <IP or Hostname>;
    return 301 https://$host$request_uri;
  }

  server {
    listen 443 ssl;
    server_name <IP or Hostname>;

    ssl_certificate /etc/nginx/certs/server.crt;
    ssl_certificate_key /etc/nginx/certs/server.key;

    location / {
      proxy_pass http://<VaultWarden Docker Container Name>:80;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
    }
  }
}
Example 2 – nginx.conf

Section V – Starting and Stopping Services

In order to start the VaultWarden and Nginx containers use the following command:

docker-compose up -d

You can use the following command in order to check if the containers are running:

docker ps

In order to stop the VaultWarden and Nginx containers use the following command:

docker-compose down

Section VI – Accessing

Once the containers are up and running you can browse using any web browser to ‘https://<IP or Hostname>’. Additionally, you can connect the BitWarden application to the VaultWarden server by selecting ‘Self Hosted’ and entering your servers IP or Hostname before logging in.

Leave a comment