a month ago
I'd like to enable PITR programmatically instead of needing to click a button on the dashboard.
2 Replies
a month ago
There is no documented API mutation for enabling PITR today. The current flow is dashboard-only (Backups tab on the Postgres service). That said, our public API is the same GraphQL API that powers the dashboard, so you can enable PITR in the dashboard with the browser network tab open to capture the exact mutation and variables, then replay it programmatically via the public API. You can also explore the schema via the GraphiQL playground to find the relevant mutation.
Status changed to Awaiting User Response Railway • 29 days ago
a month ago
Thanks bot! That helped my bot. Here's what it has to say:
Here's how to enable Postgres PITR programmatically, for the next person who finds this thread.
The key insight: PITR isn't a special dashboard feature — it's a template (templateCode: "postgres-pitr"; the disable button literally calls templateRevert). And template deployment is the one public-API operation that registers buckets in the environment config, which is what makes bucket reference variables resolve. So you enable PITR by putting its pieces into a template deploy.
Steps:
- See the canonical shape (optional but useful — it's publicly queryable):
query { template(code: "postgres-pitr") { id serializedConfig } }
- In your own template's serializedConfig, add a bucket and the pgBackRest variables to your Postgres service:
{
"buckets": { "my-pitr-bucket": { "name": "Postgres-PITR" } },
"services": {
"...your postgres entry...": {
"variables": {
"WAL_ARCHIVE_BUCKET": { "defaultValue": "${{Postgres-PITR.BUCKET}}" },
"WAL_ARCHIVE_ENDPOINT": { "defaultValue": "${{Postgres-PITR.ENDPOINT}}" },
"WAL_ARCHIVE_KEY": { "defaultValue": "${{Postgres-PITR.ACCESS_KEY_ID}}" },
"WAL_ARCHIVE_PATH": { "defaultValue": "/pgbackrest" },
"WAL_ARCHIVE_REGION": { "defaultValue": "${{Postgres-PITR.REGION}}" },
"WAL_ARCHIVE_SECRET": { "defaultValue": "${{Postgres-PITR.SECRET_ACCESS_KEY}}" }
}
}}
}
-
Deploy with templateDeployV2. The bucket is created and registered, Postgres boots with resolved variables, pgBackRest self-activates, and coverage appears in the Backups panel within a few minutes. Works with postgres-ssl (use a major version tag; minor pins aren't supported with PITR).
-
Verify programmatically: query variables(projectId, environmentId, serviceId, unrendered: false) and check every WAL_ARCHIVE_* value is non-empty. Empty renders mean the bucket isn't registered — archiving is silently off even though everything looks configured.
Pitfalls that cost us time:
- bucketCreate alone is not enough: the bucket exists but isn't in the environment config, so references render empty and you get "WAL archive credentials may be invalid" with no WAL ever archived. Regenerate credentials & redeploy can't fix that state.
- You can't add the registration afterward: environmentStageChanges silently drops buckets entries, and environmentApplyChangeSet rejects them. For an existing project, the dashboard's Enable PITR button is currently the only path (and Stage disable → apply → Enable repairs a broken half-configured state).
- templateDeployV2 requires ≥1 service and always creates services from entries — deploy PITR as part of your main template rather than a follow-up mini-template, or you'll get a name-collision duplicate (Postgres-MdBX) to clean up.
Requests for the Railway team: register bucketCreate buckets in the environment config (or document that they won't resolve as references), error instead of silently dropping unknown config keys in environmentStageChanges, and consider a bucket-only/attach mode for templateDeployV2 so existing projects can be retrofitted. A first-class PITR mutation would make all of this unnecessary — happy to be a design partner.
Status changed to Awaiting Railway Response Railway • 29 days ago
Status changed to Solved mrubens • 29 days ago