In this tutorial, we’ll deploy Bitwarden on Docker Swarm. It’s based on an earlier tutorial on this site, where we deployed Docker Swarm on DigitalOcean.

Bitwarden is a password manager with support for self-hosting. We’ll use bitwarden_rs, an unofficial Bitwarden API server implementation, as it’s a bit faster than the default implementation. Bitwarden_rs is written in Rust and is compatible with the official Bitwarden clients.

Bitwarden has the following features, among others:

The tutorial assumes you have a Docker Swarm cluster running and root access to your nodes.

Prepare Manager Node

Use ssh to connect to your manager node and create a directory where we’ll store our Bitwarden files. In this example, we’ll use /var/swarm/bitwarden (and /var/swarm/bitwarden/data for data):

# mkdir -p /var/swarm/bitwarden/data

Configure Bitwarden Deployment

Configure Bitwarden by changing the docker-compose.yml file below, making sure example.com matches your domain name and potentially disabling signups:

# vim /var/swarm/bitwarden/docker-compose.yml
version: "3"
services:
  bitwarden:
    image: bitwardenrs/server
    volumes:
      - /var/swarm/bitwarden/data:/data
    environment:
      SIGNUPS_ALLOWED: "true" # set to false to disable signups
    networks:
      - proxy
    deploy:
      labels:
        - traefik.enable=true
        - traefik.backend=bitwarden
        - traefik.backend.loadbalancer.swarm=true
        - traefik.docker.network=proxy
        - traefik.frontend.rule=Host:bitwarden.example.com
        - traefik.port=80
        - traefik.frontend.headers.SSLRedirect=true
        - traefik.frontend.headers.STSSeconds=315360000
        - traefik.frontend.headers.browserXSSFilter=true
        - traefik.frontend.headers.contentTypeNosniff=true
        - traefik.frontend.headers.forceSTSHeader=true
        - traefik.frontend.headers.SSLHost=bitwarden.example.com
        - traefik.frontend.headers.STSIncludeSubdomains=true
        - traefik.frontend.headers.STSPreload=true
        - traefik.frontend.headers.frameDeny=true
      placement:
        constraints:
          - node.role == manager
networks:
  proxy:
    external: true

For more configuration options, refer to the bitwarden_rs documentation.

Deploy Bitwarden

Finally, let’s deploy Bitwarden:

# docker stack deploy bitwarden --compose-file /var/swarm/bitwarden/docker-compose.yml

It’ll take a few seconds until Bitwarden is up and running. Once it is, visit bitwarden.example.com to access the web interface.

Last Words

Would you like to know more about privacy, security, and Docker? Here are some book recommendations:

Audible has many books on these topics and others. If you sign up using this link, you’ll get 30 days for free!

If you don’t have a Docker Swarm cluster running already, I can recommend using DigitalOcean to host one. Using this link, you’ll get $50 to spend on their services for 30 days. 😊

Revision

2023-08-31 Revised language

2019-11-04 Removed unnecessarily exposed ports and incorrect environment variable. Thanks mhaluska!