Skip to content

Deployments

A deployment takes your configuration and, for a GraphQL API, your schema, builds them into an edge package, and puts it live at every edge location. It is the only way anything you configure takes effect.

  • gpilot.toml, the service configuration. The CLI also reads gpilot.yaml, gpilot.yml, gpilot.json and gpilot.json5, and converts them to TOML before uploading.
  • schema.graphql, your GraphQL API’s schema, for a GraphQL API. Surrogate keys and cache directives are derived from it. Where a deployment that names no schema takes one from is the service’s schema source: the newest upload by default, or introspection of your origin at deploy time.

A deployment without a configuration file is valid too: every setting is then at its default, the deployment records no config version, and the portal’s Config page lists each default value. The portal offers it as Default configuration, the API as withoutConfig, and the first deployment of a new service’s setup is one.

A plain HTTP service needs no schema. Without one, the deployment is built from the configuration alone: GraphQL features are off, request.graphql_paths is [], and every path is served as plain HTTP. Whether a service has a schema is decided per deployment, so the next deployment with a schema turns GraphQL on again, and one without a schema turns it off.

What you upload is compiled into the package by the deployment build. Nothing is read at request time, which is why a configuration change needs a deployment and why a request never pays for reading one.

The origin URL is not part of this. It belongs to the service and changes with gpilot service edit, taking effect on the next deployment. Only its scheme, host and port are used; see TLS and ports.

Terminal window
gpilot deploy # ./schema.graphql and ./gpilot.toml
gpilot deploy --schema api.graphql --config prod.toml

Before it starts, gpilot deploy shows whether the configuration and the schema are new, changed or unchanged, and asks you to continue. Without a schema file it says No schema found: deploying as a plain HTTP service, GraphQL features are off. before asking, and shows Schema removed: GraphQL features off when the live deployment had a schema. Pass --yes to skip the question. In a non-interactive run, such as CI, it proceeds without asking.

The command then waits for the deployment to finish, up to --timeout (20 minutes by default), and prints each step as it completes, followed by any findings. Pass --detach to return as soon as the deployment is accepted. --force-build builds again even when the schema, configuration and GraphPilot version are unchanged.

If the progress stream closes before the deployment reports how it ended, gpilot deploy keeps checking the deployment until it ends: completed exits 0, failed exits 1. --timeout bounds the whole wait, watching and checking together. If the deployment is still open when it runs out, the command exits 7, meaning the outcome is unknown and the deployment may still be running; check it with gpilot status.

Terminal window
gpilot status # recent deployments
gpilot cancel # stop one that is still running

The portal lists a service’s deployments under Deployments, where you can also start one (New deployment), redeploy an earlier one, or stop a build. A new deployment can take each file from the latest upload, an earlier deployment or your machine, or deploy without a schema or without a configuration file. See Deployments in the portal.

A deployment moves through STARTED → PENDING → COMPLETED, or ends in FAILED or CANCELLED. These are the GraphPilot API’s spellings. The CLI writes the same statuses in lowercase (started, pending, completed, failed, cancelled), in its tables and in -o json alike, so a script that checks gpilot status compares against completed.

Your service keeps serving the whole time. The current version answers traffic until the new one is ready, and traffic moves over when it is. A deployment that fails to build never becomes live, so a broken configuration costs you a failed deployment rather than an outage.

One deployment of a service runs at a time. Starting a new one while another is still STARTED or PENDING cancels the running one: it ends CANCELLED, never goes live, and its errorMessage reads Replaced by a newer deployment of this service before it went live. A deployment GraphPilot stopped for another reason reads Cancelled before it went live. A deployment canceled on request (gpilot deployment cancel, cancelDeployment, or Stop this build in the portal) has no errorMessage.

Cache entries are keyed by the operation, not by the deployment that produced them, so deploying does not clear the cache. That is usually what you want: a configuration change should not cost you your hit rate.

It does mean a change only affects responses stored after it. Two cases where that matters:

  • You shortened a freshness lifetime (TTL). Entries written under the old one keep it until they expire.
  • You changed a partitioning policy. Entries written under the old one keep their old discriminator.

If the change was made because the cached data is now wrong, deploy and then purge:

Terminal window
gpilot deploy --yes && gpilot purge --all --yes

gpilot purge always asks for confirmation and refuses in CI without --yes, so keep the flag in scripts.

A schema change is the usual reason. Removing a field does not make cached responses containing it disappear.

GraphPilot reads a query’s lifetime and scope from the schema you deployed, not from the one your origin runs. A query that selects a field, or a fragment on a type, the deployed schema does not declare is still forwarded and answered, but its response is never stored, at any depth and whatever your origin’s Cache-Control says: nothing tells GraphPilot who may share that field’s value. gp-cache reports PASS with CACHE_SKIPPED_UNRESOLVED_SELECTION until a deployment carries the schema that declares it.

So when a release adds fields or types:

  1. deploy the new schema to GraphPilot,
  2. then deploy the origin that serves it,
  3. then ship the clients that query it.

Adding fields to the deployed schema before your origin has them costs nothing: no client asks for them yet. The other order costs hit rate for every query that already selects the new fields, for as long as the schema lags. Removing a field goes the other way round: stop querying it, take it out of your origin, then deploy the schema without it.

Configuration is validated at deploy time, not at request time, so mistakes surface here. A deployment is refused when it starts, or fails in its build, rather than being quietly adjusted, when:

The message names the value and the limit. Nothing is silently adjusted. When the build refuses the configuration or the schema, the message starts with The configuration was refused: or The schema was refused:, followed by the reason the build gave.

While an organization is being deleted, or the account that pays for it, none of its services is deployed again. A new deployment is refused by the API like any other change, with “This organization is being deleted” or “This account is being deleted”. A running deployment fails, without a retry, if the deletion starts before it goes live. Its message is:

This organization is being deleted, so it accepts no deployments. The service stays switched off until the deletion is complete. Contact support if this is not what you expect.

When the account is being deleted, the message reads:

This account is being deleted, so its organizations accept no deployments. The service stays switched off until the deletion is complete. Contact support if this is not what you expect.

A deployment can fail with a support reference

Section titled “A deployment can fail with a support reference”

A deployment that fails for a reason outside your configuration and schema does not show the build’s output. Its message is one sentence:

The deployment failed because of an internal error. Contact support and quote reference <reference>.

The reference identifies the failed run in GraphPilot’s logs. Contact support and include it. The portal, gpilot and the GraphPilot API (Deployment.errorMessage, and the error of the step that failed) all show the same message.

Findings that do not refuse a deployment are recorded by the build as diagnostics. Each is an error (something you configured has no effect), a warning (it works as written, but probably not as meant) or a notice (nothing to fix, only something worth knowing about what was deployed). None of them fails the deployment.

They come from two places, your schema and your configuration. origin says which (schema or config), and source names the check that produced it:

sourceoriginLocated byExamples
cache_control, surrogate_key, auth, type_relationschemaline and column in your schema, where the finding has a positionAn of that does not resolve, an ignore that is not a Boolean, an explicit key on a type the configuration excludes.
policy_expression, cache_policy_vary, request_graphql_paths, no_schema, auth_provider, planconfigkey (the configuration key it is about, where one applies) and the message, which names the entry. line and column are always null.See below.

The configuration findings are below. A deployment built by an earlier runtime reports policy_expression as radiogram until the service is deployed again.

sourceSeverityFinding
policy_expressionwarningA policy expression negates a predicate over a value the request may not carry, so it has no answer for a request without it and the key’s own direction decides. The key is named, such as client.profile[0].when.
cache_policy_varyerrorA [[cache.policy.vary]] entry whose name is not a legal header name. The entry is skipped and has no effect. Reported once per entry, and the message quotes the name.
request_graphql_pathserrorrequest.graphql_paths is set, but the deployment has no schema. The key is ignored and every path is served as plain HTTP. Add a schema to serve GraphQL on those paths, or remove the key. Reported for any value, [] included.
auth_providerwarningA JWT provider sets no allowed_issuers, no allowed_audiences, or neither, so it accepts tokens from any issuer or for any audience its keys verify. A provider that verifies with a public key and sets no allowed_issuers is not warned about: its deployment fails. The key is the provider’s table, such as auth.providers.idp, and the message names what is missing. Reported once per provider.
policy_expressionnoticetelemetry.record is false, so the service records no request in Insights. Requests are still served and counted for billing. The key is telemetry.record.
no_schemanoticeThe deployment has no schema: it runs as a plain HTTP service, with GraphQL features off. Recorded on every deployment without a schema, with key null.
planwarningThe configuration sets origin.shield, but the plan does not include shielding. The shield is deployed and stays inactive until the plan includes it, with no redeployment needed. The key is origin.shield. Added by GraphPilot from the plan at the time of the deployment, not by the build.

Diagnostics are shown in three places:

  • In the portal. Schema → Findings shows the findings of the live deployment, placed on the definitions they are about. Each deployment’s page under Deployments shows its own. Config → Findings lists configuration keys that do nothing: unknown keys and keys that have no effect where they stand. See findings.
  • In the CLI. gpilot deploy prints the diagnostics (schema and configuration) when the deployment completes or fails, unless it was run with --detach. It does not print the list of configuration keys that do nothing; that list is in the portal and on the GraphPilot API as Deployment.configAnalysis.
  • On the GraphPilot API, as Deployment.diagnostics:
query {
organization {
services {
subdomain
deployments {
id
createdAt
diagnostics {
origin
source
severity
message
key
line
column
}
}
}
}
}

Each record has those seven fields. severity is ERROR, WARNING or INFO (a notice, which never counts as an error or a warning). key is null for a schema finding, and line and column are null where the finding has no position.

The list itself answers one more question. null means nothing was recorded: the deployment never got as far as building. An empty list is the good case: the schema and configuration were checked and nothing was found.

There is no promotion flow between environments: a deployment builds from the files in front of it. A staging environment is a second service you deploy the same files to first. To undo a deployment, redeploy an earlier one, from its page under Deployments (Redeploy) or by deploying the previous files from the CLI. And if GraphPilot itself is the problem, the way out is where your clients point. Staging and rollback walks through all three.

Terminal window
gpilot service destroy <subdomain>

Tears down the deployed infrastructure and stops serving, while keeping the service, its schema, its configuration and its history. Deploy again to bring it back. The teardown runs in the background, so the command reports that the request was accepted rather than waiting. It asks for confirmation; pass --yes in a script.

To remove the service itself, with its history and hostnames, delete it in the portal (see deleting a service) or with gpilot service delete.