Skip to main content Skip to content

Deployments

Long-lived application instances ZopDay runs in your Kubernetes cluster, built from a connected git repo and managed as a Helm release.

6 min read Last updated: 

A deployment is a long-lived application instance ZopDay runs in your Kubernetes cluster. It lives inside an environment, is built from a connected git repository, and is rolled out through a Helm release that ZopDay manages on your behalf.

Lifecycle

  1. Client calls POST /deployments. ZopDay records the deployment and queues its first build.
  2. The repository is cloned, the stack is detected, and a GitHub Actions build produces the image.
  3. When the build completes, ZopDay applies a Helm release to the target namespace on the deployment’s deployment space, using short-lived cluster credentials minted from the connected cloud account.
  4. Every stage boundary appends an event to the deployment’s events timeline, and the deployment’s status always reflects the live state.
  5. Subsequent pushes (auto-deploy) or config changes create new revisions, rolled out as rolling updates.
  6. DELETE /deployments/{id} uninstalls the release and cleans up its revisions and events, then removes the deployment. Repeating the delete is safe.

Imported (Helm) Services

Besides git- and image-sourced deployments, the cluster import flow can bring existing Helm releases into a project as deployments with sourceType: "helm-import". These are catalog entries for workloads whose lifecycle stays with Helm on the cluster. ZopDay did not build or roll them out, so the UI treats them as view-only: the canvas card carries an Imported · Read-only badge and is not clickable, edit / redeploy / delete are hidden wherever the service is inspected, and no revision history exists (currentRevisionId stays empty). Manage or remove the underlying release with Helm (or re-run the import): the deployment row is a mirror, not a control surface.

Create a Deployment

Two equivalent forms: a flat path for integrations and CI scripts, and an env-nested form for the canvas (which already has the environment in context).

POST /deployments

Create a deployment and queue its first build.

Request
curl -X POST https://api.zop.dev/deployments \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "checkout",
"envId": "env_abc",
"sourceType": "git",
"repoUrl": "https://github.com/acme/checkout",
"branch": "main",
"integrationId": "int_github_001",
"autoDeploy": true,
"configs": {
"port": 8080,
"envVars": { "DB_HOST": "checkout-db.zopnight.internal", "LOG_LEVEL": "info" },
"secretRefs": ["secret://checkout-db-password"]
}
}'
POST /environments/{envID}/deployments

Env-nested create. Same payload, used by the canvas.

List & Get

GET /deployments

List all deployments visible to the caller across every environment.

GET /environments/{envID}/deployments

List deployments in one environment.

GET /deployments/{id}

Get a deployment, hydrated with current revision, configs, and the env's inherited infra (space, namespace, registry).

Response
{
"data": {
"id": "dep_xyz",
"name": "checkout",
"orgId": "org_acme",
"envId": "env_abc",
"sourceType": "git",
"repoUrl": "https://github.com/acme/checkout",
"branch": "main",
"integrationId": "int_github_001",
"autoDeploy": true,
"spaceId": "spc_abc",
"namespace": "checkout-prod",
"registryUrl": "123456789012.dkr.ecr.us-east-1.amazonaws.com/checkout",
"currentRevisionId": "rev_005",
"status": "active",
"configs": "{\"port\":8080,\"envVars\":{\"LOG_LEVEL\":\"info\"}}",
"canvasPosition": { "x": 320, "y": 180 },
"lastDeployAt": "2026-04-29T11:30:00Z",
"createdAt": "2026-04-15T08:00:00Z",
"updatedAt": "2026-04-29T11:30:00Z"
}
}
DELETE /deployments/{id}

Tear down a deployment: uninstall its Helm release, clean up revisions and events, then remove the deployment. Safe to repeat.

Update Configs

Env-var, secret, port, replica, and resource changes go through PATCH /deployments/{id}/configs. The new configs take effect on the next revision and are applied as a rolling update. Configs are stored as JSON; the recognised fields are port, replicas, liveness, resources, expose and rootPath.

PATCH /deployments/{id}/configs

Patch deployment configs.

Request
curl -X PATCH https://api.zop.dev/deployments/dep_xyz/configs \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"configs": {
"envVars": { "LOG_LEVEL": "debug" },
"port": 8080
}
}'

Canvas Position

PATCH /deployments/{id}/canvas-position

Persist the (x, y) of a deployment card on the canvas. Body: { x, y }, both finite numbers.

Analyze a Deployment

POST /deployments/{id}/analyze

Re-run deploy-readiness checks against the current source + configs. Returns warnings (missing health probe, missing resource requests, etc.) without creating a revision.

Revisions

Every image or config change is captured as a revision. Revisions are immutable. A redelivered GitHub push does not create a second revision; see Webhooks.

POST /deployments/{id}/revisions

Create a new revision (typically from CI after a build completes).

Request
curl -X POST https://api.zop.dev/deployments/dep_xyz/revisions \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"imageRef": "123456789012.dkr.ecr.us-east-1.amazonaws.com/checkout:v1.4.3"
}'

imageRef is required for image-sourced deployments. Other fields: dockerfile, envVars, deployedBy, configOnly (true to roll out a config change without a new image) and values (for imported Helm services).

GET /deployments/{id}/revisions

List revisions for a deployment.

GET /deployments/{id}/revisions/{revID}

Get a specific revision.

Rollback

POST /deployments/{id}/rollback

Roll back to a prior revision. The target revision is cloned into a new revision and applied.

Request
curl -X POST https://api.zop.dev/deployments/dep_xyz/rollback \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "revisionId": "<revision id>" }'

Events Timeline

GET /deployments/{id}/events

Append-only chronological list of deploy stage events. Used by the canvas drawer's activity feed.

Response
{
"data": [
{ "id": "ev_1", "stage": "building", "status": "started", "createdAt": "2026-04-29T11:00:00Z" },
{ "id": "ev_2", "stage": "building", "status": "succeeded", "meta": { "imageRef": "..." }, "createdAt": "2026-04-29T11:04:30Z" },
{ "id": "ev_3", "stage": "deploying", "status": "started", "createdAt": "2026-04-29T11:04:35Z" },
{ "id": "ev_4", "stage": "rolling_out", "status": "succeeded", "meta": { "ready": 3, "desired": 3 }, "createdAt": "2026-04-29T11:05:10Z" },
{ "id": "ev_5", "stage": "active", "status": "succeeded", "meta": { "address": "a-1234.elb..." }, "createdAt": "2026-04-29T11:06:50Z" }
]
}

LoadBalancer Status

For deployments that expose ports as http or tcp, ZopDay provisions a cloud LoadBalancer through the cluster’s ingress class. The endpoint below is what the UI polls during the post-deploy “Waiting for public address…” state.

GET /deployments/{id}/loadbalancer

Get LoadBalancer status (assigned address, listeners, TLS certificate).

Response
{
"data": {
"status": "ready",
"address": "a-12345.elb.us-east-1.amazonaws.com",
"ports": [
{ "port": 80, "protocol": "HTTP" },
{ "port": 443, "protocol": "HTTPS" }
],
"tls": { "issuer": "letsencrypt-prod", "expiresAt": "2026-07-29T00:00:00Z" }
}
}

See Builds for how images are produced, Projects & Environments for how deployments are grouped, and Deployment Spaces for the cluster they target.

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·