# Allow Use of Docker Secrets and Automagically URL Encode DB Passwords

**URL:** <https://vaultwarden.discourse.group/t/allow-use-of-docker-secrets-and-automagically-url-encode-db-passwords/1768>\
**Category:** Feature Requests\
**Created:** [July 20, 2022, 6:14pm UTC](https://vaultwarden.discourse.group/t/allow-use-of-docker-secrets-and-automagically-url-encode-db-passwords/1768 "2022-07-20T18:14:35Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![BinaryWizard904](https://avatars.discourse-cdn.com/v4/letter/b/b487fb/32.png) [@BinaryWizard904](https://vaultwarden.discourse.group/u/BinaryWizard904)\
**Post date:** [July 20, 2022, 6:14pm UTC](https://vaultwarden.discourse.group/t/allow-use-of-docker-secrets-and-automagically-url-encode-db-passwords/1768/1 "2022-07-20T18:14:35Z")

</div>

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:

```nohighlight
docker-compose.yaml
./config/set-env-from-secrets.sh
./secrets/admin_token
./secrets/db_password

```

File Contents

> **docker-compose.yaml**
>
> ```auto
> 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**
>
> ```auto
> #!/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:

```auto
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

```

---

<div class="post-metadata">

**Author:** ![BlackDex](https://yyz2.discourse-cdn.com/free1/user_avatar/vaultwarden.discourse.group/blackdex/32/8_2.png) [@BlackDex](https://vaultwarden.discourse.group/u/BlackDex)\
**Post date:** [July 20, 2022, 6:44pm UTC](https://vaultwarden.discourse.group/t/allow-use-of-docker-secrets-and-automagically-url-encode-db-passwords/1768/2 "2022-07-20T18:44:50Z")

</div>

I’m not sure if we want this as part of the codebase it self.  
But a mention of this somewhere in the wiki probably somewhere regarding docker-compose would be nice i think.

---

<div class="post-metadata">

**Author:** ![harningt](https://yyz2.discourse-cdn.com/free1/user_avatar/vaultwarden.discourse.group/harningt/32/793_2.png) [@harningt](https://vaultwarden.discourse.group/u/harningt)\
**Post date:** [October 17, 2022, 9:30pm UTC](https://vaultwarden.discourse.group/t/allow-use-of-docker-secrets-and-automagically-url-encode-db-passwords/1768/3 "2022-10-17T21:30:55Z")

</div>

A clever workaround (at least for postgres) is to use libpq’s environment to pass the credentials out of band from DB url. This avoids the encoding issue and prevents the information from being presented on the admin page.  
If/when diesel stops using libpq - then this might break.
