After Setting up my old and trusted KeePass+Nextcloud Combo and struggling with synchronization conflicts as well as integration problems with Firefox, I decided to give Bitwarden a go.

UPDATE: Instead of manually setting up the Docker container, I now use docker-compose to set it up. It automatically spawns a second container, backing up the database so I can run a backup of my passwords.

The concept is simple: It's FOSS, everything is encrypted client side. All normal functionality (imho) is available for free, premium costs 10$/year or for a family of up to five its 12$/year (1$/month). Being an open protocol you can obviously host it yourself. What I don't get though is why I would have to pay a monthly subscription fee for the premium features even if I host it myself. Therefore I decided to install dani-garcia/bitwarden_rs on my Synology NAS in a Docker container. Here's a short list of To-Dos:

  1. Setup a (sub-)domain. Mine's hosted at inwx.de, so I created a CNAME entry for my existing setup. I'll use pass.example.tld here.
  2. Get a certificate for that domain. This one's easy through the interface and Let's Encrypt. If you already have one for other services, don't worry you can have multiple certificates for different (sub-)domains.  (Settings -> Security -> Certificates -> Add)
  3. Add a reverse proxy. This forwards requests to your new (sub-domain) from port 443 (https) to the port the Docker container is running on. I'm going to use 8123 here, but any port is fine. This way you can have multiple services be reachable on the https port with different (sub-)domains. (Application Portal -> Reverse Proxy -> Create).
    Just give it a good name like "Bitwarden"; for source choose HTTPS, hostname is pass.example.tld, port 443. Destination is HTTP, localhost, port 8123. Which is where your Docker container is going to be.
  4. Download the image. Go to the Registry in the Docker interface (Install Docker from the Package Manager if you haven't already) and download the image for bitwardenrs/server:latest.
  5. Launch the image. Go to Images in the Docker interface and launch it. The name is arbitrary, mine's bitwardenrs. Go to "Advanced Settings".
  6. Configure bitwarden.
    1. Activate automatic restart.
    2. Go to volume and map docker/bitwardenrs from the NAS to /data inside the container.
    3. Got to ports and map the container port 80 to the local port 8123. 3012 is the port for the WebSocket, which we won't use for now.
    4. Got to environment variables. First set DOMAIN=https://pass.example.tld, otherwise things might magically break. I like to restrict signups to my domain so I set SIGNUPS_DOMAINS_WHITELIST=example.tld. To disable signups completely just set SIGNUPS_ALLOWED=false. If you want to be able to register you also need to configure environment variables for an SMTP Server.
  7. Enjoy.

This setup uses environment variables instead of the config.js. Be aware, that any configuration you might do in the admin interface (and thereby config.js) overwrites this.

UPDATE: Here's the docker-compose.yml. It's the same as above, but also spawns a second container bitwarden-backup based on bitwarden_rs-backup that backs up the database to db_backupfolder next to the original database every 3rd of a month at midnight (because my NAS backup runs at 0h30).

version: '3'

services:
    bitwarden:
        image: bitwardenrs/server:latest
        hostname: nas
        restart: always
        ports:
          - 8123:80
        volumes:
          - /volume1/docker/bitwardenrs:/data
        environment:
          - DOMAIN=https://pass.stabel.family
          - SIGNUPS_DOMAINS_WHITELIST=stabel.family
          - SMTP_PASSWORD=Bb2dmvj6P221HbwjVNrN
          - SMTP_USERNAME=nas@stabel.uber.space
          - SMTP_SSL=true
          - SMTP_PORT=587
          - SMTP_FROM=nas@stabel.family
          - SMTP_HOST=johnson.uberspace.de
    bitwarden-backup:
        image: bruceforce/bw_backup:latest
        restart: always
        depends_on:
          - bitwarden
        volumes:
          - /volume1/docker/bitwardenrs:/data
        environment:
          - CRON_TIME=0 0 3 * *
          - UID=0
          - GID=0
          - TIMESTAMP=false

Image: Kspearrin CC BY-SA 4.0