DATABASE_URL
Everything regarding the DATABASE_URL environment variable
The DATABASE_URL environment variable is a standardized way to specify database connection details in Password Pusher. It follows the RFC 3986 URI standard and is commonly used across various deployment environments and hosting platforms.
Overview
Password Pusher supports two database backends:
- SQLite3 (default) - File-based database with persistent storage via Docker volumes, perfect for single-server deployments
- PostgreSQL - Robust relational database for distributed or high-availability setups
The DATABASE_URL contains a URL string with all information needed to connect to your database, including the database type, host, port, database name, and authentication credentials.
Important: Remember to replace the placeholders in these examples (e.g., username, password, hostname, port, database_name) with your actual credentials and database information.
Note: Additional connection options can be provided by adding query parameters to the URL: ?option1=value1&option2=value2
SQLite3
SQLite3 is the default database backend. If DATABASE_URL is not specified, Password Pusher automatically uses SQLite3 under /opt/PasswordPusher/storage. When using the provided docker-compose.yml, that storage directory is a persistent volume and survives container restarts and upgrades.
Format
For SQLite3, the DATABASE_URL format is:
sqlite3:///path/to/database/file.sqlite3
or the shorter format:
sqlite3:path/to/database/file.sqlite3
sqlite3://orsqlite3:is the protocol- The path can be absolute or relative to the application root
- Use three slashes (
///) for absolute paths
Examples
Absolute path (recommended for Docker):
sqlite3:///opt/PasswordPusher/storage/db/production.sqlite3
Relative path (same default location):
sqlite3:storage/db/production.sqlite3
Default (when DATABASE_URL is not set):
The container entrypoint defaults to sqlite3:storage/db/production.sqlite3. Older installs that still have db/db.sqlite3 keep that deprecated path until you move the file into storage/db/.
In most Docker setups you can omit DATABASE_URL entirely and mount persistent storage as shown below.
Persistence
Mount /opt/PasswordPusher/storage. That directory holds the SQLite database (storage/db/production.sqlite3) and uploaded files.
Using Docker volumes (default in docker-compose.yml):
volumes:
- pwpush-storage:/opt/PasswordPusher/storage
volumes:
pwpush-storage:
Using bind mounts:
volumes:
- /host/path/to/storage:/opt/PasswordPusher/storage
Do not mount over /opt/PasswordPusher/db.
That path contains application migration source files (db/migrate/), not just the database. Overlaying a host directory or named volume on /opt/PasswordPusher/db hides those files from Rails. Upgrades then skip migrations (you may see ****** NO FILE ****** in db:migrate:status), and the app can crash looking for new tables.
| Mount | Result |
|---|---|
/opt/PasswordPusher/storage |
Correct — persists DB + uploads, migrations stay available |
/opt/PasswordPusher/db |
Incorrect — hides db/migrate/ and breaks upgrades |
Only the .sqlite3 file (legacy) |
Works, but prefer migrating to storage/ |
Legacy installs that already store SQLite under /opt/PasswordPusher/db:
- Back up the database file
- Move it to
storage/db/production.sqlite3(include-wal/-shmfiles if present) - Change the volume mount to
/opt/PasswordPusher/storage - Remove a custom
DATABASE_URLpointing at/opt/PasswordPusher/db/..., or update it to the storage path - Restart — pending migrations apply automatically
If you must keep a database file under /opt/PasswordPusher/db temporarily, bind-mount only the SQLite file, never the entire db/ directory:
volumes:
- ./data/production.sqlite3:/opt/PasswordPusher/db/production.sqlite3
Prefer migrating to /opt/PasswordPusher/storage when you can.
Note: Without a volume, the database lives only in the container filesystem and is lost when the container is removed. Always use a volume for production.
When to Use SQLite3
SQLite3 is ideal for:
- Single-server deployments
- Development and testing environments
- Small to medium-sized installations
- Scenarios where simplicity is preferred over scalability
For production deployments requiring high availability, multiple servers, or advanced features, consider PostgreSQL instead.
PostgreSQL
PostgreSQL is a robust, production-ready database backend suitable for distributed deployments, high-availability setups, and environments requiring advanced database features.
Format
For PostgreSQL, the DATABASE_URL follows this format:
postgres://username:password@hostname:port/database_name
Components:
postgres://- The protocol identifierusername:password- Your PostgreSQL authentication credentialshostname- The host where your PostgreSQL server is running (can be a hostname, IP address, or Docker service name)port- The port number (default is 5432)database_name- The name of your PostgreSQL database
Examples
Local PostgreSQL server:
postgres://myuser:mypassword@localhost:5432/pwpush_db
Remote PostgreSQL server:
postgres://myuser:mypassword@db.example.com:5432/pwpush_db
Docker Compose (using service name):
postgres://pwpush_user:pwpush_passwd@postgres:5432/pwpush_db
With SSL connection:
postgres://myuser:mypassword@db.example.com:5432/pwpush_db?sslmode=require
Important Notes
Hostname Restrictions: Hostname values with underscores (_) are not supported due to RFC 3986 URI standards. Use hyphens (-) instead. See issue #1602 for details.
Special Characters in Passwords: If your password contains special characters that conflict with URI encoding (such as %, ^, #, :, etc.), you may need to URL-encode them. See the Valid Characters section below.
When to Use PostgreSQL
PostgreSQL is recommended for:
- Production deployments requiring high availability
- Multi-server or distributed setups
- Environments with high traffic or large datasets
- Scenarios requiring database replication or backups
- When using the separate worker container (
pglombardo/pwpush-worker)
Configuration Examples
Docker Compose
Using SQLite3 with persistent volume:
services:
pwpush:
image: docker.io/pglombardo/pwpush:stable
environment:
# SQLite3 is the default. Omit DATABASE_URL, or set:
# DATABASE_URL: sqlite3:///opt/PasswordPusher/storage/db/production.sqlite3
volumes:
- pwpush-storage:/opt/PasswordPusher/storage
volumes:
pwpush-storage:
Using PostgreSQL:
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: pwpush_user
POSTGRES_PASSWORD: pwpush_passwd
POSTGRES_DB: pwpush_db
volumes:
- postgres-data:/var/lib/postgresql/data
pwpush:
image: docker.io/pglombardo/pwpush:stable
depends_on:
- postgres
environment:
DATABASE_URL: postgres://pwpush_user:pwpush_passwd@postgres:5432/pwpush_db
volumes:
postgres-data:
Environment Variables
Set DATABASE_URL as an environment variable:
export DATABASE_URL="postgres://myuser:mypassword@localhost:5432/pwpush_db"
Or in a .env file:
DATABASE_URL=postgres://myuser:mypassword@localhost:5432/pwpush_db
Valid Characters and URL Encoding
The DATABASE_URL follows the RFC 3986 URI standard, which restricts certain characters that can be used in URI components.
Restricted Characters
The following characters are not allowed in usernames, passwords, hostnames, or database names without URL encoding:
% ^ # _ :
Common Issues and Solutions
Underscores in hostnames: Hostnames with underscores (_) are not supported. Use hyphens (-) instead.
Example:
- ❌
db_server.example.com(not supported) - ✅
db-server.example.com(supported)
Special characters in passwords: If your password contains special characters like %, ^, #, :, you need to URL-encode them:
| Character | URL-Encoded |
|---|---|
% |
%25 |
^ |
%5E |
# |
%23 |
: |
%3A |
Example:
- Original password:
my#pass:word - URL-encoded:
my%23pass%3Aword - Full DATABASE_URL:
postgres://user:my%23pass%3Aword@localhost:5432/db
Tip: Use this regex tool to test your DATABASE_URL string for RFC 3986 compliance.
Note: This is an internet standard (RFC 3986), not a limitation introduced by Password Pusher. Most modern applications and deployment platforms follow this standard.
Troubleshooting
Common Issues
Database connection fails:
- Verify the database server is running and accessible
- Check that the hostname, port, username, password, and database name are correct
- Ensure network connectivity between the application and database server
- For Docker Compose, use the service name as the hostname
“Hostname with underscores not supported” error:
- Replace underscores (
_) with hyphens (-) in hostnames - This is a limitation of the URI standard, not Password Pusher
Password with special characters fails:
- URL-encode special characters in your password
- Consider using a password without special characters if possible
- Use environment files or Docker secrets instead of command-line arguments
SQLite database not persisting:
- Verify that volumes are properly configured in your
docker-compose.ymlordocker runcommand - Confirm the mount target is
/opt/PasswordPusher/storage(not/opt/PasswordPusher/db) - Check volume mount permissions
- Ensure the path exists and is writable
- For Docker Compose, verify the volume is defined in both the service and the top-level
volumessection
Migrations not running / missing tables after upgrade (for example notify_by_emails):
- Confirm you are not mounting a volume over
/opt/PasswordPusher/db - Inside the container,
ls /opt/PasswordPusher/db/migrateshould list migration files from the image db:migrate:statusshowing****** NO FILE ******usually means the mount hid those files- Fix the volume to
/opt/PasswordPusher/storage, restart, and let the entrypoint run migrations
See Also
- Installation Guide - Learn how to set up Password Pusher
- Upgrades & Backups - Upgrade process and migration troubleshooting
- Docker Environment File - Using environment files for configuration
- Persist Ephemeral Database - Making SQLite databases temporary
- Configuration Strategies - Different ways to configure Password Pusher