Postgres

Postgres is the default OwnStack database. Provisioning a service creates a running container on the stack and links it to an app, setting DATABASE_URL automatically. Versions 14 through 18 are supported; 17 is the default.

$ ownstack db create --app=<app> [--version=17]

This runs (on the stack):

  1. dokku postgres:create postgres-<app> --image-version 17
  2. dokku postgres:link postgres-<app> <app>
  3. Refreshes DATABASE_URL on the app config from the link.
  4. Restarts the app so the env change takes effect.

The DATABASE_URL shape

postgresql://postgres:<password>@dokku-postgres-<service>:5432/<dbname>

Notes:

  • The user is always postgres by default.
  • The host is dokku's internal docker DNS alias — only routable from inside the stack's docker network.
  • The dbname is the same as the service (sanitized).
  • The password is randomly generated by dokku at postgres:create time.

Connect from outside the stack

Use ownstack ssh app to drop into the app's container, where $DATABASE_URL resolves; or use dokku postgres:connect from the stack:

$ ssh dokku@<stack-ip> postgres:connect postgres-<app>
psql (17.x)
Type "help" for help.

postgres-<app>=#

To expose Postgres on a public port (not recommended for prod), use postgres:expose on the stack — but firewall it carefully.

Multiple databases per app

You can link more than one Postgres service to a single app:

$ ssh dokku@<stack-ip> postgres:create reporting-db --image-version 17
$ ssh dokku@<stack-ip> postgres:link reporting-db <app> --alias REPORTING_DATABASE

The --alias creates a REPORTING_DATABASE_URL env var alongside the primary DATABASE_URL. Useful for read-replicas, analytics warehouses, multi-tenant designs.

Upgrades

Postgres major-version upgrades are not in-place. The dokku-postgres flow is:

  1. Take a dump from the running service: dokku postgres:export <old-svc> > data.dump
  2. Create a new service on the new version: dokku postgres:create <new-svc> --image-version 18
  3. Import the dump: dokku postgres:import <new-svc> < data.dump
  4. Unlink the old service, link the new: dokku postgres:unlink <old-svc> <app> && dokku postgres:link <new-svc> <app>
  5. Verify, then destroy the old service: dokku postgres:destroy <old-svc>

Operations cheat-sheet

TaskCommand
Open psqlssh dokku@<stack-ip> postgres:connect <svc>
Show service infossh dokku@<stack-ip> postgres:info <svc>
List databasesssh dokku@<stack-ip> postgres:list
Stream a dump downownstack db dump --app=<app>
Restore from URLownstack db restore --app=<app> --url=...
Re-link service / refresh DATABASE_URLownstack db repair --app=<app>
Destroy service (data loss!)ssh dokku@<stack-ip> postgres:destroy <svc>