paint-brush
Running Vaultwarden in a Container as a systemd Service Using Podmanby@atabakoff
1,933 reads
1,933 reads

Running Vaultwarden in a Container as a systemd Service Using Podman

by Aleksandr TabakovJune 1st, 2022
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Install Podman and pull & run Vaultwarden: sudo podman pull vaultwarden/server:latest sudo podman run -d --name vaultwarden.pod -e ADMIN_TOKEN=YOUR_RANDOM_TOKEN_GOES_HERE -v /vw-data/:/data/ -p 8000:80 vaultwarden/server:latest Create a service file under `/etc/systemd/system/vaultwarden.pod.service` and put the following content: [Unit] Description=Vaultwarden/Bitwarden Server (Rust Edition) Documentation=https://github.com/dani-garcia/vaultwarden Wants=syslog.service [Service] Restart=on-failure ExecStart=/usr/bin/podman start -a vaultwarden.pod ExecStop=/usr/bin/podman stop vaultwarden.pod [Install] WantedBy=multi-user.target Reload the daemon and you are ready to go: sudo systemctl daemon-reload

Company Mentioned

Mention Thumbnail
featured image - Running Vaultwarden in a Container as a systemd Service Using Podman
Aleksandr Tabakov HackerNoon profile picture

What is Vaultwarden?

Vaultwarden is an alternative implementation of Bitwarden server API written in Rust. It’s compatible with official Bitwarden clients and is a perfect choice for a self-hosted vault. Being written in Rust makes it lightweight, unlike the original Bitwarden which is written in C# and quite resource-heavy.

Why Podman?

Docker doesn’t work properly with systemd. The problem is that systemd doesn’t monitor a docker container but a docker client. It means if the container crashes but the client is running, the systemd will not restart the container. It’s caused by Dockers’ client-server architecture. There’s a workaround for it but using a native solution seems more reasonable.

Podman is an open-source, daemon-less, Linux-native tool to run containers. It was developed under OCI standards and it works perfectly with systemd. Because of its daemon-less nature, it allows running containers under an arbitrary user.

Install Podman

I will show how to install podman in Ubuntu 20.10, for other distributions refer to the official guide :

sudo apt update
sudo apt install podman

Run Vaultwarden

My normal setup includes the admin panel enabled and registration of new users disabled. To enable the admin panel we have to pass an ADMIN_TOKEN environment variable. It is recommended to use a long random string for this value. We can generate it using the openssl rand command:

openssl rand -base64 48


One more thing to do before we run our vault is to create a data directory. In this directory Vaultwarden stores its config and database:

sudo mkdir /vw-data


Now everything is ready to run Vaultwarden:

sudo podman pull vaultwarden/server:latest
sudo podman run -d --name vaultwarden.pod -e ADMIN_TOKEN=YOUR_RANDOM_TOKEN_GOES_HERE -v /vw-data/:/data/ -p 8000:80 vaultwarden/server:latest

Create systemd service

Create a service file under /etc/systemd/system/vaultwarden.pod.service:

sudo touch /etc/systemd/system/vaultwarden.pod.service


I like to have the .pod suffix to differentiate native services from containerized services.


Put the following content to the service file:

[Unit]
Description=Vaultwarden/Bitwarden Server (Rust Edition)
Documentation=https://github.com/dani-garcia/vaultwarden
Wants=syslog.service

[Service]
Restart=on-failure
ExecStart=/usr/bin/podman start -a vaultwarden.pod
ExecStop=/usr/bin/podman stop vaultwarden.pod

[Install]
WantedBy=multi-user.target


Here are a few things worth pointing out:

  • Restart=on-failure is instructing to only restart the service when it exits with non-zero code. It allows us to stop the service using the podman stop as well as the systemctl command.
  • To store the container’s logs to syslog we have podman start -a. The -a option instructs to attach the container’s STDOUT and STDERR.
  • WantedBy is needed to start our container on system boot. The multi-user.target option basically means that the service should be started when all network services are up and the system is ready to accept logins. If you omit the WantedBy option your service will NOT start on boot.
  • The Wants=syslog.service option tells that syslog should be started when our service is being started. However, it’s a weak requirement and the service will still start if syslog fails to start. In other words, we would like to have logs but it’s not mandatory for our service.


Reload the daemon:

sudo systemctl daemon-reload


And check the Vaultwarden status:

sudo systemctl status vaultwarden.pod
● vaultwarden.pod.service - Vaultwarden/Bitwarden Server (Rust Edition)
     Loaded: loaded (/etc/systemd/system/vaultwarden.pod.service; disabled; vendor preset: enabled)
     Active: active (running) since Thu 2022-05-26 15:25:08 UTC; 1 day 20h ago
       Docs: https://github.com/dani-garcia/vaultwarden
   Main PID: 19461 (podman)
      Tasks: 11 (limit: 1112)
     Memory: 26.9M
     CGroup: /system.slice/vaultwarden.pod.service
             ├─19461 /usr/bin/podman start -a vaultwarden.pod
             └─19574 /usr/libexec/podman/conmon --api-version 1 -c e2a6a794ddf8bb74308a9f64b98871913f6a46a8370c921dcb353f5db721cea0 -u e2a6a794ddf8bb74308a9f64b98871913f6a46a8370c921dcb353f5db721cea0 -r /usr/bin/crun -b /var/lib/containers/storage/overlay-containers/e2a6a7>


Now you can stop/start the Vaultwarden service:

sudo systemctl stop vaultwarden.pod
sudo systemctl start vaultwarden.pod


Previously published here.