Skip to main content Skip to content

Projects and environments

Plan and create the Project → Environment → Deployment hierarchy that every ZopDay deploy runs through, and know what changes when you edit an environment.

8 min read

ZopDay’s deployment catalogue is a three-level hierarchy: Project → Environment → Deployment. Everything else in the product builds on it, so plan it before you create your first project; restructuring it later can take weeks.

ZopDay Projects page in grid view: five project cards, each with a health dot, tiles counting its git and container-image services, and chips for its environments, with search, a status filter and an Import project button

The Projects page; each project’s services by source and its environments, at the top of the Project → Environment → Deployment hierarchy.

Before you start

  • A deploy target: a registered deployment space (cluster or VM) on a connected cloud account, or ZopCloud where it is enabled for your organisation (see Quick Deploy).
  • The Kubernetes namespace you want each environment to use. You can pick an existing one or create it with the environment.
  • Optional: a registry integration for built images. Without one, images go to the cloud’s default registry.
  • Permission to create projects and environments in your organisation. Check your role in Settings → Roles.

How it works

The hierarchy

Terminal window
Organisation
└── Project (organisation-scoped grouping; usually a service, team, or app)
└── Environment (binds to a space + namespace + registry)
└── Deployment (a git repo + branch + config)
└── Revision (one rollout; built image + Helm release)
LevelOwned byStored asWhat it represents
ProjectOrganisationCatalogueAn organisation-scoped grouping. Organisation name + project name is unique.
EnvironmentProjectCatalogueThe “where”; a space + namespace + (optional) registry integration.
DeploymentEnvironmentCatalogueThe “what”; repo URL, branch, config. Infra fields are inherited from the parent environment.
RevisionDeploymentRuntimeOne rollout. Carries the built image and its rollout state.

Deployment catalogue and runtime data are kept apart on purpose. The deployments concept page explains why.

Projects are organisation-scoped and soft-deletable, and they don’t nest. Every deployment lives inside exactly one environment, which supplies its infrastructure context.

Why bind the namespace at the environment level

Deploys in one environment share a namespace. Two deployments in payments-prod (the same environment) run in the same namespace, so one can reach the other by its Kubernetes Service name without naming a namespace. See Connecting services.

Multiple environments can share a namespace, for example a staging environment in the same namespace as another project’s staging. Avoid it if you can: you lose isolation for resource limits, RBAC, and tear-down.

Organisation cascade

Deleting an organisation removes its projects, and the environments and deployments inside them, from ZopDay.

Deleting an organisation does not touch its clusters, because the underlying cluster is yours, not ZopDay’s. To remove the cluster-side artefacts as well, tear down each deployment before you delete the organisation.

Create a project

  1. Open New Project

    Click New Project in the sidebar.

  2. Name it

    Enter a project name. It must be unique in your organisation and is used to identify the project in the UI; lowercase kebab-case is recommended.

  3. Choose where it deploys

    Pick ZopCloud (fully managed, where enabled for your organisation) or Your own cloud, then select a cluster or VM as the deployment target. Provision next to the target picker starts a new cluster or VM if you don’t have one.

  4. Create

    Click Create project.

When to create a project:

  • One service that has its own repo, owners, and release cadence → one project
  • A monorepo with multiple deployable services → still one project; multiple deployments inside it
  • A platform team’s shared infrastructure (gateways, ingress controllers, observability stack) → its own project, separate from product projects

Add an environment

  1. Open the project

    Open the project and click Add environment.

  2. Name it

    The name must be unique in the project. Common patterns: prod, staging, qa, dev, or preview-{slug}.

  3. Bind it to a space and namespace

    Pick the registered cluster or VM space, then pick an existing namespace or create one. The space can’t be changed later.

  4. Pick a registry (optional)

    Choose a registry integration for built images, or leave it unset to use the cloud’s default registry (ECR / Artifact Registry / ACR) on the space’s cloud account.

Common patterns

One project per service, multiple environments

This is the most common shape. Each service is a project with dev, staging, and prod environments. Each environment is bound to a different cluster, or to different namespaces on the same cluster.

Terminal window
payments (project)
├── dev → space: shared-dev-cluster, namespace: payments-dev
├── staging → space: staging-cluster, namespace: payments-staging
└── prod → space: prod-cluster, namespace: payments-prod

One project, many ephemeral environments (preview branches)

Each PR gets its own short-lived environment. Teams often use this for review apps.

Terminal window
payments (project)
├── prod → space: prod, namespace: payments-prod
├── staging → space: staging, namespace: payments-staging
├── preview-pr-1234 → space: review, namespace: pr-1234 (auto-created on PR open)
├── preview-pr-1245 → space: review, namespace: pr-1245
└── ...

Tear preview environments down automatically when the PR closes: have your CI call DELETE /projects/{projectID}/environments/{id} from the close webhook. Deleting an environment tears down the services in it: their Helm releases are uninstalled or, on a VM, their containers are stopped and removed.

Multi-tenant platform team

A platform team that runs shared services (ingress controllers, observability) keeps them in its own project, with one environment per cluster, each using the same system namespace.

Terminal window
platform (project)
├── prod → space: prod, namespace: platform-system
└── dev → space: dev, namespace: platform-system

What changes when you change an environment

An environment has three infra fields. You can change two of them in place, but not the space:

FieldWhat happens when you change it
namespaceExisting deployments do not migrate on their own. Redeploy each one to move it to the new namespace.
registry_integration_idNew builds push to the new registry. Existing revisions keep the images they shipped with. Redeploy to move a service onto the new registry.
space_idFixed when the environment is created. To move from cluster A to cluster B, create a new environment on the new space, deploy into it, and then delete the old one. Coordinate with whoever owns DNS and load balancing in front of it.

Reference

Project fields

FieldRequiredNotes
nameyesOrganisation-unique. Used to identify the project in the UI. Lowercase kebab-case recommended.

Environment fields

FieldRequiredNotes
nameyesProject-unique. Common patterns: prod, staging, qa, dev, or preview-{slug}.
space_idyesThe registered cluster (or VM space). See Cluster registration.
namespaceyesThe Kubernetes namespace inside the space. Pick an existing one or create it when you create the environment.
registry_integration_idnoWhere built images are pushed. If unset, images go to the cloud’s default registry (ECR / Artifact Registry / ACR) on the space’s cloud account.

Project endpoints

Terminal window
POST /projects Create
GET /projects List with filters
GET /projects/{id} Get one
PATCH /projects/{id} Partial update
DELETE /projects/{id} Soft-delete
GET /projects/stats?ids=… Per-project counts, batched (up to 50 IDs)

Environment endpoints

Terminal window
POST /projects/{projectID}/environments Create
GET /projects/{projectID}/environments List
GET /environments/{envID} Flat get (no project context needed)
PATCH /projects/{projectID}/environments/{id} Partial update
DELETE /projects/{projectID}/environments/{id} Delete
GET /environments/{envID}/deployments List deployments in this env
POST /environments/{envID}/deployments Create deployment in this env

To discover namespaces on the cluster behind an environment, call GET /space-discovery/{spaceID}/namespaces (it needs a kubeconfig). See Deployment spaces for details.

Troubleshooting

I changed the namespace but my services didn't move

Existing deployments don’t migrate on their own. Redeploy each service to move it into the new namespace.

I need an environment on a different cluster

An environment’s space is fixed at creation. Create a new environment on the new space, deploy into it, then delete the old environment.

Deleting the organisation left resources on my cluster

Deleting an organisation removes ZopDay’s records only; the cluster is yours. Tear down each deployment before deleting the organisation, or run helm uninstall on the leftover releases.

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·