Running Bitwarden in Docker - Setup step by step

Diese Seite gibt es auch in Deutsch

Bitwarden is a web-based password manager, similar to LastPass, but open source and the ability to run (host) it yourself. How Bitwarden compares to other password managers, I have considered on the following page: Password Managers Secure? KeePass vs LastPass vs BitwardenBitwarden consists of several services, which can be provided via different containers. The relatively complex setup has been simplified with "Bitwarden Unified" especially for self-hosting by packing all services into one container. Alternatively, Vaultwarden is a Bitwarden-compatible server with lower system requirements.

Docker Basics

Docker allows applications to be launched by command in a so-called container.
A container is an isolated environment independent of the operating system (OS):
When a container is first launched, Docker independently loads all the necessary sources
from the internet.
Docker can be installed on Windows, macOS or an Linux Distribution

To ensure that Bitwarden is can be reached securely from the Internet, I use a Let's Encrypt reverse proxy. At first I used Nginx as Reverse-Proxy, but later replaced it with Traefik. The reverse proxy provides an encrypted HTTPS connection and makes it possible to run multiple websites on one server.

Step by step Bitwarden and Docker including access from the internet

Hardware requirement:
  1. Almost any hardware can be used for the Docker installation: For example, a virtual server of a provider, or for home: a Mini-PC, notebook, Raspberry PI, MAC, a NAS: QNAP, Synology or any other hardware on which Windows or Linux can be installed.

Schematic representation: Access from the Internet
Internet access requirements:
  1. In the case of a rented server from a provider, the provider assigns an IP address. If you want to operate a server in your own home network, you additionally need to set up port forwarding.
  2. The access from the Internet is best done via a domain with a DNS entry to the public IP address, see Domain and its management. If you do not have your own domain, you can also use a DynDNS service to access your home network.
  3. For the certificate management and access to the web services I use a reverse proxy and Let's Encrypt certificates.
Container for Bitwarden:
  1. Create and customize Docker-compose file:
  2. Start container
  3. Calling the web interface in the browser

Bitwarden Unified

Bitwarden profile:

SoftwareServer
GitHubhttps://github.com/bitwarden/server
current version 2023.1.0
found2023-01-13

Currently, the Unified variant of Bitwarden is still in beta and thus not suitable for production use. If you still want to test Bitwarden Unified, you can do so with the following setup:

Bitwarden Unified docker-compose.yml

To start Bitwarden using docker compose, the Docker image can be downloaded, created and started with a simple docker-compose.yml file. The file can be filled with any text editor as follows and then customized:

Filename: docker-compose.yml, Content:

[+]
version: "3.8"
services:
  bitwarden:
    depends_on:
      - db
    environment:
      BW_DB_PROVIDER: "mysql"
      BW_DB_SERVER: "db"
      BW_DB_DATABASE: "bitwarden_vault"
      BW_DB_USERNAME: "bitwarden"
      BW_DB_PASSWORD: "super_strong_password"
      BW_DOMAIN: "bitwarden.domain.tld"
      #the Install-Key can be requested at the following site: https://bitwarden.com/de-DE/host/
      BW_INSTALLATION_ID: "???"
      BW_INSTALLATION_KEY: "???"
      #add Email-Server-Settings
      globalSettings__mail__replyToEmail: "noreply@domain.tld"
      globalSettings__mail__smtp__host: "mail.domain.tld"
      globalSettings__mail__smtp__port: "587"
      globalSettings__mail__smtp__ssl: "false"
      globalSettings__mail__smtp__username: "smtpusername"
      globalSettings__mail__smtp__password: "smtppassword"
      #Allow Registrations?
      globalSettings__disableUserRegistration: "false"
      #Admin-Accounts:
      adminSettings__admins: "admin1@email.com,admin2@email.com"
    #Labels for ReverseProxy, see: https://www.libe.net/en-traefik
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.bw.rule=Host(`bitwarden.libe.net`)"      
      - "traefik.http.routers.bw.entrypoints=web"
      - "traefik.http.routers.bw.entrypoints=websecure"
      - "traefik.http.routers.bw.tls.certresolver=myresolver"
      - "traefik.http.services.bw.loadbalancer.server.port=8080"
    image: bitwarden/self-host:dev
    restart: always
    expose:     
      - "8080"
   #For direct test access, remove "#" in the following 2 lines. Call: http://localhost:8080 or http://ServerIP:8080
    #ports:
    #  - "8080:8080"
    volumes:
      - ./bitwarden:/etc/bitwarden
      - ./logs:/var/log/bitwarden
  db:
    environment:
      MARIADB_USER: "bitwarden"
      MARIADB_PASSWORD: "super_strong_password"
      MARIADB_DATABASE: "bitwarden_vault"
      MARIADB_RANDOM_ROOT_PASSWORD: "true"
    image: mariadb:10
    restart: always
    volumes:
      - ./db:/var/lib/mysql

#Without using a reverse proxy (https://www.libe.net/en-traefik) the webproxy network is likely to be missing
#and the following lines can be removed or commented out. Alternatively, the network can be created with "docker network create webproxy".
networks:
  default:
    external:
      name: webproxy

For direct access via IP address or localhost - also without reverse proxy, DNS or public IP - the commented out port setting can be activated for test purposes by adding "#" in front of "ports:" and "-"8080:8080"" is removed. If the reverse proxy is not used, the network webproxy is not needed and the networks: .. section can be removed.

For Internet access via Traefik reverse proxy, the domain must be replaced in the labels with the previously created DNS records (in the example: bitwarden.domain.tld).

The connection data for the MySQL database should be adjusted accordingly and the data for BW_INSTALLATION_ID and BW_INSTALLATION_KEY should be filled. The installation ID and its key can be requested from the manufacturer's site: https://bitwarden.com/de-DE/host/.

In addition, Bitwarden requires a mail server. I therefor use the following setup: Running Docker Mailserver myself | a field report.

The example uses bind mounts and no Docker volumes for permanent storage of the data. See: Docker data storage: Docker volumes vs. host folders

Starting Bitwarden Containers

The startup is done from the folder of the docker-compose.yml file with the command "docker-compose up":

docker-compose up -d

After launching the container, Bitwarden will log on to the specified domain.

Here is a screenshot of the required system resources right after the first start:

Using Bitwarden

After starting the containers, new accounts can be created via the web interface:

Admin Portal

The admin portal can be accessed via https://domain.tld/admin. The mail address of the admin user must be stored in the docker-compose.yml file:

..
      adminSettings__admins: "admin@domain.tld"
..

The call is made via the defined domain https://domain.tld/admin.

Afterwards, the access is done via a link sent by mail:

Prohibit new registrations

To prevent new users from registering, the following setting can be adjusted in the docker-compose.yml file:

..
      globalSettings__disableUserRegistration: "true"      
..

The setting will be active at the next "docker-compose up -d".

Vaultwarden

Vaultwarden profile:

SoftwareVaultwarden
GitHubhttps://github.com/dani-garcia/vaultwarden
current version 1.27.0
found2022-12-29

Vaultwarden is an alternative implementation of the Bitwarden Server API, written in Rust and compatible with Bitwarden clients.

Vaultwarden docker-compose.yml

If you prefer Vaultwarden, this alternative docker-compose.yml file can be used:

[+]
# docker-compose.yml
version: '3'

services:
  bitwarden:
    image: vaultwarden/server
    restart: always
    expose:
       - "80"   
    #Für einen direkten Test-Zugriff, in den folgenden 2 Zeilen "#" entfernen. Aufruf: http://localhost:83 oder http://ServerIP:83
    #ports:   
      #- "83:80" 
    volumes:
      - ./bw-data:/data
    environment:
      WEBSOCKET_ENABLED: 'true' # Required to use websockets
      SIGNUPS_ALLOWED: 'true'   # set to false to disable signups
      ADMIN_TOKEN: "mytoken2change"

   #Labels für ReverseProxy, siehe: https://www.libe.net/traefik
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.home.rule=Host(`bitwarden.domain.tld`)"      
      - "traefik.http.routers.home.entrypoints=web"
      - "traefik.http.routers.home.entrypoints=websecure"
      - "traefik.http.routers.home.tls.certresolver=myresolver"
      - "traefik.http.services.home.loadbalancer.server.port=80"

#Ohne dem Einsatz eines Reverse Proxy (https://www.libe.net/traefik) fehlt voraussichtlich das Netzwerk webproxy 
#und die folgenden Zeilen können entfernt oder auskommentiert werden. Alternativ kann das Netzwerk mit "docker network create webproxy" erstellt werden
networks:
  default:
    external:
      name: webproxy

Before starting, the ADMIN_TOKEN should be adjusted, this is similar to a password for access to the admin interface. For Internet access via the Traefik reverse proxy, the domain must also be replaced in the labels with the previously created DNS entries (in the example: bitwarden.domain.tld) . This example also uses bind mounts and no Docker volumes for permanent data storage. See: Docker data storage: Docker Volumes vs. Host Folders

Starting Vaultwarden Container

The startup is again done with the command "docker-compose up":

docker-compose up -d

Unlike Bitwarden, Vaultwarden does not use its own database, but a SQLite database, this is located in the bw-data folder after startup.

A look at the resource consumption using docker stats shows the much smaller footprint of Vaultwarden:

Vaultwarden needs initially not even 8 MB, Bitwarden in comparison about 570 MB with database ...

Setting up Vaultwarden

The call is again made from the specified domain, according to the example: https://bitwarden.domain.tld

Create account

A user account can be created the first time the website is called:

Admin Portal

Setup settings can be made in the admin portal. The admin token specified in the docker-compose.yml file and the URL "/admin" are used for access:

To allow me to determine who can use the password manager, I disabled signups.

Invited users can still use the password manager. If an unknown person registers, the following error is displayed:

An error has occurred. Registration not allowed or user already exists.

SMTP settings

For sending mails I used the following settings.

As mail server I use the following setup: Running Docker Mailserver yourself | a field report

positive Bewertung({{pro_count}})
Rate Post:
{{percentage}} % positive
negative Bewertung({{con_count}})

THANK YOU for your review!

Updated: 2023-01-13 von Bernhard 🔔


Top articles in this section


Nextcloud Server Docker | Setup + https: Let's Encrypt [ssl]
To synchronize contacts, appointments, and photos of my NAS, I tested Nextcloud and thus turned my back on other cloud providers for my private data. Thanks to Docker, the installation is easier and more flexible than ever, allowing Nextcloud to run on almost any hardware.

Commissioning Zigbee2MQTT in Docker - step by step
Zigbee2MQTT is an open source Zigbee bridge which can be easily integrated into existing smart home solutions thanks to the MQTT network protocol. As an example, Zigbee2MQTT combined with MQTT broker Mosquitto and Home Assistant can collect, display, record and control data from Zigbee devices. The setup described here uses Docker as a base. Manufacturer's website: https://www.zigbee2mqtt.io

Home Assistant Docker Conbee 2 and Zigbee2MQTT / deCONZ
Thanks to numerous integration options, Home Assistant is a simple platform for controlling a wide range of smart home devices. Compared to ioBroker, I found it much easier to get started with Home Assistant. While for ioBroker I was still searching for which frontend I could use for my dashboards, with Home-Assistant I had a ready-made system out of the box. Home Assistant's Lovelance dashboards can be easily clicked together in the GUI and adapted for special customizations in the code edito...

Questions / Comments


By continuing to browse the site, you agree to our use of cookies. More Details