mirror of
https://github.com/dani-garcia/vaultwarden.wiki.git
synced 2026-03-27 07:28:31 +07:00
284 lines
9.2 KiB
Markdown
284 lines
9.2 KiB
Markdown
[Podman](https://podman.io/) is a daemonless alternative to Docker, which is mostly compatible with Docker containers.
|
|
|
|
# Creating a Quadlet (Podman 4.4+)
|
|
|
|
As of version 4.4, Podman uses [quadlets](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html) and will show a warning if you use the previous `generate systemd` method.
|
|
|
|
Additional benefit is that this method will keep the container updated.
|
|
|
|
## Configuration via environment file
|
|
|
|
Configuration may be easier in an environment file and less error-prone.
|
|
|
|
*NOTE*: this file contains secrets, make sure only root has access!
|
|
|
|
```sh
|
|
sudo install -o0 -g0 -m600 /dev/null /etc/vaultwarden.env
|
|
sudo vi /etc/vaultwarden.env
|
|
```
|
|
|
|
```sh
|
|
# Contents of /etc/vaultwarden.env
|
|
ROCKET_PORT=8080
|
|
|
|
# DISABLE_ADMIN_TOKEN=true
|
|
# ADMIN_TOKEN=$argon2id$...
|
|
|
|
# LOG_LEVEL=debug
|
|
```
|
|
|
|
## Creating the podman quadlet
|
|
|
|
Configuration looks like systemd's but we configure a Container, not a Unit. See the [documentation](https://man.archlinux.org/man/quadlet.5.en#Container_units_%5BContainer%5D) for all `[Container]` directives.
|
|
|
|
```conf
|
|
# Content of /usr/share/containers/systemd/vaultwarden.container
|
|
[Unit]
|
|
Description=Vaultwarden container
|
|
After=network-online.target
|
|
|
|
[Container]
|
|
AutoUpdate=registry
|
|
Image=ghcr.io/dani-garcia/vaultwarden:latest
|
|
Exec=/start.sh
|
|
EnvironmentFile=/etc/vaultwarden.env
|
|
Volume=/vw-data/:/data/
|
|
PublishPort=8080:8080
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
```
|
|
|
|
After editing the quadlet, run `systemctl daemon-reload` to create or updates the systemd unit. You control this container using regular `systemctl` commands, e.g. `systemctl start vaultwarden.service`.
|
|
|
|
## Auto update
|
|
[auto-update](https://docs.podman.io/en/latest/markdown/podman-auto-update.1.html#description) automates the update process.
|
|
```sh
|
|
sudo podman auto-update
|
|
```
|
|
Or, you can enable the timer which invokes auto-update daily (by default, may be edited).
|
|
```sh
|
|
sudo systemctl enable podman-auto-update.timer
|
|
```
|
|
|
|
# Creating a systemd service file (older Podman versions)
|
|
|
|
Podman is easier to run in systemd than Docker due to its daemonless architechture. It comes with a handy [generate systemd command](http://docs.podman.io/en/latest/markdown/podman-generate-systemd.1.html) which can generate systemd files. Here is a [good article that goes into more detail](https://www.redhat.com/sysadmin/podman-shareable-systemd-services) as well as [this article detailing some more recent updates](https://www.redhat.com/sysadmin/improved-systemd-podman).
|
|
```sh
|
|
$ podman run -d --name vaultwarden -v /vw-data/:/data/:Z -e ROCKET_PORT=8080 -p 8080:8080 vaultwarden/server:latest
|
|
54502f309f3092d32b4c496ef3d099b270b2af7b5464e7cb4887bc16a4d38597
|
|
$ podman generate systemd --name vaultwarden
|
|
# container-vaultwarden.service
|
|
# autogenerated by Podman 1.6.2
|
|
# Tue Nov 19 15:49:15 CET 2019
|
|
|
|
[Unit]
|
|
Description=Podman container-vaultwarden.service
|
|
Documentation=man:podman-generate-systemd(1)
|
|
|
|
[Service]
|
|
Restart=on-failure
|
|
ExecStart=/usr/bin/podman start vaultwarden
|
|
ExecStop=/usr/bin/podman stop -t 10 vaultwarden
|
|
KillMode=none
|
|
Type=forking
|
|
PIDFile=/run/user/1000/overlay-containers/54502f309f3092d32b4c496ef3d099b270b2af7b5464e7cb4887bc16a4d38597/userdata/conmon.pid
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target default.target
|
|
```
|
|
|
|
You can provide a `--files` flag to tell podman to put the systemd service into a file or use ```podman generate systemd --name vaultwarden > /etc/systemd/system/container-vaultwarden.service```. With this we can enable and start the container as any normal service file.
|
|
|
|
```sh
|
|
$ systemctl enable /etc/systemd/system/container-vaultwarden.service
|
|
$ systemctl start container-vaultwarden.service
|
|
```
|
|
|
|
## New container every restart
|
|
|
|
If we want to create a new container every time the service starts we can use the `podman generate systemd --new` command to generate a service file that recreates containers
|
|
|
|
```sh
|
|
$ podman generate systemd --new --name vaultwarden
|
|
```
|
|
|
|
If you're using an older Podman, you can edit the service file to contain the following instead:
|
|
|
|
```sh
|
|
[Unit]
|
|
Description=Podman container-vaultwarden.service
|
|
|
|
[Service]
|
|
Restart=on-failure
|
|
ExecStartPre=/usr/bin/rm -f /%t/%n-pid /%t/%n-cid
|
|
ExecStart=/usr/bin/podman run --conmon-pidfile /%t/%n-pid --cidfile /%t/%n-cid --env-file=/home/spytec/Vaultwarden/vaultwarden.conf -d -p 8080:8080 -v /home/spytec/Vaultwarden/vw-data:/data/:Z vaultwarden/server:latest
|
|
ExecStop=/usr/bin/podman stop -t "15" --cidfile /%t/%n-cid
|
|
ExecStop=/usr/bin/podman rm -f --cidfile /%t/%n-cid
|
|
KillMode=none
|
|
Type=forking
|
|
PIDFile=/%t/%n-pid
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target default.target
|
|
```
|
|
|
|
Where `vaultwarden.conf` environment file can contain all the container environment values you need
|
|
|
|
```conf
|
|
ROCKET_PORT=8080
|
|
```
|
|
|
|
If you want the container to have a specific name, you might need to add `ExecStartPre=/usr/bin/podman rm -i -f vaultwarden` if the process isn't cleaned up correctly. Note that this method currently doesn't work with the `User=` options users (see https://github.com/containers/podman/issues/5572).
|
|
|
|
# Troubleshooting
|
|
|
|
## Debugging systemd service file
|
|
|
|
If the host goes down or the container crashes, the systemd service file should automatically stop the existing container and spin it up again. We can find the error through `journalctl -u container-vaultwarden -t 100`.
|
|
|
|
Most of the time the errors we see can be fixed by simply upping the timeout in Podman command in the service file.
|
|
|
|
## Full use of quadlet files for Vaultwarden and database
|
|
|
|
The application and the PostgreSQL database are containerised and placed in a pod. The application uses its own network via the Podman network functionality. Persistent volumes are used for database data and for Vaultwarden application data. Secrets used by the deployment containers are managed by the Podman secret functionality.
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
A(vaultwarden.network) --- B(vaultwarden.pod)
|
|
B --- C(vaultwarden-app.container)
|
|
B --- D(vaultwarden-db.container)
|
|
C --- G[/env_file=/etc/vaultwarden/config/]
|
|
C --- E[(vaultwarden-app.volume)]
|
|
D --- F[(vaultwarden-db.volume)]
|
|
D --- H[/env_file=/home/vaultwarden/vaultwarden/vaultwarden-db.env/]
|
|
C --- I{{podman-secret: database_url, admin_token}}
|
|
D --- J{{podman-secret: postgres_password}}
|
|
style A fill:#ffec99
|
|
style B fill:#ffc9c9
|
|
style C fill:#b2f2bb
|
|
style D fill:#b2f2bb
|
|
style E fill:#a5d8ff
|
|
style F fill:#a5d8ff
|
|
style G fill:#f08c00
|
|
style H fill:#f08c00
|
|
style I fill:#d0bfff
|
|
style J fill:#d0bfff
|
|
```
|
|
|
|
This infrastructure is defined using these quadlet files:
|
|
|
|
- vaultwarden-app.container
|
|
- vaultwarden-app.volume
|
|
- vaultwarden-db.container
|
|
- vaultwarden-db.volume
|
|
- vaultwarden.network
|
|
- vaultwarden.pod
|
|
|
|
### Definition of the Pod
|
|
|
|
Create the file `~/.config/containers/systemd/vaultwarden.pod:
|
|
|
|
```systemd
|
|
[Pod]
|
|
PodName=vaultwarden
|
|
Network=vaultwarden.network
|
|
PublishPort=8080:8080
|
|
```
|
|
|
|
### Definition of the network
|
|
|
|
|
|
Create the file `~/.config/containers/systemd/vaultwarden.network:
|
|
|
|
```systemd
|
|
[Network]
|
|
NetworkName=vaultwarden
|
|
Gateway=192.168.220.1
|
|
Subnet=192.168.220.0/24
|
|
```
|
|
|
|
### Definition of the persistent volumes
|
|
|
|
Create the file `~/.config/containers/systemd/vaultwarden-app.volume`:
|
|
|
|
```systemd
|
|
[Volume]
|
|
VolumeName=vaultwarden-app
|
|
```
|
|
|
|
and the file `~/.config/containers/systemd/vaultwarden-db.volume`:
|
|
|
|
```systemd
|
|
[Volume]
|
|
VolumeName=vaultwarden-db
|
|
```
|
|
|
|
### Definition of the containers
|
|
|
|
Create the file `~/.config/containers/systemd/vaultwarden-app.container`:
|
|
|
|
```systemd
|
|
[Container]
|
|
ContainerName=vaultwarden-app
|
|
EnvironmentFile=/etc/vaultwarden/config
|
|
HealthCmd=/healthcheck.sh
|
|
HealthInterval=120s
|
|
HealthRetries=10
|
|
HealthTimeout=45s
|
|
Image=docker.io/vaultwarden/server:1.34.3
|
|
Pod=vaultwarden.pod
|
|
Secret=database_url,type=env,target=DATABASE_URL
|
|
Secret=admin_token,type=env,target=ADMIN_TOKEN
|
|
Volume=vaultwarden-app.volume:/data
|
|
[Unit]
|
|
Requires=vaultwarden-db.service
|
|
After=vaultwarden-db.service
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
```
|
|
|
|
and the file `~/.config/containers/systemd/vaultwarden-db.container`:
|
|
|
|
```systemd
|
|
[Container]
|
|
ContainerName=vaultwarden-db
|
|
EnvironmentFile=/home/vaultwarden/vaultwarden/vaultwarden-db.env
|
|
HealthCmd=/usr/bin/pg_isready -q -d vaultwarden -U vaultwarden
|
|
HealthInterval=120s
|
|
HealthRetries=10
|
|
HealthTimeout=45s
|
|
Image=docker.io/library/postgres:17
|
|
Pod=vaultwarden.pod
|
|
Secret=postgres_password,type=env,target=POSTGRES_PASSWORD
|
|
Volume=vaultwarden-db.volume:/var/lib/postgresql/data
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
```
|
|
|
|
### Configuration
|
|
|
|
Configuration is done using the environment file `/etc/vaultwarden/config` and `~/vaultwarden/vaultwarden-db.env`.
|
|
|
|
In the `~/vaultwarden/vaultwarden-db.env` file set the vars `POSTGRES_USER` and `POSTGRES_DB`
|
|
|
|
### Secrets
|
|
|
|
You need to define the secrets `postgres_password`, `database_url` and `admin_token` :
|
|
|
|
I assume that POSTGRES_USER=vaultwarden and POSTGRES_DB=vaultwarden
|
|
|
|
```bash
|
|
openssl rand -base64 32|podman secret create postgres_password -
|
|
echo "postgres://vaultwarden:$(podman secret inspect --showsecret --format '{{.SecretData}}' postgres_password)@vaultwarden-db/vaultwarden" | tr -d '\n' | podman secret create database_url -
|
|
echo -n "MySecretPassword" | argon2 "$(openssl rand -base64 32)" -e -id -k 65540 -t 3 -p 4| tr -d '\n' | podman secret create admin_token -
|
|
```
|
|
|
|
### Deploy
|
|
|
|
```bash
|
|
systemctl --user daemon-reload
|
|
systemctl --user start vaultwarden-pod.service
|
|
``` |