Apologies for the delay coming back to this but been busy with a few things and having little time for my Bitwarden project. Yesterday I’ve managed to get it up and running.
I’ll try to give some context in a nutshell, hope you don’t mind and I don’t sound condescending (not intended at all, specially as I’m not an expert):
From an end user perspective I’d rather think it as a “micro virtual machine”: it will be executing within your host and allow you to run stuff on that container as if you’d remote control a virtual machine (for instance you can launch an interactive shell). How it works below the surface is way different from a VM but as a person interested in having a software deployed in an isolated manner, is a similar experience.
Besides the containers themselves, you might hear about stacks which are basically a group of containers that work together to provide a given service. For instance Bitwarden Unified will require bot the application itself and its database, so is a good choice to create a stack with one container for the application (using the BitWarden Unified image) and another for the database (there you have different options as many database engines are supported).
I’ve been using Portainer for about half year but lately I’ve started moving out of its stack management as it was a bit limiting for my stuff; right now I’m using docker compose for the stacks setup directly (still using Portainer for inspecting and connecting to the containers). In any case, I think Portainer is good enough for this use case, but in the end it leans on docker compose so the knowledge for configuring the stack is the same.
That’s the very basic. Then docker has a lot of things you can tweak with for given the containers real usage (otherwise they’d be just an isolated box):
- volumes: mounting host file system onto the container
- port mapping: mapping the container ports into the hosts ports to allow extenal connections
- networks: allow to different containers to communicate to each other by joining a network
- secrets: prevent using environment variables for setting up sensitive data
- resource limits: to prevent containers taking too much from the host
- etc etc etc
Setup with a Reverse Proxy
I’m sharing a version of my solution, in case it helps. Unfortunately this includes using a reverse proxy that I had set up before and is outside the solution so it can be confusing; the reason for that is that Bitwarden app won’t work without SSL so you either configure the certificate on the container itself or have a proxy on top of that (you can check this comment with some thoughts around that) . In any case here it goes an example for the compose.yaml
(or the stack definition):
name: bitwarden
services:
app:
image: bitwarden/self-host:beta
depends_on:
- db
volumes:
- /my-stacks/bitwarden/bitwarden-data:/etc/bitwarden # where /my-stacks/bitwarden/bitwarden-data is a directory on your local filesystem where you'd like the container to keep it's persistent storage (in this case some encryption keys, certificates and logs)
environment:
# Server hostname
BW_DOMAIN: my-bitwarden.my-domain # This assumes you have your own domain. If not exposing to the internet you can use .local or similar stuff
# Database
BW_DB_PROVIDER: mysql
BW_DB_SERVER: db # See the other container configuration for explanation on this value
BW_DB_DATABASE: my-bitwarden-database-name
BW_DB_USERNAME: my-user
BW_DB_PASSWORD: my-strong-password-for-my-user
# Installation information - obtained from https://bitwarden.com/host/
BW_INSTALLATION_ID: my-guid-taken-from-bitwarden
BW_INSTALLATION_KEY: my-secret-taken-from-bitwarden
# if you'd like to prevent registration, after your users are registered you'll need to uncomment next line and restart the stack
# globalSettings__disableUserRegistration: true
# Email - Needed for getting verification emails, alerts, etc. You can use the tool without this but I don't think is a good idea. Leaving an example with gmail
globalSettings__mail__replyToEmail: [email protected]
globalSettings__mail__smtp__host: smtp.gmail.com
globalSettings__mail__smtp__port: 587
globalSettings__mail__smtp__ssl: true
globalSettings__mail__smtp__username: [email protected]
globalSettings__mail__smtp__password: my-16chars-app-password # Check https://support.google.com/accounts/answer/185833?hl=en for how to create and use this
networks:
default:
reverse-proxy-network: # joining the container to a network with the reverse proxy
aliases:
- bitwarden.local # the name used for thereverse proxy to reach this container. Basically this means that the reverse proxy is mapping anything that targets https://my-bitwarden.my-domain to http://bitwarden.local:8080, being 8080 the default port used by Bitwarden
db: # This is used also as the hostname, that's why same literal is in the BW_DB_SERVER variable
image: lscr.io/linuxserver/mariadb:latest
environment:
MYSQL_DATABASE: my-bitwarden-database-name
MYSQL_USER: my-user
MYSQL_PASSWORD: my-strong-password-for-my-user
MYSQL_ROOT_PASSWORD: my-super-strong-password-for-root-access
volumes:
- /my-stacks/bitwarden/mysql:/config # where /my-stacks/bitwarden/mysql is a directory on your local filesystem where you'd like the container to keep it's persistent storage (in this case both database files and mariadb configuration)
networks:
reverse-proxy-network: #the docker network where the reverse proxy is located
external: true
Any place where you find a
my-
prefix, is because that value shoud be decided and configured
Hope this is helpful. Cheers