Skip to Content
Framework GuidesLocal development

Local development

A project’s databases are private to the cluster. They have no public address, and the platform only opens the network path from the apps connected to them — which is what keeps them safe, and also what stops the app on your laptop from reaching them.

There are two answers, and which one you need depends on whether your app has to talk to the database or merely be configured like the deployed one.

Values only: ghayma env pull

If you run against a local Postgres, Mongo or Valkey and just want the same variables the deployed app receives — the ones you set plus every value derived from the site’s connections — pull them:

ghayma env pull

That writes .env.local with the effective environment. The database hosts in it are in-cluster addresses, so they answer nothing from here; everything else (storage credentials, the auth app’s variables, the managed platform key) works from your machine as it does in the cluster.

The real databases: ghayma connect --local

If the app must actually reach the project’s data — a migration to run, a query to reproduce, a bug that only shows up against real rows — open a tunnel:

# Terminal 1: leave this running ghayma connect --local # 🔌 Tunnel open for 'main' — its databases answer on this machine: # my-postgres (postgres) → 127.0.0.1:15432 # Wrote 12 variables to .env.local (hosts point at the listeners; restore with: ghayma env pull) # Leave this running; Ctrl-C closes the tunnel.
# Terminal 2: the app reads .env.local and connects to 127.0.0.1:15432 npm run dev

A Valkey answers on 127.0.0.1:16379 with CLI v0.13.0 or later (see Valkey).

Press Ctrl-C in the first terminal when you are done. The listeners close, the session is given back, and the addresses in .env.local stop answering — run ghayma env pull to put the cluster addresses back in the file.

The tunnel needs the project admin role and lasts 8 hours. Full reference, including the file-safety rules and the options: ghayma connect --local.

Why not just add a named principal

A named principal gives the database a public address of its own, and for an afternoon of local work it is more than you need. The address answers from anywhere for as long as the principal is in force, so the credential has to be stored somewhere, and closing the door again is a step somebody has to remember. --expires bounds it, but the smallest unit is a day.

The tunnel gives you the same reach with none of that. Nothing listens on the public internet, the addresses only answer on 127.0.0.1 while the command runs, the session dies on its own after 8 hours, and opening and closing it are both in the project’s audit log. Reach for a principal instead when something outside the platform must reach the database permanently — a BI tool, a partner’s importer, a CI job. A Valkey has no principals yet, so the tunnel is its only way in from outside (see Valkey).