Staging and rollback
A deployment that fails to build never goes live, so a broken file costs you a failed deployment rather than an outage. A deployment that builds and behaves wrongly is another matter. This guide sets up the three things you want before that day: a staging service to catch it, a rollback to undo it, and a way around GraphPilot if the problem is GraphPilot. What a deployment is and what happens while it runs is on deployments.
The running example is shop-api in production, with its origin at
https://api.example.com, and a staging origin at https://staging-api.example.com. Both
deploy from the same repository, where schema.graphql and gpilot.toml are versioned next to
the application.
What you need
Section titled “What you need”- The
gpilotCLI, logged in, and access to the service’s Deployments in the portal. - A plan that includes more than one service, for the staging service. See pricing.
- Your configuration files in version control, unless
gpilot.tomlholds a JWT provider’s sharedsecret(see below).
1. Create a staging service
Section titled “1. Create a staging service”There is no promotion between environments: a deployment builds from the files in front of it. A staging environment is therefore a second service, with its own subdomain and its own origin:
gpilot service create \ --name "Shop API staging" \ --subdomain shop-api-staging \ --url https://staging-api.example.com \ --environment staging--environment is a label (production unless you set it) that tells the two services apart in
lists. It changes nothing about how the service runs.
The two services share nothing: separate cache, separate keys, separate telemetry. That is what makes a staging deployment a real rehearsal, and it also means a purge on one never touches the other.
2. Deploy to staging first
Section titled “2. Deploy to staging first”Deploy the same files to both, staging first:
gpilot deploy --service shop-api-staging --yes# verify against https://shop-api-staging.k7m2qp.graphpilot.cloud, thengpilot deploy --service shop-api --yesIn CI, run the first line on pushes to a staging branch and the second on main; one
organization API key can deploy both. See deploy from CI, and the
recipe promoting from staging in CI for one workflow that deploys staging on
every merge and production after an approval.
Verify against staging what the change was meant to do: the gp-cache status and
gp-cache-reason of the requests it affects, and the deployment’s findings in the portal. See
findings.
3. Roll back to a deployment that worked
Section titled “3. Roll back to a deployment that worked”To go back, redeploy the version that worked.
In the portal, open Deployments, open the deployment that was good and choose Redeploy. The dialog starts with that deployment’s schema and configuration selected, so the new deployment builds from exactly those two files. It runs on the service’s runtime pin, or the stable version when the service has none, unless you pick another version under Proxy version. The version the good deployment ran on is marked same as this deployment there, as long as it has not been withdrawn.
From the CLI, deploy the previous files again:
git checkout <previous-commit> -- schema.graphql gpilot.tomlgpilot deploy --service shop-api --yesKeep both files in version control either way: git tells you why a version changed, which the
deployment list does not. The exception is a gpilot.toml that holds a JWT provider’s shared
secret, which the file carries as written: keep
that file out of the repository, or use a provider with a public key.
Rolling back to an older runtime has a time limit. After some runtime versions, an older runtime is refused seven days after the service first went live on the newer one, with a message naming the version to use:
This service can no longer run runtime <version>. Deploy runtime <minimum> or later.If no runtime the service can run is registered yet, the message ends with “No runtime it can run is registered yet; contact support.” instead.
A service pinned to an older runtime within those seven days keeps what that runtime needs, so a rollback you pin in time is not cut off. A rollback of the schema and configuration on the current runtime is never affected.
If the bad version was wrong about caching rather than about serving, entries it stored keep their lifetime and partitioning after the rollback, because the cache survives a deployment. Purge them once the rollback is live:
gpilot purge --all --yes --service shop-api4. Know how to take GraphPilot out of the path
Section titled “4. Know how to take GraphPilot out of the path”If GraphPilot itself is the problem, the way out is where your clients point, not a setting.
- On a custom domain, point the DNS record back at your origin. Clients need no change, and the switch takes effect as your DNS TTL allows. Keep that TTL short.
- On the service hostname (
shop-api.k7m2qp.graphpilot.cloud), clients have to be pointed at your origin directly. Make that endpoint configurable in your clients before you need it: it is the difference between a configuration change and a release.
Either way your origin then serves the full, uncached load. Size for it.
Check that it works
Section titled “Check that it works”After each deployment, the newest entry in the list is completed (the CLI writes statuses in
lowercase, in the table and in -o json):
gpilot status --service shop-api-staginggpilot status --service shop-apiAfter a rollback, send a request the bad version answered wrongly with curl. Once you have
purged, the first answer is a MISS from your origin under the restored configuration, and the
gp-cache status and gp-cache-reason match what the good version reported. A HIT before the
purge can still be an entry the bad version stored.
Rehearse step 4 once on staging: switch a test client to the staging origin directly and back.
Pitfalls
Section titled “Pitfalls”- A redeploy uses the service’s runtime pin, else the stable version, unless you choose another. If you suspect a GraphPilot change, pick what the good deployment ran on under Proxy version (marked same as this deployment).
- Staging keeps its own cache. A
HITon staging says nothing about production’s entries, and staging’s hit rate reflects staging’s traffic. - An origin locked to GraphPilot refuses direct traffic. If your origin accepts only GraphPilot’s IP ranges or only signed requests, step 4 needs a way to relax that. Decide it in advance.
- A long DNS TTL turns a five-minute exit into an hour. Lower it before an incident, not during one.