Berth

Postgres and Redis

berth pg:create db                 # Postgres 17 in its own VM
berth pg:link db myapp             # a login for myapp, DATABASE_URL set, redeployed

The app now has DATABASE_URL=postgres://myapp:…@192.168.66.1:6001/db. Each linked app gets its own login, but they share the tables, so several apps can use one database.

berth pg:psql db                                # psql
berth pg:psql db -c "select count(*) from users"
berth pg:backup db                              # pg_dump → ~/.berth/backups/pg/db/<time>.dump
berth pg:restore db ~/.berth/backups/pg/db/20261025-030000.dump
berth pg:expose db 15432                        # for TablePlus and friends, at 127.0.0.1:15432
berth pg:expose db off
berth pg:upgrade db --to 18                     # dump, new Postgres, restore, relink
berth pg:unlink db myapp                        # revoke the login, remove DATABASE_URL
berth pg:destroy db                             # refuses while apps are linked (--force if you mean it)
berth pg:list

Every Postgres database is dumped every night at 03:00, and the last 14 dumps sit in ~/.berth/backups/pg/ where Time Machine will find them. The dumps are the real backup: the live files are inside a container volume, and copying a running database's files isn't reliable anyway. pg:upgrade keeps the old data volume until you delete it, just in case.

Link a second database to the same app and its variable is named after it (PG_ANALYTICS_URL); pick your own name with --as.

Redis works the same way, with REDIS_URL and append-only persistence. Each linked app gets its own Redis user, so unlinking one doesn't disturb the others:

berth redis:create cache
berth redis:link cache myapp
berth redis:cli cache GET somekey
berth redis:backup cache
berth redis:restore cache ~/.berth/backups/redis/cache/<time>.rdb

pg:create and redis:create take --memory (512M and 256M by default) and --image (--image postgres:16, for example).

Edit this page on GitHub (it's a section of the README)