[vaultwarden::db::sqlite_migrations][ERROR] Error creating database directory when using Postgres #1313

Closed
opened 2025-10-09 17:11:05 +03:00 by OVERLORD · 5 comments
Owner

Originally created by @cschmatzler on GitHub.

Subject of the issue

Using a DATABASE_URL env variable starting with postgres://, Vaultwarden still tries to run SQLite migrations and fails at https://github.com/dani-garcia/vaultwarden/blob/main/src/db/mod.rs#L291. Data directory is writeable since the keys are created successfully.

Deployment environment

Debian Bullseye with Docker version 20.10.8, build 3967b7d

  • vaultwarden version: Docker image vaultwarden/server:1.22.2

  • Install method:

docker run --rm --name vaultwarden \
                        --log-driver=none \
                        --user 1500:1500 \
                        --cap-drop=ALL \
                        --cap-add=DAC_OVERRIDE \
                        --tmpfs=/tmp:rw,noexec,nosuid,size=100m \
                        --network={redacted} \
                        --env-file=/{redacted}/vaultwarden/env-vaultwarden \
                        --mount type=bind,src=/{redacted}/vaultwarden/data,dst=/data \
                        --mount type=bind,src=/etc/passwd,dst=/etc/passwd,ro \
                        --mount type=bind,src=/etc/timezone,dst=/etc/timezone,ro \
                        --mount type=bind,src=/etc/localtime,dst=/etc/localtime,ro \
                        vaultwarden/server:1.22.2
  • MySQL/MariaDB or PostgreSQL version: postgres:13.3

  • Other relevant details:

> ls -l data
total 12
drwxr-xr-x 2 1500 1500 4096 Aug 16 20:44 icon_cache
-rw-r--r-- 1 1500 1500 1675 Aug 16 20:44 rsa_key.pem
-rw-r--r-- 1 1500 1500 451 Aug 16 20:44 rsa_key.pub.pem

env-vaultwarden:

ROCKET_PORT=8080

DATABASE_URL="postgresql://{redacted}:{redacted}@postgres/vaultwarden"

Running it under root uid works.

Steps to reproduce

Create the env file, a postgres database, data dir with correct owner and run the above command to launch the docker image.

Expected behaviour

SQLite migrations should be skipped and container should launch.

Actual behaviour

Container stops at SQLite migrations failing

Troubleshooting data

[2021-08-16 20:43:49.406][vaultwarden][INFO] Private key created correctly.
[2021-08-16 20:43:49.407][vaultwarden][INFO] Public key created correctly.
[2021-08-16 20:43:49.407][vaultwarden::db::sqlite_migrations][ERROR] Error creating database directory
Originally created by @cschmatzler on GitHub. ### Subject of the issue Using a `DATABASE_URL` env variable starting with `postgres://`, Vaultwarden still tries to run SQLite migrations and fails at https://github.com/dani-garcia/vaultwarden/blob/main/src/db/mod.rs#L291. Data directory is writeable since the keys are created successfully. ### Deployment environment Debian Bullseye with Docker `version 20.10.8, build 3967b7d` * vaultwarden version: Docker image `vaultwarden/server:1.22.2` * Install method: ``` docker run --rm --name vaultwarden \ --log-driver=none \ --user 1500:1500 \ --cap-drop=ALL \ --cap-add=DAC_OVERRIDE \ --tmpfs=/tmp:rw,noexec,nosuid,size=100m \ --network={redacted} \ --env-file=/{redacted}/vaultwarden/env-vaultwarden \ --mount type=bind,src=/{redacted}/vaultwarden/data,dst=/data \ --mount type=bind,src=/etc/passwd,dst=/etc/passwd,ro \ --mount type=bind,src=/etc/timezone,dst=/etc/timezone,ro \ --mount type=bind,src=/etc/localtime,dst=/etc/localtime,ro \ vaultwarden/server:1.22.2 ``` * MySQL/MariaDB or PostgreSQL version: `postgres:13.3` * Other relevant details: ``` > ls -l data total 12 drwxr-xr-x 2 1500 1500 4096 Aug 16 20:44 icon_cache -rw-r--r-- 1 1500 1500 1675 Aug 16 20:44 rsa_key.pem -rw-r--r-- 1 1500 1500 451 Aug 16 20:44 rsa_key.pub.pem ``` env-vaultwarden: ``` ROCKET_PORT=8080 DATABASE_URL="postgresql://{redacted}:{redacted}@postgres/vaultwarden" ``` Running it under root uid works. ### Steps to reproduce Create the env file, a postgres database, data dir with correct owner and run the above command to launch the docker image. ### Expected behaviour SQLite migrations should be skipped and container should launch. ### Actual behaviour Container stops at SQLite migrations failing ### Troubleshooting data ``` [2021-08-16 20:43:49.406][vaultwarden][INFO] Private key created correctly. [2021-08-16 20:43:49.407][vaultwarden][INFO] Public key created correctly. [2021-08-16 20:43:49.407][vaultwarden::db::sqlite_migrations][ERROR] Error creating database directory ```
Author
Owner

@cschmatzler commented on GitHub:

Found the issue.
DATABASE_URL may not be quoted, neither in single nor in double quotes. This is in contrast to the wiki entry here, which gives

To run the binary or container ensure the DATABASE_URL environment variable is set (i.e. DATABASE_URL='postgresql://<user>:<password>@postgresql/bitwarden')
as an example.

The server should probably allow quoted environment variables? When passing a quoted variable as -e DATABASE_URL='...', Docker automatically unquotes it, but as --env-file, it stays quoted.

@cschmatzler commented on GitHub: Found the issue. `DATABASE_URL` may not be quoted, neither in single nor in double quotes. This is in contrast to the wiki entry [here](https://github.com/dani-garcia/vaultwarden/wiki/Using-the-PostgreSQL-Backend), which gives > To run the binary or container ensure the `DATABASE_URL` environment variable is set (i.e. `DATABASE_URL='postgresql://<user>:<password>@postgresql/bitwarden'`) as an example. The server should probably allow quoted environment variables? When passing a quoted variable as `-e DATABASE_URL='...'`, Docker automatically unquotes it, but as `--env-file`, it stays quoted.
Author
Owner

@jjlin commented on GitHub:

It's generally not the application's job to do more unquoting on environment variables, as the user might want an env var to have a quoted value. Unfortunately, there is not really any standard for env file syntax, so different tools can handle it differently.

I've updated https://github.com/dani-garcia/vaultwarden/wiki/Configuration-overview#loading-environment-variables-from-a-file to mention this pitfall with --env-file. That wiki page covers other ways to load env files as well.

@jjlin commented on GitHub: It's generally not the application's job to do more unquoting on environment variables, as the user might want an env var to have a quoted value. Unfortunately, there is not really any standard for env file syntax, so different tools can handle it differently. I've updated https://github.com/dani-garcia/vaultwarden/wiki/Configuration-overview#loading-environment-variables-from-a-file to mention this pitfall with `--env-file`. That wiki page covers other ways to load env files as well.
Author
Owner

@cschmatzler commented on GitHub:

Let's minimize a little:

docker run --rm --name vaultwarden --user 1500:1500 --env-file=/{redacted}/vaultwarden/env-vaultwarden --mount type=bind,src=/{redacted}/vaultwarden/data,dst=/data vaultwarden/server:1.22.2

results in the same.
Omitting the user flag and running it as root does start the container and logs Running migration a bunch, and brings up the web vault... but does not write anything to the Postgres database and loses all data after a container restart, so it's writing somewhere in the ephemeral file system.

Which is very interesting, because it also logs

[2021-08-16 22:53:32.746][vaultwarden][INFO] Private key created correctly.
[2021-08-16 22:53:32.746][vaultwarden][INFO] Public key created correctly.

and if it was defaulting to sqlite...

database_url:           String, false,  auto,   |c| format!("{}/{}", c.data_folder, "db.sqlite3");

https://github.com/dani-garcia/vaultwarden/blob/main/src/config.rs#L302

rsa_key_filename:       String, false,  auto,   |c| format!("{}/{}", c.data_folder, "rsa_key");

https://github.com/dani-garcia/vaultwarden/blob/main/src/config.rs#L314

are both using c.data_folder, which has write permissions even for my 1500:1500 user, because the rsa_key path can be created and does persist between container restarts.

@cschmatzler commented on GitHub: Let's minimize a little: ``` docker run --rm --name vaultwarden --user 1500:1500 --env-file=/{redacted}/vaultwarden/env-vaultwarden --mount type=bind,src=/{redacted}/vaultwarden/data,dst=/data vaultwarden/server:1.22.2 ``` results in the same. Omitting the `user` flag and running it as root *does* start the container and logs `Running migration` a bunch, and brings up the web vault... but does not write anything to the Postgres database and loses all data after a container restart, so it's writing somewhere in the ephemeral file system. Which is very interesting, because it also logs ``` [2021-08-16 22:53:32.746][vaultwarden][INFO] Private key created correctly. [2021-08-16 22:53:32.746][vaultwarden][INFO] Public key created correctly. ``` and if it was defaulting to sqlite... ``` database_url: String, false, auto, |c| format!("{}/{}", c.data_folder, "db.sqlite3"); ``` https://github.com/dani-garcia/vaultwarden/blob/main/src/config.rs#L302 ``` rsa_key_filename: String, false, auto, |c| format!("{}/{}", c.data_folder, "rsa_key"); ``` https://github.com/dani-garcia/vaultwarden/blob/main/src/config.rs#L314 are both using `c.data_folder`, which has write permissions even for my `1500:1500` user, because the `rsa_key` path *can* be created and *does* persist between container restarts.
Author
Owner

@BlackDex commented on GitHub:

I'm having no issues using postgresql.
Are you sure the correct env is loaded? Since sqlite is default, i think those env's you try to load arn't working.
Try to add LOG_LEVEL=debug or trace and see if the output changes.

@BlackDex commented on GitHub: I'm having no issues using postgresql. Are you sure the correct env is loaded? Since sqlite is default, i think those env's you try to load arn't working. Try to add LOG_LEVEL=debug or trace and see if the output changes.
Author
Owner

@cschmatzler commented on GitHub:

Running

docker run --rm --name vaultwarden \
                        --log-driver=none \
                        --user 1500:1500 \
                        --cap-drop=ALL \
                        --cap-add=DAC_OVERRIDE \
                        --tmpfs=/tmp:rw,noexec,nosuid,size=100m \
                        --network={redacted} \
                        --env-file=/{redacted}/vaultwarden/env-vaultwarden \
                        --mount type=bind,src=/{redacted}/vaultwarden/data,dst=/data \
                        --mount type=bind,src=/etc/passwd,dst=/etc/passwd,ro \
                        --mount type=bind,src=/etc/timezone,dst=/etc/timezone,ro \
                        --mount type=bind,src=/etc/localtime,dst=/etc/localtime,ro \
                        vaultwarden/server:1.22.2 \
                        printenv
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=ad541f43b05b
ROCKET_PORT=8080
LOG_LEVEL=trace
DATABASE_URL="postgresql://{redacted}:{redacted}@postgres/vaultwarden"
ROCKET_ENV=staging
ROCKET_WORKERS=10
HOME=/{redacted}

Passing the DATABASE_URL environment variable to psql connects to the database successfully.

> psql "postgresql://{redacted}:{redacted}@postgres/vaultwarden"

psql (13.3 (Debian 13.3-1.pgdg100+1))
Type "help" for help.

vaultwarden=# 
@cschmatzler commented on GitHub: Running ``` docker run --rm --name vaultwarden \ --log-driver=none \ --user 1500:1500 \ --cap-drop=ALL \ --cap-add=DAC_OVERRIDE \ --tmpfs=/tmp:rw,noexec,nosuid,size=100m \ --network={redacted} \ --env-file=/{redacted}/vaultwarden/env-vaultwarden \ --mount type=bind,src=/{redacted}/vaultwarden/data,dst=/data \ --mount type=bind,src=/etc/passwd,dst=/etc/passwd,ro \ --mount type=bind,src=/etc/timezone,dst=/etc/timezone,ro \ --mount type=bind,src=/etc/localtime,dst=/etc/localtime,ro \ vaultwarden/server:1.22.2 \ printenv ``` ``` PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=ad541f43b05b ROCKET_PORT=8080 LOG_LEVEL=trace DATABASE_URL="postgresql://{redacted}:{redacted}@postgres/vaultwarden" ROCKET_ENV=staging ROCKET_WORKERS=10 HOME=/{redacted} ``` Passing the `DATABASE_URL` environment variable to `psql` connects to the database successfully. ``` > psql "postgresql://{redacted}:{redacted}@postgres/vaultwarden" psql (13.3 (Debian 13.3-1.pgdg100+1)) Type "help" for help. vaultwarden=# ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/vaultwarden#1313