Skip to main content Skip to content

Deployments

Understand what a ZopDay deployment and revision are, where deployments come from, how each revision moves through the pipeline, and how to edit, share, or delete one.

13 min read

A deployment is the deployment catalogue entry for one shippable thing: a repo, branch, and config that ZopDay can roll out repeatedly. A revision is one rollout of that deployment: the specific image and Helm release that is live or pending. Deployment catalogue data is stable and editable; revision data is append-only and immutable once shipped, so editing a deployment changes future rollouts, never past ones.

ZopDay deploy canvas for payment-service production: namespace and registry details, type, status and source filters, a banner for an ephemeral preview machine, and six services (api-gateway, billing-svc, fraud-scorer, ledger, preview-api, preview-web) from git or a container image with port and health

The deploy canvas for one environment: each service with its source, port, replicas, and health.

Before you start

  • A project with an environment bound to a registered space. See Projects and environments.
  • For git deployments, the repo connected. Auto-deploy on push needs the GitHub App integration (see Pipelines).
  • A role with the deployment:* policies you need: deployment:view to see revisions, deployment:create / deployment:update / deployment:delete to change them.

How it works

Where a deployment comes from

Most deployments come from a repo, but there are four kinds. All of them share the same deployment catalogue, revisions, and live progress view:

SourceWhat it isWho owns the release
Git repoZopDay builds an image from your code and ships it. The default.You
Container imageYou supply an image reference; nothing is built.You
App CatalogA Helm app ZopDay installs from the App Catalog.ZopDay
Imported Helm releaseA release already running on your cluster that ZopDay adopts so it shows up in the topology.You

The last two behave differently when you delete them. ZopDay installed the App Catalog app, so deleting it runs a real helm uninstall. ZopDay never installed the imported release, so removing it only stops tracking it. The release keeps running.

Imported Helm releases are read-only. ZopDay never rolls them out, and you can’t edit or delete them from the canvas. They carry a purple Imported marker on the canvas card, the drawer header, and the detail page, with an info button that explains why they are view-only. A project whose services are all imported shows the same marker in the sidebar and on its project card. The “How to access” card shows the public URL your cluster’s ingress routes to the service. If no ingress routes there, it shows the in-cluster address instead.

Deployment catalogue vs runtime

LayerWhat it owns
Deployment catalogueProjects, environments, deployments, and deployment spaces. Stable records you create, edit, and delete.
RuntimeDeployment revisions (versioned rollouts and the work queue), and the append-only event timeline.

The runtime is stateless with respect to the deployment catalogue: it reads that data and never keeps its own copy. Infrastructure fields (which space, which namespace, which registry) come from the parent environment and are not stored on the deployment, so a deployment picks up a change to its environment’s namespace or registry on its next deploy.

Revisions and the work queue

Each revision doubles as a work-queue item, moving through these states:

Terminal window
pending → claimed → build_dispatched → pending → claimed → deploying → active | failed | dlq

Version metadata and work-queue state live on the same record, so nothing needs reconciling if a worker restarts mid-deploy.

The pipeline (per revision)

Terminal window
Resolve → Clone → Detect → Build (GitHub Actions) → Callback → Deploy → WatchRollout

Each stage emits an append-only event at its start and on success or failure. This is the same pipeline described in Pipelines and run in the Quickstart, viewed here per revision.

  1. Resolve

    Read the parent deployment, environment, and space from the deployment catalogue. Verify the space is reachable.

  2. Clone

    Git clone the repo at the configured branch. Git credentials are fetched over the same path ZopDay uses for all repo access.

  3. Detect

    Detect the language, runtime version, and build approach. If a Dockerfile is present, ZopDay uses it as-is; otherwise Railpack detects the build.

  4. Dispatch build

    ZopDay dispatches the build to GitHub Actions. The runner builds the image and pushes it to the registry resolved from the environment, or to the cloud default if there is no registry integration. Nothing builds inside your cluster. After dispatch, the revision is parked in a build-dispatched state so it isn’t re-picked before the build callback resumes it.

  5. Callback (from builder)

    The builder streams log chunks and terminal status back to ZopDay over a signed callback. On success, the deploy stage is queued.

  6. Deploy

    Render the service’s Helm chart with its configuration and apply it with a kubeauth-minted kubeconfig. On a VM space, ZopDay runs the new container behind Caddy instead.

  7. WatchRollout

    Follow the rollout until it reaches steady state and the revision goes active, or fails. See Pipelines for what happens on failure.

On success, status='active' and current_revision_id is updated atomically. On any stage failure, ZopDay retries up to 3 times, then the revision moves to the DLQ.

Webhook idempotency. Each GitHub delivery ID is recorded on the revision, and replays of the same delivery are ignored. If GitHub re-fires the webhook hours later after a transient delivery error, no duplicate revision or build is created.

No standing credentials

The deploy pod holds zero standing credentials on target clusters. Cluster access is minted per deploy via kubeauth and reused from memory for a short time: up to 13 minutes on EKS (a presigned STS token that expires after 15) and up to 45 minutes on GKE (an OAuth token that lives about an hour). On AKS, ZopDay fetches the cluster’s admin kubeconfig and re-fetches it after 13 minutes, but the certificate inside it stays valid until the cluster’s certificates are rotated. There is no long-lived service account or in-cluster agent, and no kubeconfig file stays on disk past the deploy pod’s lifetime.

Share one URL to take a teammate, or a visitor who isn’t signed in yet, straight to installing a specific app, repo, or image. Links start with /deploy and take one of three shapes. If a link carries more than one, the first one present wins.

LinkOptional extrasOpens
?install=<chart>NoneStarter Templates with that App Catalog chart preselected
?repo=<url>&branch= (default main), &path= (default repo root), &port=, repeated &env=NAME=valueThe deploy drawer with the repo filled in
?image=<ref>&port=, repeated &env=NAME=valueThe deploy drawer with the image filled in

ZopDay treats every value as untrusted and checks it before anything opens:

  • A repo URL must be http(s) with no embedded credentials.
  • Ports must be 1 to 65535.
  • Branch names and paths are validated the same way the canvas wizard validates them.
  • PORT can’t be set through &env=.

If a value fails, you see the specific reason and nothing opens. The deploy drawer defaults the target to ZopCloud where it is enabled for your organisation, and Your own cloud reveals a cluster picker. A visitor who isn’t signed in keeps the link through sign-up and sign-in.

Install from the App Catalog

  1. Pick and name the app

    Pick an app or database from the App Catalog, name it, and choose the cluster.

  2. Configure (if offered)

    A Configure step appears only when the chart publishes values worth editing. You configure the app through what its chart publishes, not through the port / replicas / probes form a git-built service uses.

  3. Launch

    Click Launch. Afterwards, the service’s settings panel is generated from the chart’s own schema and has its own Delete service tab.

Chart updates

For any chart-backed service, ZopDay compares the version actually running on your cluster with the newest version in the App Catalog. When yours is behind, a notice appears on the service’s Overview. ZopDay only offers real upgrades. If your version is equal or pinned ahead by hand, you never see a downgrade labelled as an update.

Click the notice to open Settings and a confirm dialog. The dialog downloads both chart packages and diffs their values, so the list of added and removed fields is a true version-to-version comparison. You can set a newly added field with a simple default in the dialog, and it ships in the same upgrade instead of a second rollout.

Starter Templates

Use Starter Templates, the App Catalog flow, when you don’t have a cluster yet. It builds the whole chain in one pass: a project, a cluster provisioning job, a namespace, an environment, and finally the deployment and its first revision. Nothing is created until you press Launch.

Cluster provisioning takes 15 to 30 minutes, so the wizard keeps its place if you navigate away or refresh. The job carries on server-side, and the page reattaches to it. Values that look like secrets are not kept across a refresh. The wizard lists them at Launch so you know they’ll install at the chart’s default.

Open Starter Templates from the sidebar to create a new project. Open it from the deploy canvas toolbar or its empty state to reuse the project and environment you already have open.

Edit a deployment

Common edits and whether they create a revision:

EditTriggers new revision?
repo_url changeNo. The next manual or webhook trigger creates a new revision against the new repo.
branch changeNo. Same as above.
Config change (saved from the service’s Settings tab)Yes: config-only revision. config_only=true on the new revision. No rebuild fires. The same image is applied with the new values. Over the API, PATCH /deployments/{id}/configs stores the change and POST /deployments/{id}/apply-config rolls it out.
canvas_position changeNo. Visual only.
Environment edits to namespace or registryNo. Existing deployments stay where they are until you redeploy them. The space can’t change: it is fixed when the environment is created (see Projects and environments).

Rollback creates a revision

A rollback does not edit an existing revision. It creates a new revision that mirrors the target. The new revision reuses the target revision’s image, so no rebuild fires. It takes the service’s current configuration and environment variables, so a rollback reverts code, not config. Every change to what’s running gets its own revision, with its own actor and timestamp. See Rollbacks for the full contract.

Delete a deployment

Deleting a deployment triggers a teardown before the deployment catalogue entry is soft-deleted. Teardown is:

  • helm uninstall of the release on the bound space’s namespace
  • Revision and event cleanup
  • Idempotent: re-runs return already_clean=true

Reference

Deployment fields

FieldNotes
env_idThe parent environment. Defines the space, namespace, and registry.
repo_urlGit URL of the source repo.
branchThe branch to track. Auto-deploys and redeploys build this branch at its latest commit.
current_revision_idPointer to the latest successfully shipped revision. Updated atomically when a revision goes active.
statusThe deployment’s current state (for example active, in flight, or failed), derived from its latest revision.
last_deploy_atTimestamp of the last successful deploy. Drives the project list’s “last deploy” column.
canvas_position{x, y} for the architecture canvas.

Revision fields

FieldPurpose
statusThe state machine above
delivery_idWebhook idempotency. Replays of the same GitHub delivery are ignored and no-op.
payload_snapshot JSONThe payload that triggered this revision: repo state, env, registry. Frozen at claim time so a mid-flight env edit doesn’t surprise the build.
stage_markerWhich pipeline stage the worker last completed. Used for resume on pod restart.
retry_countHow many times this revision has been retried. Caps at 3 before DLQ.
claimed_atWhen the current worker pod last claimed this revision. Drives stale-lock recovery.
config_onlyTrue if this revision is a config-only redeploy (no rebuild).
snapshot_atWhen payload_snapshot was frozen.

Troubleshooting

Teardown failed because the cluster was unreachable

Re-trigger the teardown once the cluster recovers. Teardown is idempotent, so a partial first attempt won’t cause a double uninstall; a re-run on a clean release returns already_clean=true.

The Templates button does nothing

The environment runs on a VM. App Catalog apps are Helm charts and need a Kubernetes cluster, so the button is inert on a VM environment and its tooltip gives the reason. Use a cluster environment, or deploy from a repo or image instead.

A chart upgrade shows no configuration differences

This is expected when the fix lives entirely in the chart’s templates: nothing in the values changed. The chart version still moves when you confirm.

An install link opens nothing

One of the link’s values failed validation (for example a repo URL with embedded credentials, a port outside 1 to 65535, or PORT set through &env=). ZopDay shows the specific reason; fix that value and share the link again.

Next steps

Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·