hakobuDocs
Menu

Databases

View as Markdown

A database is a PostgreSQL database with a role of its own, in one shared PostgreSQL server on the project's server. Only its project's apps reach it.

New → Database on the project's page. Link it to an app in the app's Settings → Resources: the app gets DATABASE_URL, POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DB, POSTGRES_USER and POSTGRES_PASSWORD on its next deploy. The password is generated.

Backups

With backups on (one click in Settings), every database is backed up daily to a private R2 bucket hakobu creates in your Cloudflare account. Each backup is:

  • sealed by the server the database runs on, with that server's own key, which the panel never has;
  • checked: its SHA-256 is kept and verified before a restore, and it's restored into a scratch database right after upload, counting its tables;
  • locked for 7 days by the bucket, even against a bug in hakobu;
  • rotated: the last 7 are kept, and one a week for a month.

The database's page lists its backups, makes one now, checks one again and restores one. See Backups and recovery for the whole picture.

Rollback with data

Before each deploy of an app, its database is snapshotted on the server. Rollback with data puts the snapshot back with the build before, so a migration that went wrong is undone. Rows written since are lost.

Moving a database in

A database from another host comes in as a backup of a hakobu database. With backups on, on the panel's server:

ssh old-host 'pg_dump -Fc -U postgres mydb' | (cd /opt/hakobu && sudo -u hakobu ./hakobu database import shop/mydb -)

naming the database by its project, shop; when several users have a project of that name, --user <GitHub login> says whose. The running panel takes the dump and seals it on the database's server, so hakobu must be running and that server connected.

Only pg_dump's custom format (-Fc) is taken. On the database's page, Check restores the dump into a scratch database and counts its tables; Restore replaces the database's data with it (objects become the database role's, grants are dropped). A restore that fails changes nothing, so a trial move and the real one later are the same two steps.