# CLI reference

`nebulactrl` is a command line client for the control plane REST API. It authenticates with an API token; see [API tokens and scopes](https://nebulactrl.com/docs/operations/teams.md) and [the API reference](https://nebulactrl.com/docs/reference/api.md).

## Global options

Manage NebulaCtrl projects, services, deployments and servers through the control plane REST API.

A <service> is a service ID or project/env/slug. Configuration lives in ~/.config/nebulactrl/config.json (override with NEBULACTRL_CONFIG; NEBULACTRL_URL and NEBULACTRL_TOKEN override its fields).

| Flag | Type | Default | Description |
|---|---|---|---|
| `--idempotency-key` | string |  | Idempotency-Key for mutating calls (default: random per invocation) |
| `--json` | bool |  | print machine-readable JSON |

Exit codes: `0` success, `1` failure, `2` wrong flags or arguments.

## Command list

| Command | Description |
|---|---|
| [`nebulactrl backups`](#nebulactrl-backups) | Back up and restore managed databases |
| [`nebulactrl backups create`](#nebulactrl-backups-create) | Back up a database now |
| [`nebulactrl backups destinations`](#nebulactrl-backups-destinations) | Manage backup destinations (S3-compatible buckets, server directories) |
| [`nebulactrl backups destinations add`](#nebulactrl-backups-destinations-add) | Add a backup destination |
| [`nebulactrl backups destinations ls`](#nebulactrl-backups-destinations-ls) | List backup destinations |
| [`nebulactrl backups destinations rm`](#nebulactrl-backups-destinations-rm) | Remove a backup destination |
| [`nebulactrl backups destinations test`](#nebulactrl-backups-destinations-test) | Write, read and delete a probe object through a server's agent |
| [`nebulactrl backups lock`](#nebulactrl-backups-lock) | Keep a backup forever (never pruned or deleted) |
| [`nebulactrl backups ls`](#nebulactrl-backups-ls) | List a database's backups |
| [`nebulactrl backups restore`](#nebulactrl-backups-restore) | Restore a backup into a new database (default) or in place |
| [`nebulactrl backups rm`](#nebulactrl-backups-rm) | Delete a backup and its stored object |
| [`nebulactrl backups schedules`](#nebulactrl-backups-schedules) | Manage recurring backups |
| [`nebulactrl backups schedules add`](#nebulactrl-backups-schedules-add) | Schedule recurring backups |
| [`nebulactrl backups schedules ls`](#nebulactrl-backups-schedules-ls) | List a database's backup schedules |
| [`nebulactrl backups schedules rm`](#nebulactrl-backups-schedules-rm) | Remove a backup schedule |
| [`nebulactrl backups unlock`](#nebulactrl-backups-unlock) | Allow retention to prune a backup again |
| [`nebulactrl build-settings`](#nebulactrl-build-settings) | Show or set the team's default build location and registry |
| [`nebulactrl databases`](#nebulactrl-databases) | Manage managed databases |
| [`nebulactrl databases create`](#nebulactrl-databases-create) | Create a managed database (staged until deployed) |
| [`nebulactrl databases engines`](#nebulactrl-databases-engines) | List the database engines and versions |
| [`nebulactrl databases info`](#nebulactrl-databases-info) | Show a database's engine, exports and last reported state |
| [`nebulactrl databases promote`](#nebulactrl-databases-promote) | Promote a read replica to primary (manual) |
| [`nebulactrl databases rebuild`](#nebulactrl-databases-rebuild) | Rebuild a replica, or a fenced old primary as a replica of the new primary |
| [`nebulactrl databases replicas`](#nebulactrl-databases-replicas) | Manage PostgreSQL read replicas |
| [`nebulactrl databases replicas add`](#nebulactrl-databases-replicas-add) | Add a read replica of a PostgreSQL primary |
| [`nebulactrl databases replicas ls`](#nebulactrl-databases-replicas-ls) | List the read replicas of a database and their lag |
| [`nebulactrl databases replicas rm`](#nebulactrl-databases-replicas-rm) | Remove a read replica |
| [`nebulactrl databases restore`](#nebulactrl-databases-restore) | Restore a database from a dump file on this machine |
| [`nebulactrl databases reveal`](#nebulactrl-databases-reveal) | Print a connection string (audited as secret.reveal) |
| [`nebulactrl databases rotate`](#nebulactrl-databases-rotate) | Rotate the database password and stage its consumers |
| [`nebulactrl databases upgrade`](#nebulactrl-databases-upgrade) | Plan (default) or run a database version upgrade |
| [`nebulactrl deployments`](#nebulactrl-deployments) | Inspect and roll back deployments |
| [`nebulactrl deployments cancel`](#nebulactrl-deployments-cancel) | Cancel a running deployment |
| [`nebulactrl deployments download-logs`](#nebulactrl-deployments-download-logs) | Download a deployment's build and deploy log as a file |
| [`nebulactrl deployments ls`](#nebulactrl-deployments-ls) | List the deployments of a service |
| [`nebulactrl deployments rollback`](#nebulactrl-deployments-rollback) | Redeploy the release of a previous deployment |
| [`nebulactrl deployments status`](#nebulactrl-deployments-status) | Show a deployment and its step timeline |
| [`nebulactrl domains`](#nebulactrl-domains) | Manage service domains |
| [`nebulactrl domains add`](#nebulactrl-domains-add) | Attach a hostname to a service |
| [`nebulactrl domains generate`](#nebulactrl-domains-generate) | Generate a domain from the server's base domain |
| [`nebulactrl domains ls`](#nebulactrl-domains-ls) | List a service's domains |
| [`nebulactrl domains rm`](#nebulactrl-domains-rm) | Remove a domain from a service |
| [`nebulactrl domains www`](#nebulactrl-domains-www) | Turn the www/apex redirect of a domain on or off |
| [`nebulactrl envs`](#nebulactrl-envs) | Manage environments |
| [`nebulactrl envs clone`](#nebulactrl-envs-clone) | Clone an environment into a new, non-production one |
| [`nebulactrl envs ls`](#nebulactrl-envs-ls) | List the environments of a project |
| [`nebulactrl import`](#nebulactrl-import) | Import a project from another tool |
| [`nebulactrl import compose`](#nebulactrl-import-compose) | Import a Docker Compose project as staged services |
| [`nebulactrl import coolify`](#nebulactrl-import-coolify) | Import projects, applications and databases from a Coolify v4 instance as staged services |
| [`nebulactrl instance`](#nebulactrl-instance) | Settings of the whole installation (instance admin only) |
| [`nebulactrl instance dashboard-access`](#nebulactrl-instance-dashboard-access) | Who may reach the dashboard and how its certificate is issued |
| [`nebulactrl instance dashboard-access get`](#nebulactrl-instance-dashboard-access-get) | Show the dashboard's allow list and certificate method |
| [`nebulactrl instance dashboard-access set`](#nebulactrl-instance-dashboard-access-set) | Change the dashboard's allow list and certificate method |
| [`nebulactrl login`](#nebulactrl-login) | Store the control plane URL and API token |
| [`nebulactrl members`](#nebulactrl-members) | Manage the members of your team |
| [`nebulactrl members invite`](#nebulactrl-members-invite) | Invite someone by email, or create a link invite |
| [`nebulactrl members ls`](#nebulactrl-members-ls) | List the members of the token's team |
| [`nebulactrl mesh`](#nebulactrl-mesh) | Manage the server mesh (a tailnet of your servers) |
| [`nebulactrl mesh check`](#nebulactrl-mesh-check) | Test whether the server's mesh node reaches the other servers |
| [`nebulactrl mesh disable`](#nebulactrl-mesh-disable) | Remove a server from the mesh |
| [`nebulactrl mesh enable`](#nebulactrl-mesh-enable) | Join a server to the mesh (adds one tagged tailnet device) |
| [`nebulactrl mesh links`](#nebulactrl-mesh-links) | Show the cross-server links of an environment: links, grants and routes |
| [`nebulactrl mesh reconcile`](#nebulactrl-mesh-reconcile) | Create (add) or clean up (repair) the cross-server links of an environment now |
| [`nebulactrl mesh reprovision`](#nebulactrl-mesh-reprovision) | Re-create the server's mesh node (new device and tailnet IP) |
| [`nebulactrl mesh service`](#nebulactrl-mesh-service) | Show what a service exposes on the mesh, which providers it reaches and who reaches it |
| [`nebulactrl mesh status`](#nebulactrl-mesh-status) | Show the mesh: nodes, links and the ACL state |
| [`nebulactrl projects`](#nebulactrl-projects) | Manage projects |
| [`nebulactrl projects create`](#nebulactrl-projects-create) | Create a project (with a production environment) |
| [`nebulactrl projects ls`](#nebulactrl-projects-ls) | List projects |
| [`nebulactrl projects update`](#nebulactrl-projects-update) | Rename a project or set where its services are built |
| [`nebulactrl servers`](#nebulactrl-servers) | Manage Docker hosts |
| [`nebulactrl servers enroll-token`](#nebulactrl-servers-enroll-token) | Create a one-time agent enrollment token |
| [`nebulactrl servers ls`](#nebulactrl-servers-ls) | List servers |
| [`nebulactrl servers revoke`](#nebulactrl-servers-revoke) | Revoke a server's agent identity |
| [`nebulactrl servers unrestricted`](#nebulactrl-servers-unrestricted) | Show, enable or disable the Unrestricted switch of a server (instance admin) |
| [`nebulactrl servers update`](#nebulactrl-servers-update) | Set a server's role and build settings |
| [`nebulactrl services`](#nebulactrl-services) | Manage services |
| [`nebulactrl services build-plan`](#nebulactrl-services-build-plan) | Preview how a git service would be built |
| [`nebulactrl services clone`](#nebulactrl-services-clone) | Clone a service (staged copy; secrets are copied sealed) |
| [`nebulactrl services create`](#nebulactrl-services-create) | Create a service (staged until deployed) |
| [`nebulactrl services deploy`](#nebulactrl-services-deploy) | Deploy a service |
| [`nebulactrl services deploy-hook`](#nebulactrl-services-deploy-hook) | Show, enable, disable or rotate a service's deploy hook |
| [`nebulactrl services docker`](#nebulactrl-services-docker) | Show or set a service's Docker options (staged until the next deployment) |
| [`nebulactrl services download-logs`](#nebulactrl-services-download-logs) | Download a service's stored runtime logs as a file |
| [`nebulactrl services logs`](#nebulactrl-services-logs) | Show runtime logs of a service |
| [`nebulactrl services ls`](#nebulactrl-services-ls) | List the services of an environment |
| [`nebulactrl services maintenance`](#nebulactrl-services-maintenance) | Put a service into maintenance mode, or take it out |
| [`nebulactrl services move`](#nebulactrl-services-move) | Move a service to another environment (staged until the next deploy) |
| [`nebulactrl services restart`](#nebulactrl-services-restart) | Restart a service's container |
| [`nebulactrl services run`](#nebulactrl-services-run) | Run a one-off command in a container of the service's image |
| [`nebulactrl services scale`](#nebulactrl-services-scale) | Set the number of replicas or turn on autoscaling |
| [`nebulactrl services shell`](#nebulactrl-services-shell) | Open an interactive shell in a service's container |
| [`nebulactrl services update`](#nebulactrl-services-update) | Set where and how a service is built |
| [`nebulactrl tasks`](#nebulactrl-tasks) | Cron tasks and their runs |
| [`nebulactrl tasks create`](#nebulactrl-tasks-create) | Schedule a recurring command |
| [`nebulactrl tasks logs`](#nebulactrl-tasks-logs) | Print the output of a run (follows a run that is still active) |
| [`nebulactrl tasks ls`](#nebulactrl-tasks-ls) | List a service's cron tasks |
| [`nebulactrl tasks rm`](#nebulactrl-tasks-rm) | Delete a cron task and its run history |
| [`nebulactrl tasks run`](#nebulactrl-tasks-run) | Run a cron task now and follow its output |
| [`nebulactrl tasks runs`](#nebulactrl-tasks-runs) | Run history of a service's tasks and one-off commands |
| [`nebulactrl tasks update`](#nebulactrl-tasks-update) | Change a cron task's schedule or time zone |
| [`nebulactrl teams`](#nebulactrl-teams) | Manage teams |
| [`nebulactrl teams create`](#nebulactrl-teams-create) | Create a team (you become its owner; needs an admin-scope token) |
| [`nebulactrl teams ls`](#nebulactrl-teams-ls) | List your teams and the saved token per team |
| [`nebulactrl teams switch`](#nebulactrl-teams-switch) | Use the saved token of another team |
| [`nebulactrl templates`](#nebulactrl-templates) | Browse and install one-click templates |
| [`nebulactrl templates install`](#nebulactrl-templates-install) | Install a template as staged services (or deploy right away) |
| [`nebulactrl templates installed`](#nebulactrl-templates-installed) | List the template stacks of an environment |
| [`nebulactrl templates ls`](#nebulactrl-templates-ls) | List catalog templates |
| [`nebulactrl templates plan`](#nebulactrl-templates-plan) | Preflight an install (changes nothing) |
| [`nebulactrl templates rm`](#nebulactrl-templates-rm) | Delete a template stack |
| [`nebulactrl templates show`](#nebulactrl-templates-show) | Show a template: services, inputs and licence |
| [`nebulactrl templates update`](#nebulactrl-templates-update) | Show what a newer template revision changes, or stage it (--apply) |
| [`nebulactrl vars`](#nebulactrl-vars) | Manage service environment variables |
| [`nebulactrl vars history`](#nebulactrl-vars-history) | Show a variable's versions (secrets show a fingerprint only) |
| [`nebulactrl vars ls`](#nebulactrl-vars-ls) | List variables (secret values are never shown) |
| [`nebulactrl vars rm`](#nebulactrl-vars-rm) | Delete variables (staged until the next deploy) |
| [`nebulactrl vars rotate`](#nebulactrl-vars-rotate) | Replace a generated variable's value (staged, never deployed) |
| [`nebulactrl vars set`](#nebulactrl-vars-set) | Set variables (staged until the next deploy) |
| [`nebulactrl vars shared`](#nebulactrl-vars-shared) | Manage shared variables of the team (@team), a project (<project>) or an environment (<project>/<env>) |
| [`nebulactrl vars shared ls`](#nebulactrl-vars-shared-ls) | List shared variables |
| [`nebulactrl vars shared rm`](#nebulactrl-vars-shared-rm) | Delete shared variables |
| [`nebulactrl vars shared rotate`](#nebulactrl-vars-shared-rotate) | Replace a generated shared variable (staged, never deployed) |
| [`nebulactrl vars shared set`](#nebulactrl-vars-shared-set) | Set shared variables (restages the services that use them) |
| [`nebulactrl vars shared share`](#nebulactrl-vars-shared-share) | Stage KEY=${{shared.KEY}} on services |

## nebulactrl backups

Back up and restore managed databases.

```
nebulactrl backups
```

### nebulactrl backups create

Back up a database now.

```
nebulactrl backups create <database> --destination <name|id> [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--destination` | string |  | destination name or id |
| `--timeout` | duration | `2h0m0s` | give up waiting after this long (with --wait) |
| `--wait` | bool |  | wait for the backup to finish; exit non-zero unless it succeeded |

### nebulactrl backups destinations

Manage backup destinations (S3-compatible buckets, server directories).

```
nebulactrl backups destinations
```

#### nebulactrl backups destinations add

Add a backup destination.

```
nebulactrl backups destinations add --name <n> --kind s3|local [flags]
```

The S3 secret key is never taken as an argument (it would show in process lists): pass --secret-key-file
(`-` reads standard input) or set NEBULACTRL_BACKUP_SECRET_KEY.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--access-key` | string |  | S3 access key id |
| `--bucket` | string |  | S3 bucket |
| `--endpoint` | string |  | S3 endpoint URL (empty: AWS) |
| `--kind` | string |  | s3 or local |
| `--local-dir` | string |  | local destinations: sub-directory of the agent's backup directory |
| `--name` | string |  | destination name |
| `--path-style` | bool |  | path-style addressing (MinIO, SeaweedFS, Garage) |
| `--prefix` | string |  | key prefix |
| `--region` | string |  | S3 region |
| `--secret-key-file` | string |  | file holding the S3 secret key (`-` for stdin) |

#### nebulactrl backups destinations ls

List backup destinations.

```
nebulactrl backups destinations ls
```

#### nebulactrl backups destinations rm

Remove a backup destination.

```
nebulactrl backups destinations rm <name|id>
```

#### nebulactrl backups destinations test

Write, read and delete a probe object through a server's agent.

```
nebulactrl backups destinations test <name|id> --server <server-id> [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--server` | string |  | server whose agent runs the test |

### nebulactrl backups lock

Keep a backup forever (never pruned or deleted).

```
nebulactrl backups lock <backup-id>
```

### nebulactrl backups ls

List a database's backups.

```
nebulactrl backups ls <database>
```

### nebulactrl backups restore

Restore a backup into a new database (default) or in place.

```
nebulactrl backups restore <backup-id> [flags]
```

By default the backup is restored into a NEW sibling database with fresh credentials; the original is
untouched. With --in-place the database is overwritten after a safety backup; --confirm must equal its slug.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--confirm` | string |  | the database's slug (required with --in-place) |
| `--in-place` | bool |  | overwrite the database instead of restoring into a new one |
| `--name` | string |  | name of the new database |
| `--server` | string |  | server id for the new database |
| `--timeout` | duration | `2h0m0s` | give up waiting after this long (with --wait) |
| `--wait` | bool |  | wait for the restore to finish; exit non-zero unless it succeeded |

### nebulactrl backups rm

Delete a backup and its stored object.

```
nebulactrl backups rm <backup-id>
```

### nebulactrl backups schedules

Manage recurring backups.

```
nebulactrl backups schedules
```

#### nebulactrl backups schedules add

Schedule recurring backups.

```
nebulactrl backups schedules add <database> --destination <name|id> --cron "0 3 * * *" [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--cron` | string |  | 5-field cron expression or @daily/@hourly/… |
| `--destination` | string |  | destination name or id |
| `--keep` | int | `7` | keep the newest N backups (0 = no limit) |
| `--keep-days` | int |  | delete backups older than N days (0 = never) |
| `--timezone` | string | `UTC` | IANA timezone |

#### nebulactrl backups schedules ls

List a database's backup schedules.

```
nebulactrl backups schedules ls <database>
```

#### nebulactrl backups schedules rm

Remove a backup schedule.

```
nebulactrl backups schedules rm <schedule-id>
```

### nebulactrl backups unlock

Allow retention to prune a backup again.

```
nebulactrl backups unlock <backup-id>
```

## nebulactrl build-settings

Show or set the team's default build location and registry.

```
nebulactrl build-settings [--build-location target|build-server] [--registry <id|none>] [flags]
```

Without flags, prints the team default. With flags (administrators only), replaces it. Projects and services can
override it. When no usable build server or registry exists a build falls back to the target server.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--build-location` | string |  | target or build-server |
| `--registry` | string |  | default registry ID (none clears) |

## nebulactrl databases

Manage managed databases.

```
nebulactrl databases
```

### nebulactrl databases create

Create a managed database (staged until deployed).

```
nebulactrl databases create --project <project> --env <env> --engine <engine> [--version <v>] [--name <name>] [--flavor postgis] [--database <db>] [--server <server>] [--accept-license] [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--accept-license` | bool |  | acknowledge the licence of a source-available engine (MongoDB, Redis) |
| `--database` | string |  | database name (default: app) |
| `--engine` | string |  | postgres, mysql, mariadb, valkey, redis, mongodb or clickhouse |
| `--env` | string |  | environment ID, slug or name |
| `--flavor` | string |  | image variant, e.g. postgis |
| `--name` | string |  | display name (default: the engine name) |
| `--project` | string |  | project ID, slug or name |
| `--server` | string |  | target server ID or name |
| `--version` | string |  | major version (default: the engine's default) |

### nebulactrl databases engines

List the database engines and versions.

```
nebulactrl databases engines
```

### nebulactrl databases info

Show a database's engine, exports and last reported state.

```
nebulactrl databases info <service>
```

### nebulactrl databases promote

Promote a read replica to primary (manual).

```
nebulactrl databases promote <replica> [--yes] [--accept-data-loss] [flags]
```

Prints the promotion plan. With --yes it promotes: a switchover while the old primary is reachable (it is frozen, stopped and fenced; no data is lost) or a forced promote otherwise (needs --accept-data-loss: what the replica had not received is lost). The old primary is fenced and never runs as a primary again. Variables that reference it are rewritten as staged changes. Manual: NebulaCtrl does not detect failures or switch automatically.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--accept-data-loss` | bool |  | accept losing what the replica had not received (forced promote) |
| `--yes` | bool |  | promote |

### nebulactrl databases rebuild

Rebuild a replica, or a fenced old primary as a replica of the new primary.

```
nebulactrl databases rebuild <replica-or-fenced-primary> [--follow <new-primary>] [flags]
```

Clones the primary again into a new data volume; the old volume is kept until it is deleted.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--follow` | string |  | the new primary a fenced old primary should follow (default: the replica that was promoted) |

### nebulactrl databases replicas

Manage PostgreSQL read replicas.

```
nebulactrl databases replicas
```

#### nebulactrl databases replicas add

Add a read replica of a PostgreSQL primary.

```
nebulactrl databases replicas add <primary> --server <server> [--name <name>] [--dry-run] [--accept-mesh-changes] [flags]
```

Creates a read replica service in the primary's environment and clones the primary into it. The replica runs on the primary's server or, with the server mesh enabled on both, on another server. Replication is asynchronous and manual: nothing is detected or switched automatically. --dry-run prints the plan only.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--accept-mesh-changes` | bool |  | confirm that the replica adds tailnet devices |
| `--dry-run` | bool |  | only print the plan |
| `--name` | string |  | display name (default: <primary>-replica-<n>) |
| `--server` | string |  | server ID or name the replica runs on |

#### nebulactrl databases replicas ls

List the read replicas of a database and their lag.

```
nebulactrl databases replicas ls <primary-or-replica>
```

#### nebulactrl databases replicas rm

Remove a read replica.

```
nebulactrl databases replicas rm <replica> --yes [flags]
```

Deletes the replica's container and data volume, drops its slot, role and pg_hba.conf line on the primary and releases its mesh link.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--yes` | bool |  | confirm the removal |

### nebulactrl databases restore

Restore a database from a dump file on this machine.

```
nebulactrl databases restore <database> --file <dump> [--name <name>] [--server <server>] [--in-place --confirm <slug> [--destination <dest>]] [flags]
```

Uploads a dump file and restores it into a managed database: a pg_dump file (custom -Fc, tar -Ft or plain SQL, optionally
.gz), a mysqldump / mariadb-dump SQL file (optionally .gz) or a mongodump --archive file. The format is detected from the file.
The file is streamed through the control plane to the server's agent; nothing is stored on the way, and the default limit is 5 GiB.

By default the dump is restored into a NEW sibling database with fresh credentials (the original is untouched): point your
apps at it when you are satisfied. With --in-place the database's data is replaced after a safety backup; --confirm must
equal its slug, and --destination names the backup destination of the safety backup (default: the one of its schedule).

Examples:

```sh
nebulactrl databases restore shop/production/postgres --file shop.pgdump
  nebulactrl databases restore shop/production/postgres --file shop.sql.gz --in-place --confirm postgres --destination s3
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--confirm` | string |  | the database's slug (required with --in-place) |
| `--destination` | string |  | backup destination (id or name) of the safety backup (--in-place) |
| `--file` | string |  | the dump file to restore (required) |
| `--in-place` | bool |  | replace the database's data instead of restoring into a new database |
| `--name` | string |  | name of the new database |
| `--server` | string |  | server id for the new database |
| `--timeout` | duration | `2h0m0s` | give up waiting for the new database, and again for the restore, after this long |
| `--wait` | bool | `true` | wait for the restore to finish; exit non-zero unless it succeeded (--wait=false returns once the file is uploaded) |

### nebulactrl databases reveal

Print a connection string (audited as secret.reveal).

```
nebulactrl databases reveal <service> [--key DATABASE_URL] [flags]
```

Prints one derived connection variable in plain text to stdout. The action is recorded in the audit log and needs the deployments:write scope.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--key` | string |  | export to reveal (default: the connection URL) |

### nebulactrl databases rotate

Rotate the database password and stage its consumers.

```
nebulactrl databases rotate <service> [--dry-run] [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--dry-run` | bool |  | only print the plan |

### nebulactrl databases upgrade

Plan (default) or run a database version upgrade.

```
nebulactrl databases upgrade <service> <version> [--yes] [flags]
```

Prints the upgrade plan. With --yes it runs the upgrade: in-place engines stage the new image; PostgreSQL majors are converted with pg_upgrade into a new volume and then staged. Take a backup first.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--yes` | bool |  | apply the upgrade |

## nebulactrl deployments

Inspect and roll back deployments.

```
nebulactrl deployments
```

### nebulactrl deployments cancel

Cancel a running deployment.

```
nebulactrl deployments cancel <deployment-id>
```

Cancels a deployment at whatever step it has reached. Before the agent started it the deployment ends as canceled at once.
Once the agent runs it, the agent is asked to abort: a build is killed, the new containers are removed, routes are restored and a stopped previous release is started again, so the current release keeps serving.
The deployment ends as canceled when the agent reports back (check with `deployments status`). Once the new release is live it is too late and the deployment finishes.

### nebulactrl deployments download-logs

Download a deployment's build and deploy log as a file.

```
nebulactrl deployments download-logs <deployment-id> [flags]
```

Writes the deployment's persisted lines (build, deploy and runtime streams; at most 10,000) in the order
they were recorded, as plain text (`<time> [<stream>] <line>`) or NDJSON. Secret values are masked on the
server. --streams all adds the agent's verbose debug trace.

Examples:

```sh
nebulactrl deployments download-logs 6f1c0d5e-… -o build.log
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--format` | string | `txt` | file format: txt or ndjson |
| `--from` | string |  | only lines at or after this time: RFC 3339, a date, or a duration ago (24h) |
| `-o, --output` | string |  | write to this file instead of stdout (created with mode 0600) |
| `--streams` | string |  | all, or a comma-separated list of build, deploy, runtime, debug (default: build, deploy, runtime) |
| `--to` | string |  | only lines before this time (same forms as --from) |

### nebulactrl deployments ls

List the deployments of a service.

```
nebulactrl deployments ls <service>
```

### nebulactrl deployments rollback

Redeploy the release of a previous deployment.

```
nebulactrl deployments rollback <deployment-id> [flags]
```

Creates a new deployment that points at the release of the given deployment.
Application image and configuration only. Databases, volumes and external services are not rolled back.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--timeout` | duration | `30m0s` | give up waiting after this long (with --wait) |
| `--wait` | bool |  | wait for the rollback to finish; exit non-zero unless it succeeded |

### nebulactrl deployments status

Show a deployment and its step timeline.

```
nebulactrl deployments status <deployment-id>
```

## nebulactrl domains

Manage service domains.

```
nebulactrl domains
```

### nebulactrl domains add

Attach a hostname to a service.

```
nebulactrl domains add <service> <hostname> [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--component` | string |  | Compose stacks: the component (compose service) the domain routes to |
| `--port` | int |  | target port (default: the service port; Compose stacks: the container port, optional when the component declares one) |
| `--www-redirect` | bool |  | also route the www/apex counterpart and 301-redirect it to this hostname (needs proxy:write; both hostnames get certificates) |

### nebulactrl domains generate

Generate a domain from the server's base domain.

```
nebulactrl domains generate <service> [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--component` | string |  | Compose stacks: the component the generated domain routes to |

### nebulactrl domains ls

List a service's domains.

```
nebulactrl domains ls <service>
```

### nebulactrl domains rm

Remove a domain from a service.

```
nebulactrl domains rm <service> <hostname|domain-id>
```

### nebulactrl domains www

Turn the www/apex redirect of a domain on or off.

```
nebulactrl domains www <service> <hostname|domain-id> <on|off>
```

`on` routes the www/apex counterpart of the domain (www.<host>, or the host without its www.) and answers it with
a 301 redirect to the domain, keeping the path and query. Both hostnames get certificates and each needs its own
DNS record. `off` removes the redirect. The change is staged until the next deploy. Needs proxy:write; the domain
must be a whole-host serve domain without a path prefix.

Examples:

```sh
nebulactrl domains www acme/production/web example.com on
```

## nebulactrl envs

Manage environments.

```
nebulactrl envs
```

### nebulactrl envs clone

Clone an environment into a new, non-production one.

```
nebulactrl envs clone <env> --project <project> --name <name> [--domains drop|suffix] [--dry-run] [flags]
```

Create a new environment with a staged copy of every service of <env>: configuration, variables, the environment's shared variables, volume definitions, links and the canvas layout. Slugs are kept, so ${{postgres.DATABASE_URL}} in a cloned service points at the cloned postgres. Secrets are copied sealed and generated values are generated again. Databases are new and empty (restore a dump into them); volumes are new and empty. Nothing runs until the services are deployed.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--domain-suffix` | string |  | suffix for --domains suffix (default: -copy in the same environment, -<environment slug> otherwise) |
| `--domains` | string | `drop` | domains of the clone: drop (attach new ones later) or suffix (suffix the first label of each hostname) |
| `--dry-run` | bool |  | show what the clone would do and change nothing |
| `--name` | string |  | name of the new environment |
| `--project` | string |  | project ID, slug or name |
| `--server` | string |  | place the clone on this server (ID or name; default: the source's server) |

### nebulactrl envs ls

List the environments of a project.

```
nebulactrl envs ls --project <project> [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--project` | string |  | project ID, slug or name |

## nebulactrl import

Import a project from another tool.

```
nebulactrl import
```

### nebulactrl import compose

Import a Docker Compose project as staged services.

```
nebulactrl import compose <docker-compose.yml|-> --project <p> --env <e> --server <s> [flags]
```

Reads a Compose file (a local file, stdin with -, or a file in a git repository with --repo) and stages one NebulaCtrl service per
Compose service in the environment, grouped on the canvas and linked in deploy order. Nothing is deployed unless you pass --deploy.

Files next to the Compose file (.env, env_file entries, bind-mounted config files) are read from disk. Host names of other
services in variables are rewritten to references, and official database images become managed databases unless you turn that off.
Use --plan to review without changing anything. Per-service decisions are written as <service>=<value> or <service>.<KEY>.

With --as-stack the whole file becomes ONE service (a native Compose stack): the file is kept as written, the .env entries become the
stack's variables (used for ${VAR} interpolation only), and domains are suggested per component. A stack runs under the safe
allow-list (no privileged mode, host network, devices, Docker socket or host bind mounts, no build:) unless an instance admin made
the server unrestricted; violations are listed and block the import. In stack mode --secret, --not-secret and
--skip-var take the variable name (<KEY>); --domain and --port take the component name.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--as-stack` | bool |  | run the whole file as one native Compose stack (one service, the file kept as written) instead of splitting it into services |
| `--branch` | string |  | branch of --repo or --repo-url (default: the default branch) |
| `--connection` | string |  | git connection ID or name for --repo |
| `--convert-bind` | stringArray |  | <service>=<container path>: turn a directory bind mount into a named volume (repeatable) |
| `--deploy` | bool |  | deploy the new services right away |
| `--domain` | stringArray |  | <service>=<hostname>\|auto\|off: set the domain (repeatable) |
| `--env` | string |  | environment ID, slug or name |
| `--env-file` | string |  | the .env file for ${VAR} interpolation (default: .env next to the Compose file) |
| `--exclude` | stringArray |  | <service>: do not import this service (repeatable) |
| `--file` | stringArray |  | supply a referenced file: <path as written in Compose>=<local file> (repeatable) |
| `--git` | stringArray |  | <service>=<https url>[#branch]: build a service from this repository (repeatable) |
| `--image` | stringArray |  | <service>=<image>: pull this image instead of building (repeatable) |
| `--include` | stringArray |  | <service>: also import a service that Compose gates behind a profile (repeatable) |
| `--managed` | stringArray |  | <service>: use a managed database (repeatable; needed to accept the licence of Redis and MongoDB) |
| `--name` | string |  | canvas group title (default: the Compose project name) |
| `--no-managed` | stringArray |  | <service>: keep an official database image as a plain image service (repeatable) |
| `--no-rewrite` | stringArray |  | <service>.<KEY>: keep the host names in the variable as they are (repeatable) |
| `--not-secret` | stringArray |  | <service>.<KEY>: store the variable in plain text (repeatable) |
| `--path` | string |  | path of the Compose file in the repository (default: docker-compose.yml, compose.yaml, ...) |
| `--plan` | bool |  | show what would be imported and change nothing |
| `--port` | stringArray |  | <service>=<port>: the service port (repeatable) |
| `--project` | string |  | project ID, slug or name |
| `--publish` | stringArray |  | <service>=<port>/<tcp\|udp>: publish a container port through a TCP/UDP route (repeatable) |
| `--repo` | string |  | read the Compose file from owner/name of a git connection (with --connection) |
| `--repo-url` | string |  | read the Compose file from a public github.com or gitlab.com repository URL |
| `--secret` | stringArray |  | <service>.<KEY>: store the variable as a secret (repeatable) |
| `--server` | string |  | server ID or name the services run on |
| `--skip-var` | stringArray |  | <service>.<KEY>: do not import the variable (repeatable) |

### nebulactrl import coolify

Import projects, applications and databases from a Coolify v4 instance as staged services.

```
nebulactrl import coolify --url <coolify url> --server <server> [flags]
```

Reads a Coolify instance through its API and stages the same projects and environments here: applications become image or git services
(Dockerfile builds stay Dockerfile builds, Nixpacks becomes Railpack), databases become managed databases of the same engine and version,
domains, health checks, resource limits, custom Docker options, deployment commands and variables come along. Variables that point at a Coolify
database or application are rewritten to ${{service.EXPORT}} references; credentials, locked values and secret-looking keys are stored as secrets.
Nothing is deployed unless you pass --deploy, and database and volume DATA is never copied (the plan prints the follow-up commands).

The Coolify API token needs the `read` and `read:sensitive` abilities (Keys & Tokens → API tokens in Coolify); read:sensitive is what returns
variable values and custom Docker options. The token is read from --token-env (default COOLIFY_TOKEN), --token-file or --token, sent to your
NebulaCtrl server for this one request, and never stored or printed. Registry pull credentials cannot be read from Coolify: give them with
--registry-user and --registry-token-env.

Use --plan (or --dry-run) to review without changing anything: it lists every resource, its variables by key (never values), the rewritten
references and everything that is not imported. Per-resource decisions name the resource by its Coolify name or UUID, variables as <resource>.<KEY>.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--deploy` | bool |  | deploy the new services right away (default: everything stays staged) |
| `--domain` | stringArray |  | <resource>/<coolify host>=<new host>\|off: change or drop a domain (repeatable) |
| `--dry-run` | bool |  | same as --plan |
| `--engine-version` | stringArray |  | <database>=<version>: managed database version (repeatable) |
| `--exclude` | stringArray |  | <resource>: do not import this application or database (repeatable) |
| `--git-connection` | string |  | git connection ID or name used to clone private GitHub/GitLab repositories |
| `--include` | stringArray |  | <resource>: import it although it is off by default; for Redis and MongoDB this accepts their source-available licence (repeatable) |
| `--into` | stringArray |  | <coolify project>=<project>: import into an existing project instead of creating one (repeatable) |
| `--kind` | stringArray |  | <resource>=<app\|worker> (repeatable) |
| `--no-rewrite` | stringArray |  | <resource>.<KEY>: keep host names and credentials of Coolify resources in the value as they are (repeatable) |
| `--not-secret` | stringArray |  | <resource>.<KEY>: store the variable in plain text (repeatable) |
| `--plan` | bool |  | show what would be imported and change nothing |
| `--port` | stringArray |  | <resource>=<port>: service port; 0 makes it a worker without a port (repeatable) |
| `--registry-token-env` | stringArray |  | <registry host>=<ENV_VAR>: environment variable with that registry's token or password (repeatable) |
| `--registry-user` | stringArray |  | <registry host>=<username>: pull credential user, for example ghcr.io=octocat (repeatable) |
| `--rename` | stringArray |  | <resource>=<name>: service name (repeatable) |
| `--rename-project` | stringArray |  | <coolify project>=<name>: name of the new project (default: the same name, plus " (Coolify)" when it exists) |
| `--secret` | stringArray |  | <resource>.<KEY>: store the variable as a secret (repeatable) |
| `--server` | string |  | server ID or name the services run on (required to import) |
| `--set` | stringArray |  | <resource>.<KEY>=<value>: supply the value of a locked variable (visible in the process list: prefer --set-env) (repeatable) |
| `--set-env` | stringArray |  | <resource>.<KEY>=<ENV_VAR>: supply the value of a locked variable from an environment variable (repeatable) |
| `--skip-project` | stringArray |  | <coolify project>: do not import this project (repeatable) |
| `--skip-var` | stringArray |  | <resource>.<KEY>: do not import the variable (repeatable) |
| `--token` | string |  | Coolify API token (visible in the process list: prefer --token-env or --token-file) |
| `--token-env` | string | `COOLIFY_TOKEN` | environment variable that holds the Coolify API token |
| `--token-file` | string |  | read the Coolify API token from this file (- for stdin) |
| `--url` | string |  | address of the Coolify instance (default: $COOLIFY_URL) |

## nebulactrl instance

Settings of the whole installation (instance admin only).

```
nebulactrl instance
```

### nebulactrl instance dashboard-access

Who may reach the dashboard and how its certificate is issued.

```
nebulactrl instance dashboard-access
```

#### nebulactrl instance dashboard-access get

Show the dashboard's allow list and certificate method.

```
nebulactrl instance dashboard-access get
```

#### nebulactrl instance dashboard-access set

Change the dashboard's allow list and certificate method.

```
nebulactrl instance dashboard-access set [--allow <cidr>]... [--tailnet-only | --clear-allow] [--dns-resolver <provider> | --http-01] [--confirm-lockout] [flags]
```

Restricts who may reach the dashboard's hostname (an IP allow list on its route) and chooses how its certificate is issued.
Settings you do not name stay as they are. --allow replaces the list (repeat it or separate CIDRs with commas; IPv4 and IPv6).
--tailnet-only is the list 100.64.0.0/10, fd7a:115c:a1e0::/48. Agents on other servers and webhooks reach the control plane
through the same hostname, so keep their addresses in the list.
The change is refused (409 dashboard_lockout) when the list leaves out the address you are connecting from, unless --confirm-lockout is set.
--dns-resolver needs a resolver of that provider on the control-plane server (Servers, Proxy). Run from the host with an SSH tunnel to recover from a lock-out.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--allow` | stringSlice |  | CIDR or address allowed to reach the dashboard; replaces the list (repeatable, comma separated) |
| `--clear-allow` | bool |  | lift the restriction: everybody may reach the dashboard |
| `--confirm-lockout` | bool |  | save even though the list excludes the address you are connecting from |
| `--dns-resolver` | string |  | issue the certificate through this DNS-01 provider (for example cloudflare) |
| `--http-01` | bool |  | issue the certificate automatically over HTTP-01 |
| `--tailnet-only` | bool |  | allow only Tailscale addresses (100.64.0.0/10, fd7a:115c:a1e0::/48) |

## nebulactrl login

Store the control plane URL and API token.

```
nebulactrl login --url <url> --token <token> [flags]
```

Verifies the token against GET /me and writes ~/.config/nebulactrl/config.json (mode 0600).
Pass --token - to read the token from stdin; NEBULACTRL_TOKEN is used when --token is omitted.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--token` | string |  | API token (nct_…); - reads stdin |
| `--url` | string |  | control plane URL, e.g. https://nebula.example.com |

## nebulactrl members

Manage the members of your team.

```
nebulactrl members
```

### nebulactrl members invite

Invite someone by email, or create a link invite.

```
nebulactrl members invite [--email <address>] --role <role> [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--email` | string |  | mail the invite to this address (single use); omit for a link invite |
| `--expires-in-days` | int64 |  | validity in days (default 7) |
| `--max-uses` | int64 |  | link invites: how many people may use it (default 1) |
| `--role` | string |  | owner, admin, developer or viewer |

### nebulactrl members ls

List the members of the token's team.

```
nebulactrl members ls
```

## nebulactrl mesh

Manage the server mesh (a tailnet of your servers).

```
nebulactrl mesh
```

### nebulactrl mesh check

Test whether the server's mesh node reaches the other servers.

```
nebulactrl mesh check <server>
```

### nebulactrl mesh disable

Remove a server from the mesh.

```
nebulactrl mesh disable <server>
```

### nebulactrl mesh enable

Join a server to the mesh (adds one tagged tailnet device).

```
nebulactrl mesh enable <server> [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--accept-mesh-changes` | bool |  | confirm that this adds tailnet devices |
| `--dry-run` | bool |  | print the plan without changing anything |

### nebulactrl mesh links

Show the cross-server links of an environment: links, grants and routes.

```
nebulactrl mesh links <project/env>
```

### nebulactrl mesh reconcile

Create (add) or clean up (repair) the cross-server links of an environment now.

```
nebulactrl mesh reconcile <project/env> [flags]
```

Mode add creates every link the environment's variable references and canvas links need. It adds tailnet devices (tagged devices may be billed by Tailscale), so it needs --accept-mesh-changes.
Mode repair only removes grants whose source is gone; it never adds a device.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--accept-mesh-changes` | bool |  | confirm the tailnet devices mode add creates |
| `--mode` | string | `add` | add or repair |

### nebulactrl mesh reprovision

Re-create the server's mesh node (new device and tailnet IP).

```
nebulactrl mesh reprovision <server>
```

### nebulactrl mesh service

Show what a service exposes on the mesh, which providers it reaches and who reaches it.

```
nebulactrl mesh service <service>
```

### nebulactrl mesh status

Show the mesh: nodes, links and the ACL state.

```
nebulactrl mesh status
```

## nebulactrl projects

Manage projects.

```
nebulactrl projects
```

### nebulactrl projects create

Create a project (with a production environment).

```
nebulactrl projects create <name> [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--description` | string |  | project description |

### nebulactrl projects ls

List projects.

```
nebulactrl projects ls
```

### nebulactrl projects update

Rename a project or set where its services are built.

```
nebulactrl projects update <project> [--name <n>] [--description <d>] [--build-location inherit|target|build-server [--build-server <server>] [--registry <id>]] [flags]
```

--build-location overrides the team default for every git service of the project (a service can override it again).
The placement is replaced as a unit: --build-server pins a build server and --registry names the registry; an
omitted one is cleared (the control plane picks a build server, the team default registry applies).

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--build-location` | string |  | inherit, target or build-server |
| `--build-server` | string |  | pin the build server (ID or name) |
| `--description` | string |  | new description |
| `--name` | string |  | new name |
| `--registry` | string |  | registry ID the builds are pushed to |

## nebulactrl servers

Manage Docker hosts.

```
nebulactrl servers
```

### nebulactrl servers enroll-token

Create a one-time agent enrollment token.

```
nebulactrl servers enroll-token --name <name> [flags]
```

Registers a pending server and prints the one-hour, single-use enrollment token together with the
command that installs the agent on the host. The token is shown once.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--acme-email` | string |  | email for Let's Encrypt registration |
| `--base-domain` | string |  | base domain for generated hostnames |
| `--name` | string |  | server name |
| `--public-ip` | string |  | public IP, used for DNS checks and sslip.io domains |

### nebulactrl servers ls

List servers.

```
nebulactrl servers ls
```

### nebulactrl servers revoke

Revoke a server's agent identity.

```
nebulactrl servers revoke <server-id|name>
```

Disconnects the agent and cancels its pending commands. The agent must re-enroll to come back.

### nebulactrl servers unrestricted

Show, enable or disable the Unrestricted switch of a server (instance admin).

```
nebulactrl servers unrestricted <server-id|name> [--on --confirm <name> | --off] [flags]
```

By default Compose stacks and services run under safe allow-lists. An unrestricted server lifts them for everything on it:
privileged mode, host networking, devices, GPUs, a custom runtime, the host PID namespace, unconfined seccomp or AppArmor,
NET_ADMIN, SYS_ADMIN, the Docker socket and host bind mounts. Anyone who can deploy there can take over the server, so only
the instance admin can switch it, and enabling needs --confirm with the server's exact name. Disabling does not stop running
containers; the next deploy of something that needs it fails. Without --on or --off, prints the current state.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--confirm` | string |  | the server's exact name (required with --on) |
| `--off` | bool |  | make the server restricted again |
| `--on` | bool |  | make the server unrestricted |

### nebulactrl servers update

Set a server's role and build settings.

```
nebulactrl servers update <server-id|name> [--role deployments|builds|both] [--max-builds <n>] [--allow-emulation[=false]] [--allow-previews[=false]] [flags]
```

Roles: `deployments` runs services (the default), `builds` only builds images for other servers and pushes them
to a registry, `both` does both. A build server needs an agent that can build and push (`build.push`).
--max-builds caps parallel builds (1-16, default 2; more queue). --allow-emulation lets it build for another
CPU architecture (slow). --allow-previews lets pull request previews build on it (off: previews build on their own server).

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--allow-emulation` | bool |  | allow cross-architecture builds through emulation |
| `--allow-previews` | bool |  | let pull request previews build here |
| `--max-builds` | int |  | parallel builds on this server (1-16) |
| `--role` | string |  | deployments, builds or both |

## nebulactrl services

Manage services.

```
nebulactrl services
```

### nebulactrl services build-plan

Preview how a git service would be built.

```
nebulactrl services build-plan <service>
```

Asks the service's server to clone the branch head and report the build method (Dockerfile, Railpack or a
starter Dockerfile), the detected providers and the start command. Nothing is built or deployed.

### nebulactrl services clone

Clone a service (staged copy; secrets are copied sealed).

```
nebulactrl services clone <service> [--env <env> [--project <project>]] [--name <name>] [--domains drop|suffix] [--dry-run] [flags]
```

Clone a service into the same or another environment. The clone is staged: nothing runs until it is deployed.

It gets the configuration, variables (secrets stay secret, generated values are generated again), volume definitions (new, empty volumes) and, in the same environment, the source's links. A managed database is created new and empty: restore a dump into it. Domains are dropped by default or cloned with a suffix.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--domain-suffix` | string |  | suffix for --domains suffix (default: -copy in the same environment, -<environment slug> otherwise) |
| `--domains` | string | `drop` | domains of the clone: drop (attach new ones later) or suffix (suffix the first label of each hostname) |
| `--dry-run` | bool |  | show what the clone would do and change nothing |
| `--env` | string |  | environment of the clone (ID, slug or name; default: the source's environment) |
| `--name` | string |  | name of the clone (default: "<name> copy" in the same environment) |
| `--project` | string |  | project of --env (default: the source's project) |
| `--server` | string |  | place the clone on this server (ID or name; default: the source's server) |

### nebulactrl services create

Create a service (staged until deployed).

```
nebulactrl services create --project <project> --env <env> --name <name> (--image <ref> | --git <url> [--branch <b>]) [--server <server>] [--port <n>] [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--branch` | string |  | Git branch (default: the repository default) |
| `--build-location` | string |  | where the git source is built: inherit (default), target or build-server |
| `--build-server` | string |  | pin the build server (ID or name); with --build-location build-server |
| `--build-type` | string |  | how a git source is built: auto (default), dockerfile, railpack or starter:<node\|python\|go\|ruby\|php\|static> |
| `--env` | string |  | environment ID, slug or name |
| `--git` | string |  | Git repository URL (built on the target server, or on a build server) |
| `--image` | string |  | Docker image, e.g. traefik/whoami:latest |
| `--name` | string |  | service name |
| `--port` | int |  | HTTP/internal port the service listens on (0 = none) |
| `--project` | string |  | project ID, slug or name |
| `--registry` | string |  | registry ID the build is pushed to (default: the project or team registry) |
| `--server` | string |  | target server ID or name |

### nebulactrl services deploy

Deploy a service.

```
nebulactrl services deploy <service> [flags]
```

Starts a deployment and returns once it is accepted (HTTP 202). With --wait, polls until the
deployment reaches a terminal status and exits 0 only when it is `succeeded`.
With --no-cache a git service builds this one deployment without any cache (docker build --no-cache --pull,
no reuse of an image a build server already pushed); later deployments build normally.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--no-cache` | bool |  | build this deployment without cache (git services; docker build --no-cache --pull) |
| `--timeout` | duration | `30m0s` | give up waiting after this long (with --wait) |
| `--wait` | bool |  | wait for the deployment to finish; exit non-zero unless it succeeded |

### nebulactrl services deploy-hook

Show, enable, disable or rotate a service's deploy hook.

```
nebulactrl services deploy-hook <service> [--enable|--disable|--rotate] [flags]
```

A deploy hook is a URL (POST /hooks/deploy/<service-id>/<secret>) that deploys the service like a manual deploy,
for CI pipelines and container registries (Docker Hub, GHCR). Without a flag the command shows the hook's state.

--enable creates a secret and prints the URL; --rotate replaces the secret of an enabled hook and prints the new URL;
--disable turns the hook off and deletes the secret. The URL is shown once and cannot be read again.
Managing a hook needs the deployments:write scope.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--disable` | bool |  | turn the hook off and delete its secret |
| `--enable` | bool |  | turn the hook on with a new secret and print the URL once |
| `--rotate` | bool |  | replace the secret of an enabled hook and print the new URL once |

### nebulactrl services docker

Show or set a service's Docker options (staged until the next deployment).

```
nebulactrl services docker <service> [flags]
```

Without flags, prints the service's Docker options. With flags, changes them and stages the service. The options are typed:
there is no free-text docker run string. Hardening options (--cap-drop ALL, --no-new-privileges, --read-only, --pids-limit),
--hostname, --dns, curated --sysctl, --user and --group-add work on every server.

--device, --gpus, --runtime, --privileged, --pid-host, --seccomp-unconfined, --apparmor-unconfined (and the NET_ADMIN and
SYS_ADMIN capabilities, set in the web UI) work only on a server an instance admin made unrestricted
(`nebulactrl servers unrestricted`): they can hand over the host. Other servers answer 422 requires_unrestricted_server.
Capabilities to add, ulimits, shm size, extra hosts, labels, tmpfs and the entrypoint are edited in the web UI.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--apparmor-unconfined` | bool |  | [unrestricted server] run without the default AppArmor profile |
| `--cap-drop` | stringSlice |  | capabilities to drop, e.g. ALL or NET_RAW (comma-separated; none clears) |
| `--clear` | bool |  | remove every Docker option of the service |
| `--device` | stringArray |  | [unrestricted server] host device host[:container][:perms], repeatable; none clears |
| `--dns` | stringSlice |  | DNS resolver IPs, at most 3 (none clears) |
| `--gpus` | string |  | [unrestricted server] NVIDIA GPUs: all or a count (none clears) |
| `--group-add` | stringSlice |  | supplementary numeric group IDs (none clears) |
| `--hostname` | string |  | container hostname (default: the service slug; "default" resets) |
| `--no-new-privileges` | bool |  | set the no-new-privileges security option (--no-new-privileges=false turns it off) |
| `--pid-host` | bool |  | [unrestricted server] share the host's PID namespace |
| `--pids-limit` | int64 |  | limit the processes and threads of the container (0 = no limit) |
| `--privileged` | bool |  | [unrestricted server] privileged mode: root on the host |
| `--read-only` | bool |  | mount the root filesystem read-only (config files must then sit on a volume) |
| `--runtime` | string |  | [unrestricted server] OCI runtime, e.g. runsc (default resets) |
| `--seccomp-unconfined` | bool |  | [unrestricted server] run without the default seccomp profile |
| `--sysctl` | stringArray |  | namespaced kernel parameter key=value, repeatable (key= removes it) |
| `--user` | string |  | run as uid[:gid] ("default" resets to the image's user) |

### nebulactrl services download-logs

Download a service's stored runtime logs as a file.

```
nebulactrl services download-logs <service> [flags]
```

Writes the service's stored runtime log (the server keeps 7 days by default), oldest first, as plain text
(`<time> <line>`) or NDJSON. Secret values are masked on the server. At most 200,000 lines: a longer range
ends with a note, so narrow it with --from/--to. Needs the logs:read scope and the service's server online.

Examples:

```sh
nebulactrl services download-logs acme/production/web --from 24h -o web.log
  nebulactrl services download-logs web --format ndjson --grep 'level:error' > errors.ndjson
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--component` | string |  | Compose stacks: only this component's lines |
| `--format` | string | `txt` | file format: txt or ndjson |
| `--from` | string |  | only lines at or after this time: RFC 3339, a date, or a duration ago (24h) |
| `--grep` | string |  | only lines matching this log search query (free text, "phrases", level:error) |
| `-o, --output` | string |  | write to this file instead of stdout (created with mode 0600) |
| `--to` | string |  | only lines before this time (same forms as --from) |

### nebulactrl services logs

Show runtime logs of a service.

```
nebulactrl services logs <service> [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `-f, --follow` | bool |  | stream new lines until interrupted |
| `--tail` | int | `200` | number of recent lines to show |
| `--timestamps` | bool |  | prefix each line with its timestamp |

### nebulactrl services ls

List the services of an environment.

```
nebulactrl services ls --project <project> --env <env> [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--env` | string |  | environment ID, slug or name |
| `--project` | string |  | project ID, slug or name |

### nebulactrl services maintenance

Put a service into maintenance mode, or take it out.

```
nebulactrl services maintenance <service> on|off [--title <t>] [--message <m>] [--eta <rfc3339|duration>] [flags]
```

While on, every domain of the service answers HTTP 503 with a maintenance page and a Retry-After header instead of
reaching the service. It takes effect immediately without a deployment, and it is never staged or rolled back.
--eta takes an RFC 3339 time (2026-11-02T09:30:00Z) or a duration from now (45m, 2h). The page text and ETA are
only used with `on`; `off` keeps the stored text for next time.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--eta` | string |  | expected return: an RFC 3339 time or a duration from now (45m, 2h) |
| `--message` | string |  | page message |
| `--title` | string |  | page title (default: Down for maintenance) |

### nebulactrl services move

Move a service to another environment (staged until the next deploy).

```
nebulactrl services move <service> --env <env> [--project <project>] [--force] [--dry-run] [flags]
```

Move a service to another environment. It keeps running where it is until its next deployment, which joins the new environment's network and variables. References are checked first: variables that point at services staying behind, and other services' variables that point at the moved one, break. Without --force a move that breaks references is refused; --dry-run prints the plan. Canvas links of the service are removed.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--dry-run` | bool |  | print the plan (references, links, slug) and change nothing |
| `--env` | string |  | target environment (ID, slug or name) |
| `--force` | bool |  | move even though references from or to the service break |
| `--project` | string |  | project of --env (default: the service's project) |

### nebulactrl services restart

Restart a service's container.

```
nebulactrl services restart <service>
```

### nebulactrl services run

Run a one-off command in a container of the service's image.

```
nebulactrl services run <service> -- <command...> [flags]
```

Runs the command (argv, no shell; use `-- sh -c '...'` for shell syntax) in a throwaway container of the service's
current image, with its environment, networks and resource limits, on its server. Prints the output and exits
with the command's exit code. Needs the deployments:write scope and is audited.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--detach` | bool |  | start the run and return without waiting for it |
| `--timeout` | duration | `0s` | stop the command after this long (default 30m) |

### nebulactrl services scale

Set the number of replicas or turn on autoscaling.

```
nebulactrl services scale <service> [<replicas>] [--autoscale min:max[:target]|off] [flags]
```

Runs a stateless service (no volumes, an HTTP port) on 1-10 replicas on its server. The change applies
immediately without a deployment and without a rebuild. --autoscale min:max[:target] scales on CPU
(target percent of the replica's CPU limit, default 70); --autoscale off returns to manual scaling.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--autoscale` | string |  | autoscale on CPU between min and max replicas: min:max[:target%] or off |

### nebulactrl services shell

Open an interactive shell in a service's container.

```
nebulactrl services shell <service> [-- command args…] [flags]
```

Opens a terminal in a running replica of the service (bash if the image has it, else sh), or runs the command after `--` with a terminal attached. Needs the Owner, Admin or Developer role and a token with deployments:write. Production services need --production. Sessions are audited (never their input or output) and close after 15 minutes without input.

Examples:

```sh
nebulactrl services shell acme/production/web
  nebulactrl services shell web --replica 1 -- psql -U postgres
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--production` | bool |  | confirm opening a terminal in a production environment |
| `--replica` | int |  | replica index to open (0-based) |

### nebulactrl services update

Set where and how a service is built.

```
nebulactrl services update <service> [--build-location inherit|target|build-server] [--build-server <server|none>] [--registry <id|none>] [--submodules auto|on|off] [flags]
```

The service's own override of the project and team build settings; `inherit` follows them. `none` clears a pin or
registry. `--submodules` sets the git submodule checkout (auto: recursive when the repository has a .gitmodules file; on: always, a failure fails the build; off). The change is staged until the next deployment, like every setting. Compose stacks are edited in the web UI.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--build-location` | string |  | inherit, target or build-server |
| `--build-server` | string |  | pin the build server (ID or name; none clears) |
| `--registry` | string |  | registry ID (none clears) |
| `--submodules` | string |  | git submodules: auto, on or off |

## nebulactrl tasks

Cron tasks and their runs.

```
nebulactrl tasks
```

### nebulactrl tasks create

Schedule a recurring command.

```
nebulactrl tasks create <service> --name <name> --schedule <cron> -- <command...> [flags]
```

Runs the command (argv, no shell; use `-- sh -c '...'` for shell syntax) in a throwaway container of the service's
current image with its environment. The schedule is a 5-field cron expression or @hourly/@daily/@weekly/@monthly,
evaluated in --timezone (an IANA name such as Europe/Berlin; default UTC). Daylight-saving changes keep the wall-clock
time: a run in the skipped hour is skipped for that day, a repeated hour runs once.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--concurrency` | string |  | forbid (default: skip a tick while the previous run is active) or allow |
| `--disabled` | bool |  | create the task disabled |
| `--name` | string |  | task name, unique per service |
| `--schedule` | string |  | cron expression, e.g. "*/15 * * * *" or @daily, evaluated in --timezone |
| `--timeout` | duration | `0s` | stop a run after this long (default 30m) |
| `--timezone` | string |  | IANA time zone of the schedule, e.g. Europe/Berlin (default UTC) |

### nebulactrl tasks logs

Print the output of a run (follows a run that is still active).

```
nebulactrl tasks logs <run-id>
```

### nebulactrl tasks ls

List a service's cron tasks.

```
nebulactrl tasks ls <service>
```

### nebulactrl tasks rm

Delete a cron task and its run history.

```
nebulactrl tasks rm <service> <task>
```

### nebulactrl tasks run

Run a cron task now and follow its output.

```
nebulactrl tasks run <service> <task> [flags]
```

Starts a run immediately (whatever the schedule), prints its output and exits with the command's exit code.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--detach` | bool |  | start the run and return without waiting for it |

### nebulactrl tasks runs

Run history of a service's tasks and one-off commands.

```
nebulactrl tasks runs <service> [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--limit` | int |  | how many runs (default 50) |
| `--task` | string |  | only the runs of this task (name or id) |

### nebulactrl tasks update

Change a cron task's schedule or time zone.

```
nebulactrl tasks update <service> <task> [--schedule <cron>] [--timezone <zone>] [flags]
```

Changing the schedule or the time zone recomputes the next run from now; the new next run is printed.
The time zone is an IANA name such as Europe/Berlin (UTC when never set).

Examples:

```sh
nebulactrl tasks update acme/production/web nightly --timezone Europe/Berlin
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--schedule` | string |  | new cron expression |
| `--timezone` | string |  | new IANA time zone |

## nebulactrl teams

Manage teams.

```
nebulactrl teams
```

### nebulactrl teams create

Create a team (you become its owner; needs an admin-scope token).

```
nebulactrl teams create <name>
```

### nebulactrl teams ls

List your teams and the saved token per team.

```
nebulactrl teams ls
```

### nebulactrl teams switch

Use the saved token of another team.

```
nebulactrl teams switch <slug>
```

## nebulactrl templates

Browse and install one-click templates.

```
nebulactrl templates
```

### nebulactrl templates install

Install a template as staged services (or deploy right away).

```
nebulactrl templates install <template> --project <p> --env <e> --server <s> [--input KEY=VALUE]... [--deploy] [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--deploy` | bool |  | deploy the new services right away |
| `--env` | string |  | environment ID, slug or name |
| `--input` | stringArray |  | install input KEY=VALUE (repeatable) |
| `--name` | string |  | canvas group title |
| `--project` | string |  | project ID, slug or name |
| `--server` | string |  | server ID or name the stack runs on |

### nebulactrl templates installed

List the template stacks of an environment.

```
nebulactrl templates installed --project <p> --env <e> [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--env` | string |  | environment ID, slug or name |
| `--project` | string |  | project ID, slug or name |

### nebulactrl templates ls

List catalog templates.

```
nebulactrl templates ls [--category c] [--license class] [--search text] [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--category` | string |  | homelab, media, storage, games, devtools, ai, data, web, analytics, automation, productivity or security |
| `--license` | string |  | licence class: permissive, copyleft, source-available or proprietary |
| `--search` | string |  | search words (name, summary, tags, licence, database engines) |

### nebulactrl templates plan

Preflight an install (changes nothing).

```
nebulactrl templates plan <template> --project <p> --env <e> [--server <s>] [--input KEY=VALUE]... [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--env` | string |  | environment ID, slug or name |
| `--input` | stringArray |  | install input KEY=VALUE (repeatable) |
| `--project` | string |  | project ID, slug or name |
| `--server` | string |  | server ID or name (enables capacity and port checks) |

### nebulactrl templates rm

Delete a template stack.

```
nebulactrl templates rm <instance-id> --confirm <template-id> [--delete-volumes] [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--confirm` | string |  | the template id, to confirm |
| `--delete-volumes` | bool |  | also remove the stack's Docker volumes (data is lost) |

### nebulactrl templates show

Show a template: services, inputs and licence.

```
nebulactrl templates show <template>
```

### nebulactrl templates update

Show what a newer template revision changes, or stage it (--apply).

```
nebulactrl templates update <instance-id> [--apply] [--input KEY=VALUE]... [flags]
```

Without --apply this prints the diff between the template as installed and the catalog's current revision and changes nothing.
With --apply the changes marked 'apply' are staged as ordinary edits (nothing is deployed). Fields you changed are kept; databases, routes and services are never touched.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--apply` | bool |  | stage the changes (default: only show them) |
| `--input` | stringArray |  | value for an input the new revision added, KEY=VALUE (repeatable) |

## nebulactrl vars

Manage service environment variables.

```
nebulactrl vars
```

### nebulactrl vars history

Show a variable's versions (secrets show a fingerprint only).

```
nebulactrl vars history <service> KEY
```

### nebulactrl vars ls

List variables (secret values are never shown).

```
nebulactrl vars ls <service> [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--exports` | bool |  | also list the virtual variables other services can reference |
| `--platform` | bool |  | also list the platform-provided variables |

### nebulactrl vars rm

Delete variables (staged until the next deploy).

```
nebulactrl vars rm <service> KEY...
```

### nebulactrl vars rotate

Replace a generated variable's value (staged, never deployed).

```
nebulactrl vars rotate <service> KEY [--dry-run] [flags]
```

Re-runs the generators of a variable created with ${{secret(..)}} and similar. --dry-run prints the plan only:
which services consume the value, in which order to deploy them, and any blockers. Without it the new
value is staged on this service and on every consumer; nothing is deployed. Database credentials
cannot be rotated this way once deployed.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--dry-run` | bool |  | show the plan without staging anything |

### nebulactrl vars set

Set variables (staged until the next deploy).

```
nebulactrl vars set <service> KEY=VALUE... [--secret] [--scope build] [flags]
```

Upserts variables on a service. Changes are staged: run `services deploy` to apply them.
Values are never echoed. Use KEY=- to read a value from stdin, which keeps secrets out of the
shell history and process list. A variable that is already secret stays secret.

A value may contain generators that run once, on the server: KEY='${{secret(32)}}' stores a random
secret. Running the same command again keeps the generated value (use `vars rotate` to replace it).
Other forms: ${{service-slug.KEY}}, ${{KEY}}, ${{shared.KEY}}; write $${{ for a literal ${{.
--scope build passes the variable to image builds of git services (--build-arg, or a BuildKit secret
when it is secret); --scope both also keeps it in the container.

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--comment` | string |  | a note stored with the variable |
| `--scope` | string |  | where the variable is injected: runtime (default), build or both |
| `--secret` | bool |  | mark the variables as secret (write-only) |

### nebulactrl vars shared

Manage shared variables of the team (@team), a project (<project>) or an environment (<project>/<env>).

```
nebulactrl vars shared
```

#### nebulactrl vars shared ls

List shared variables.

```
nebulactrl vars shared ls <@team|project[/env]>
```

#### nebulactrl vars shared rm

Delete shared variables.

```
nebulactrl vars shared rm <@team|project[/env]> KEY...
```

#### nebulactrl vars shared rotate

Replace a generated shared variable (staged, never deployed).

```
nebulactrl vars shared rotate <@team|project[/env]> KEY [--dry-run] [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--dry-run` | bool |  | show the plan without staging anything |

#### nebulactrl vars shared set

Set shared variables (restages the services that use them).

```
nebulactrl vars shared set <@team|project[/env]> KEY=VALUE... [--secret] [flags]
```

Options:

| Flag | Type | Default | Description |
|---|---|---|---|
| `--secret` | bool |  | mark the variables as secret (write-only) |

#### nebulactrl vars shared share

Stage KEY=${{shared.KEY}} on services.

```
nebulactrl vars shared share <@team|project[/env]> KEY <service>...
```

A shared variable reaches a service only through an explicit reference row. This stages
KEY=${{shared.KEY}} on each service (services given as ID or project/env/slug).
