What survives a push, and what doesn’t
When you push todev, forge replaces the previous deployment. The new pod starts from your image with a clean filesystem — nothing the old pod wrote to disk carries over, because forge does not attach a persistent volume to a pushed app.
| Where your data is | Survives a dev push? |
|---|---|
| In an external database you connect to | Yes — it lives outside the cluster, untouched by your deploy |
| Baked into your image (resource files, defaults) | Yes — it’s part of every build |
| Pod-local disk (files your pod writes at runtime) | No — the new pod gets a clean filesystem |
| In memory | No — every push is a fresh process |
staging it’s stricter still: each push spins up a fresh preview environment, so nothing carries across staging pushes. A clean slate every time is the point of a preview.
For the full lifecycle of what a push replaces, see Pushes.
There is no automatic per-app database
A pushed app — aplugin-paper, plugin-velocity, gamemode, or service — runs in your namespace with no database attached. Forge does not provision Postgres (or any database) for it. There is no per-app database URL injected, no schema created, no connection string to discover.
Managed Postgres for developer apps is on the roadmap, not a today capability. The platform runs Postgres for its own services and for shared dev-workspace infrastructure, but there is no supported flow that hands a pushed app its own provisioned database. If you need one, raise it in
#grounds-platform with your app and data shape so it can be tracked.Connect an external database
This is the supported pattern today: run the database wherever you like (a managed Postgres, your own Redis, a hosted provider), and inject the connection details as an encrypted secret so they are never baked into your JAR or your manifest.Decide what your app reads
Pick the env var names your code reads at startup —
DATABASE_URL, DB_PASSWORD, whatever your framework expects.Names cannot start with GROUNDS_ (reserved for platform built-ins like GROUNDS_TOKEN). Everything else is yours.Store the connection string as a secret
Set sensitive values as encrypted secrets — not plain env vars — from the Env tab in the portal. Forge encrypts them at rest and injects them at deploy time.See Environment and secrets for the exact flow, naming and size rules, and the secrets rollout caveat.
Read it in your app
Forge injects the secret into your container as an ordinary environment variable (via a Kubernetes
secretKeyRef), so your code reads it like any other env var.What about the Postgres in dev workspaces?
If you’ve used a test environment, you may have seen a Postgres running inside it. That is shared throwaway infrastructure for the whole workspace bundle, not a database provisioned for your specific app:- It’s a disposable, fixed-credential Postgres that lives only inside the per-engineer workspace.
- It exists for bundled platform services to share, and it is wiped with the workspace.
- It is not how a pushed app gets durable storage, and it does not exist in production.
Limits and honest caveats
Pod-local disk does not survive a push
Pod-local disk does not survive a push
A pushed app has no managed volume. Files your pod writes at runtime live on ephemeral pod storage and are gone when the pod is replaced on your next push. Anything you need to keep belongs in a database you control.
Staging keeps nothing
Staging keeps nothing
Every
staging push is a fresh preview environment. Data written in one staging push is not visible in the next — by design.No managed Postgres for apps yet
No managed Postgres for apps yet
There is no
grounds db create, no auto-injected DATABASE_URL, no per-app schema. If a doc or example implies a pushed app gets a database automatically, that’s aspirational — it isn’t wired in the push flow today.Secrets depend on platform config
Secrets depend on platform config
Encrypted secret writes can 503 if the forge instance hasn’t been provisioned with its secret-encryption key. That gates only the encrypted path; plain env vars keep working. See Environment and secrets.
Related
Environment and secrets
Set plain env vars and encrypted secrets — the supported way to pass a database connection string to your app.
Pushes
What a push replaces and what survives it.
Preview environments
Why staging pushes keep nothing — each one is a clean slate.
Manifest reference
Every field in
grounds.yaml. Note: there is no database field — credentials go in secrets, not the manifest.