Skip to content
NebulaCtrldocs
Concepts

Projects and environments

How NebulaCtrl organizes work. Organizations own projects, projects hold environments and services, and each service runs as processes from a source.

NebulaCtrl organizes everything in a hierarchy. An organization owns projects. A project has environments and services. A service is deployed separately in each environment and runs as one or more processes.

Organization
├── Clusters, members, teams, API tokens, Git connections
└── Project
    ├── Environments: development, production, preview environments
    └── Services (each deployed per environment)
        ├── Source: image, git, public-git or proxy
        └── Processes: http, worker, cron, job or proxy

Organizations, roles and teams

An organization is the top-level tenant. Every project, cluster, member, invitation and API token belongs to exactly one organization. The first person to sign in to a new control plane becomes the owner of the organization named Default. Its owners also operate the control plane itself, for example by starting a console update.

A role says what a member or an API token may do:

RoleMay
viewerRead everything except secret values.
deployerEverything a viewer may, plus, among other things, change services, processes, variables, domains and volumes, deploy, roll back, cancel deployments and scale.
adminEverything a deployer may, plus, among other things, create projects and environments, connect clusters, decide approvals, invite members, and manage API tokens, Git connections and policy.
ownerEverything an admin may, plus delete or transfer the organization.

An API token carries a role of its own and can be limited to specific projects. A team is a named group of members that owns projects. You manage a team by hand or provision it from your identity provider with SCIM. See Members and teams.

Projects

A project groups the services that ship together. New project starts it with the environments you tick: development, staging and production, all ticked by default. You can add more later. A project also holds its own variables, its deploy concurrency limit and its preview environment settings.

You create a project in the console with New project. Under Start with, choose Empty canvas, Web + Postgres or From a repository. A repository can start the project from its nebula.toml, from a Compose file, or from its Dockerfile alone. You can also install a template, import a Compose file, or declare the whole project in a nebula.toml project file.

Environments

An environment is a deployment target within a project, such as development or production. Each environment has:

  • One cluster. The environment is bound to a cluster when it's created, to the organization's recommended cluster unless you pick another. A new or unbound environment binds to the connected cluster that is publicly reachable first, then the one already running more of the project's environments, then the one running more of the organization's, then the one with more free memory. An environment with no cluster binds on its first build or deploy.
  • Its own namespace in that cluster, with default-deny network rules. See Networking.
  • Its own variables, domains and process settings. Replicas, resources and volume size are defaults on the service that each environment can override.
  • A tracked branch, main by default, and an auto-deploy setting. A push to the tracked branch builds and deploys a Git service when auto-deploy is on. It's on in development and off in production.

A production environment is protected. Every deploy, rollback, promotion or change set there needs an approval, and some pass at once under your organization's policy. See Change sets and approvals.

A preview environment is a short-lived copy of a base environment for one pull request from the same repository. It deploys from the pull request's head branch and is deleted when the pull request closes, or when it goes 1, 3 or 7 days without a push, as you choose in the project's settings. See Preview environments.

Deleting an environment or a project deletes everything it owned, including volumes and their backups in object storage. The confirmation lists what goes before you type the name.

Services and sources

A service is a deployable unit: an image plus one or more processes. Its source says how the image comes to exist:

SourceThe image comes fromHow it deploys
imageA registry, pulled ready-built.When you deploy a tag or digest. A push trigger can create a release when a matching tag appears in the registry. Without it, NebulaCtrl builds nothing.
gitA repository reached through a Git connection (a GitHub App, Forgejo or GitLab). NebulaCtrl builds it.On every push to the environment's tracked branch, or when you deploy.
public-gitA public repository URL, cloned without any connection. NebulaCtrl builds it.Only when you deploy, because there's no webhook to receive a push.
proxyNo image at all. Every process forwards to an upstream address the cluster can reach.Nothing is built or pulled.

An image source with a push trigger is called trigger-only. See Builds for how Git sources are built, and Deploy an image for registries and tags.

Processes

A process is a named way of running a service's image, with its own command, resources and scaling. The kind decides how it runs:

KindWhat it is
httpA long-running web process with a port, reachable through a domain.
workerA long-running process with no public route. It can declare a TCP port that other services in the same environment reach at svc-SERVICE:PORT.
cronA process that runs on a schedule.
jobA process that runs to completion once for each release.
proxyForwards to an upstream address instead of running an image. Only a proxy service has these.

See Processes for commands, replicas, resources and health checks.

Variables

A variable is a key and value on a project, on an environment, or on one service in one environment. It can be sealed as a secret. A release merges them in ascending order of specificity: external resource, then project, then environment, then service. A more specific scope overrides a broader one. A value can reference another service's variable with ${{ SERVICE.KEY }}. See Variables.

Database services

A database service is a service created from a database template: PostgreSQL 18 or 16, Valkey 9 or 7, MySQL 8, or MongoDB 7. It has a worker process with a TCP port, a volume, and generated secret variables for the connection. PostgreSQL runs on CloudNativePG as a replicated cluster with health-checked failover, and is the only engine with readers and a read endpoint. Valkey, MySQL and MongoDB start with one instance.

A database service gets a daily dump backup only if the organization has an object store, and the schedule keeps the last 7 dumps. Without an object store, no backup is scheduled, and the console tells you so when you create the database. See Databases.

Volumes

A volume is persistent storage attached to a process. A release that touches a volume needs an explicit downtime acknowledgement, because the running release stops before the new one starts; a PostgreSQL database is exempt. On the default K3s storage class, a volume is a directory on the node's disk, so its size is a request that nothing enforces. See Volumes.

On this page