Skip to content
Levelrail

Add a Postgres database to an app on Levelrail

A database on Levelrail is run like an app: its own data volume, generated credentials and its own lifecycle. This guide creates one, hands its connection string to an app, and puts a backup schedule on it that checks every backup it takes.

  • Beginner
  • 3 min read
On this page

Before you start

  • A Levelrail control plane with the CLI signed in, and an app already deployed on it. The examples call it web.
  • For backups: an S3 compatible bucket and an access key, and a master key configured on the control plane. Backup routes answer 501 without one.

Create it and connect it

  1. Step 1Create the database

    Name it, pick the engine and the major version. Without --node-id, it is placed on the least loaded node, or on the only node when there is one. The call returns at once and provisioning carries on in the background.

    bash
    levelrail-cli databases create --name main --engine postgres --version 16
  2. Step 2Wait until it is ready

    Ready means the engine port accepts connections. The API never returns the database password, so connection details show the host, the port and a masked connection string.

    bash
    levelrail-cli databases status main
    levelrail-cli databases get main
  3. Step 3Connect it to the app

    apps connect hands the database's connection string to the app as an environment variable, resolved from the encrypted store and never logged. Without --env-var the name is derived from the database, here MAIN_DATABASE_URL.

    bash
    levelrail-cli apps connect web main --env-var DATABASE_URL
  4. Step 4Restart the app to pick it up

    The value is injected when the app's container is created, so restart the app once. Do the same after a credential rotation.

    bash
    levelrail-cli apps restart web
  5. Step 5Check that the app can reach it

    Each connection carries a badge: same node, cross node over the mesh, or cross node with the mesh off. The last one will not reach the database, so move one of them or turn on mesh networking.

    bash
    levelrail-cli apps connections list web

Back it up

  1. Step 6Add a backup target

    A backup target is a bucket whose key is stored encrypted, like any other secret. --provider is aws, r2 or custom, and --endpoint is required for the last two. Note the target id from the list.

    bash
    levelrail-cli backup-targets create --name offsite --provider aws --region us-east-1 \
      --bucket acme-db-backups \
      --access-key-id "$AWS_ACCESS_KEY_ID" --secret-access-key "$AWS_SECRET_ACCESS_KEY"
    levelrail-cli backup-targets list
  2. Step 7Schedule nightly backups

    A standard five field cron expression, checked when you set it. --retain keeps the last N successful backups. Each scheduled backup that succeeds is verified again right after it lands.

    bash
    levelrail-cli backups schedule set main --target <target-id> --cron "0 3 * * *" --retain 14
  3. Step 8Take one now and verify it

    A manual backup starts in the background, so list the backups for its status. Manual backups are not verified on their own, so ask for it.

    bash
    levelrail-cli backups trigger main --target <target-id>
    levelrail-cli backups list main
    levelrail-cli backups verify main --backup <backup-id>

Prove the restore, not just the file

Verification re-downloads the object and checks its checksum, its size and the trailer pg_dump writes last, so a truncated dump fails. It proves the file is intact, not that it restores cleanly. Restoring into a new scratch database is the proof, and it leaves the live one untouched. The restore drill covers what to check once it is up.

bash
levelrail-cli backups restore-as-new main --backup <backup-id> --new-name main-drill
levelrail-cli databases query main-drill --sql "select count(*) from users"
Questions

Frequently asked questions

Can I run pgvector, TimescaleDB or PostGIS?

Yes. They are Postgres flavors chosen through the version string, for example 17-pgvector or 17-postgis. The engine stays postgres, so backups and restores work the same. Create the extension inside the database once it starts.

Can one app use more than one database?

Yes. Connect each database with apps connect. Every connection lands in its own environment variable, and there is no cap on how many an app has.

What happens to the data when I delete the database?

Delete stops and removes the database but keeps its data volume. Deleting a database that apps still use needs the force flag.

Does a missed scheduled backup run later?

No. If the control plane is down when a scheduled backup should fire, that run is missed and not replayed on restart.

Keep going
Next steps

Take it further with Levelrail

The product page covers what it does, how to install it and where the docs live.