This feature request comes with a working solution. I’m just not sure where to implement it in the Vaultwarden repo so i can’t create create a pull request proposing an implementation myself.
Feature Request
Support passing a raw (i.e. non-url encoded) database password as a secret to the Vaultwarden docker container.
Background
When using MariaDB, MySQL, or PostgreSQL as the database backend for Vaultwarden, you must specify DATABASE_URL
as a environmental variable. Additionally, the password for these must be URL Encoded. It is assumed that you will construct this variable outside of the container and pass it as a variable, exposing it to all the world.
However, it is possible to make the docker container construct it using just 15 lines of code instead. You won’t even need to add any packages.
Barebones Example:
The set-env-from-secrets.sh
script is used to read docker secret db_password
, url encode it, and use it to construct and set the DATABASE_URL
environmental variable. To ensure it is run before vaultwarden, it is copied to /etc/vaultwarden.d/set-env-from-secrets.sh
in the vaultwarden container.
In addition, the set-env-from-secrets.sh
file also sets the ADMIN_TOKEN
variable, so you can check the admin diagnostics page to verify PostgresSQL is being used as the backend.
This example assumes the following directory layout:
docker-compose.yaml
./config/set-env-from-secrets.sh
./secrets/admin_token
./secrets/db_password
File Contents
docker-compose.yaml
version: '3'
services:
postgres:
image: docker.io/library/postgres:14
restart: always
environment:
POSTGRES_DB: 'vaultwarden'
POSTGRES_USER: 'warden'
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
volumes:
- postgres_vol:/var/lib/postgresql/data:rw
expose:
- 5432
vaultwarden:
image: docker.io/vaultwarden/server:latest
depends_on:
- postgres
restart: always
environment:
URL_TEMPLATE: 'postgres://warden:%s@postgres/vaultwarden'
configs:
- source: set_vaultwarden_env
target: /etc/vaultwarden.d/set-env-from-secrets.sh
secrets:
- admin_token
- db_password
volumes:
- vaultwarden_vol:/data/:rw
ports:
- "8080:80"
secrets:
admin_token:
file: ./secrets/admin_token
db_password:
file: ./secrets/db_password
configs:
set_vaultwarden_env:
file: ./config/vaultwarden/set-env-from-secrets.sh
volumes:
postgres_vol:
vaultwarden_vol:
set-env-from-secrets.sh
#!/usr/bin/env sh
url_encode () {
string=$*
while [ -n "$string" ]; do
tail=${string#?}
head=${string%$tail}
case $head in
[-._~0-9A-Za-z]) printf %c "$head";;
*) printf %%%02x "'$head"
esac
string=$tail
done
echo
}
export DATABASE_URL=$(printf "$URL_TEMPLATE" "$(url_encode $(cat /run/secrets/db_password))")
export ADMIN_TOKEN=$(cat /run/secrets/admin_token)
The admin_token
and db_password
files contain password strings. Set them yourself or generate them via:
gpg --dry-run --gen-random --armor 1 64 > ./secrets/admin_token 2> /dev/null
gpg --dry-run --gen-random --armor 1 64 > ./secrets/db_password 2> /dev/null