> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ovalbee.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ovalbee.com/_mcp/server.

# OvalBee CLI

`ovalbee` is a single executable for Linux, macOS and Windows. It installs and upgrades self-hosted OvalBee on Docker Compose or Kubernetes, applies a license, recovers the administrator account, and runs flows, follows logs and moves data from scripts.

## Install the CLI

```bash
curl -fsSL https://app.ovalbee.com/install.sh | bash
```

The script downloads the build for your system, checks its SHA-256 checksum and puts `ovalbee` in `~/.local/bin`, without `sudo`. Set `OVALBEE_VERSION=X.Y.Z` to install a specific release, or `OVALBEE_INSTALL_DIR` to install somewhere else.

To install by hand, for example on Windows, read the current version from `https://cdn.ovalbee.com/cli/latest`, then download `https://cdn.ovalbee.com/cli/<version>/ovalbee_<os>_<arch>` (`.exe` on Windows) and check it against `SHA256SUMS` in the same folder. Builds exist for `linux`, `darwin` and `windows` on `amd64` and `arm64`.

### Updating

`ovalbee update` checks for a newer CLI, shows the current and available versions and asks before replacing itself. It verifies the checksum and that the new build runs before swapping it in; if anything fails, the old executable stays. It never updates in the background, and other commands never check for updates.

* `ovalbee update --check` changes nothing. It exits with 0 when the CLI is up to date and 10 when an update is available.
* `--version X.Y.Z` installs a specific release, including an older one.
* A CLI installed in a directory you can't write to, such as `/usr/local/bin`, needs `sudo ovalbee update`, or a reinstall into a directory you own.
* A build from source reports version `dev` and is replaced only when you pass `--version`.

The CLI is versioned separately from OvalBee itself: `ovalbee version` prints the CLI version, and `ovalbee status` shows what an installation runs.

### Mirrors and air-gapped networks

Set `OVALBEE_DOWNLOAD_URL` to a mirror of `https://cdn.ovalbee.com` with the same layout. The install script, `ovalbee update`, `ovalbee install` and `ovalbee upgrade` all use it. Without network access at all, `ovalbee install --bundle` and `ovalbee upgrade --bundle` take a platform bundle file you copied over.

### Shell completion

`ovalbee completion bash|zsh|fish|powershell` prints a completion script. Command, subcommand and flag candidates come from the CLI itself, without signing in, reading a context or contacting an installation.

For Bash, add this to `~/.bashrc`:

```bash
source <(ovalbee completion bash)
```

For Zsh, add this to `~/.zshrc` after enabling its completion system:

```zsh
autoload -Uz compinit
compinit
source <(ovalbee completion zsh)
```

For Fish, run these commands in Fish. The completion file loads automatically in new shells:

```fish
mkdir -p ~/.config/fish/completions
ovalbee completion fish > ~/.config/fish/completions/ovalbee.fish
source ~/.config/fish/completions/ovalbee.fish
```

If the installer added `~/.local/bin` only to another shell's profile, run `fish_add_path ~/.local/bin` first.

For PowerShell, add this to your `$PROFILE`:

```powershell
ovalbee completion powershell | Out-String | Invoke-Expression
```

Completion covers command names and flags, not server-side resource names or flag values.

## Contexts

Every command acts on the selected **context**: one OvalBee installation and, when the CLI manages it, how to reach the machines it runs on.

| Context | Address                                                      |
| ------- | ------------------------------------------------------------ |
| `local` | `http://localhost:30080` — selected until you choose another |
| `cloud` | `https://app.ovalbee.com`                                    |

```bash
ovalbee context list                 # all contexts, the selected one marked
ovalbee context use cloud            # select a context
ovalbee --context staging status     # act on another context for one command
```

`ovalbee install` records the installation it creates as a context. To manage an installation that is already running, attach it:

```bash
ovalbee context add staging --url https://ovalbee.example.com                 # API only
ovalbee context add office --url http://gpu-box:30080 --compose-dir /opt/ovalbee   # Docker Compose
ovalbee context add prod --url https://ovalbee.example.com --namespace ovalbee --release ovalbee --gitops
```

Attaching changes nothing in the installation. A context without `--compose-dir` or `--namespace` is API-only: commands that need the host or cluster, such as `restart` or `admin reset-password`, refuse and say what is missing.

`OVALBEE_CONTEXT` selects a context for a whole shell or CI job. `OVALBEE_URL` and `OVALBEE_TOKEN` override the address and the credential. Contexts are stored in `config.json` and tokens in `credentials.json` (readable only by you) in your user configuration directory, or in `OVALBEE_CONFIG_DIR`.

## Sign in

The CLI signs in with an [API token](/administration/secrets-and-tokens#api-tokens) and never asks for your password. Create a token in OvalBee under **Settings** → **API Tokens**, then store it:

```bash
ovalbee auth login                   # paste the token at the prompt; it isn't shown
ovalbee --context cloud auth login   # OvalBee Cloud
```

A token belongs to one workspace: store a token from another workspace to switch. The CLI checks the token with the server and records its workspace; `--workspace` makes it refuse a token from any other.

* Scripts and CI pipe the token in (`echo "$OVALBEE_API_TOKEN" | ovalbee auth login`), or set `OVALBEE_TOKEN` for each command without storing anything.
* `ovalbee auth status` checks the stored token with the server and exits with 1 when you are not signed in.
* `ovalbee auth logout` forgets the token on this computer. The token keeps working until you revoke it in **Settings** → **API Tokens**.

Tokens and licenses are never accepted as command-line arguments, so they don't end up in your shell history.

## Install OvalBee

### On one machine with Docker

You need Docker Engine and Docker Compose v2.

```bash
ovalbee install
```

The CLI downloads the installation bundle of the latest OvalBee release, writes `docker-compose.yml` and `.env` to `<user data directory>/ovalbee/local`, generates every secret and password, starts OvalBee and waits until it answers. It then signs itself in with an API token named `ovalbee-admin` that it issues for `admin` inside the installation, and prints the generated administrator password once. That password is the initial value only: changing it in OvalBee later is not reflected in `.env`.

| Option                |                                                                                            |
| --------------------- | ------------------------------------------------------------------------------------------ |
| `--version X.Y.Z`     | The OvalBee release to install. `nightly` installs the current development build.          |
| `--port`              | Port OvalBee is served on, `30080` by default.                                             |
| `--dir`, `--data-dir` | Where the files and the data go.                                                           |
| `--name`              | Context name, `local` by default.                                                          |
| `--bundle PATH`       | Install from a downloaded `ovalbee-platform.tar.gz`, or from a checkout of the repository. |
| `--no-start`          | Write the files and the context without starting anything.                                 |

Running `ovalbee install` again on the same directory resumes the installation and never replaces secrets. The new context is selected only if you had not selected another one; otherwise the CLI prints the `ovalbee context use` command.

### On Kubernetes with Helm

```bash
ovalbee install --backend kubernetes --url https://ovalbee.example.com \
  --kube-context my-cluster --namespace ovalbee
```

This needs `helm` and `kubectl`. The CLI shows the cluster, namespace, release, chart version and image tag, asks for confirmation and installs the OvalBee Helm chart with generated secrets. Add your own values with `--values FILE` (repeatable). See [Self-hosted installation](/administration/self-hosting) for what the cluster needs.

> **Note**
>
> Running OvalBee on Kubernetes and running node runs as Kubernetes pods are separate. Starting node runs and deployments on the Kubernetes executor needs the Business plan: without it the platform runs, but node runs and deployments are refused. See [Compute](/administration/compute).

### With GitOps

If Argo CD, Flux or another controller owns your cluster, let it install OvalBee:

```bash
ovalbee install --backend kubernetes --gitops --url https://ovalbee.example.com --output-dir ./ovalbee
```

The CLI changes nothing in the cluster. It writes three files for review and commit:

* `values.yaml` — a short, commented override with your choices. It pins the image tag and names an existing Secret instead of generated secrets.
* `chart-default-values.yaml` — every value the chart accepts, with its default, for reference.
* `README.md` — where the chart is published and at which version, the Secret's name and every key it needs, how to create that Secret without committing its values, example Argo CD `Application` and Flux `HelmRelease` manifests, and how to upgrade.

The chart's source is `charts/ovalbee` in the [OvalBee repository](https://github.com/oval-bee/ovalbee) at each release tag; the generated `README.md` names the chart version that matches the release you chose and where to pull it from. No secret value is written into these files.

The context records that a controller owns the release: `start`, `stop` and `restart` refuse, and `upgrade` prints the changes to make in Git instead of applying them. `status`, `logs`, `doctor` and the workspace commands work as usual.

## Operate an installation

| Command                                      | What it does                                                                                                                                                                         |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ovalbee status`                             | Address, health, signed-in workspace, installed version and the state of each service.                                                                                               |
| `ovalbee logs [service] [-f] [--tail N]`     | Service logs of the platform. For the logs of a node run, use `ovalbee run logs`.                                                                                                    |
| `ovalbee stop`, `start`, `restart [service]` | Stop and start OvalBee or one service, keeping all data. On Kubernetes, `stop` scales the release to zero and `start` restores the previous replica counts.                          |
| `ovalbee upgrade [--version X.Y.Z]`          | Upgrade to the latest release, or the one given.                                                                                                                                     |
| `ovalbee doctor`                             | Check Docker or the cluster, ports, disk space, the release and the API. Inside a source checkout it also checks that checkout's development stack. Exits with 1 when a check fails. |

`upgrade` shows the installed and target versions and asks first. It refuses to go to an older version unless you pass `--allow-downgrade`, because database migrations only go forward. On Docker Compose it replaces `docker-compose.yml` and adds settings new releases introduce to `.env` without changing existing ones; keep your own changes in a `docker-compose.override.yml` next to it.

### Reset the administrator password

```bash
ovalbee admin reset-password              # the admin account
ovalbee admin reset-password --user alice # by username or email
```

This works when nobody can sign in. It runs [`ovalbee-admin`](/administration/self-hosting#command-line-administration) inside the installation through Docker or `kubectl exec`, so it needs access to the machine or cluster, never only an API address, and no internet access. The new password is typed twice without echo, or read with `--password-stdin`. The change is recorded in the audit log, and a password reset link already emailed to the account stops working.

### Apply a license

```bash
ovalbee license status            # plan, validity and the installation ID
ovalbee license apply license.jwt
```

A license is issued for one installation. Send OvalBee the installation ID that `license status` shows, then apply the file you receive; `-` reads it from standard input (add `--yes` there, since nothing is left to confirm on). The license is checked on the server, which refuses a license for another installation, an expired one, or one that was altered, and says which. Both commands need an instance administrator. On OvalBee Cloud, plans are managed per workspace on the **Billing** page instead.

## Automate workspaces

These commands work on any context you are signed in to, OvalBee Cloud included. Every list and `show` command accepts `--json`. A flow, node, dataset or deployment can be named by its id or its exact name; a name that matches more than one is refused.

### Flows and runs

```bash
ovalbee flow list
ovalbee flow show "Train detector"
ovalbee node run "Train detector" train --follow   # start a node and print its log until it ends
ovalbee run list --active
ovalbee run logs 1234 --follow
ovalbee run wait 1234 --timeout 2h
ovalbee run stop 1234
```

`node run` prints the run's task id as soon as it starts. Nodes downstream run as well unless you pass `--isolated`. With `--wait` or `--follow`, and with `run wait`, the exit code says how the run ended:

| Exit code | Meaning                                                  |
| --------- | -------------------------------------------------------- |
| 0         | Completed                                                |
| 2         | Failed                                                   |
| 3         | Cancelled                                                |
| 4         | Still running: the timeout passed, or you pressed Ctrl-C |
| 1         | Any other error                                          |

Pressing Ctrl-C stops waiting, not the run. To cancel it, use `ovalbee run stop` or `ovalbee node stop`, which ask for confirmation.

`ovalbee flow export` writes a flow as a YAML document, and `ovalbee flow import` creates a new flow from one, for example in another workspace or installation. Datasets, secrets and models are referred to by name, so they need to exist under the same names where you import. An invalid document creates nothing and lists its problems. `ovalbee open` opens the selected installation, a flow or a run in the browser; `--print` prints the address instead.

### Data, models and deployments

```bash
ovalbee dataset upload "Street scenes" ./photos --create
ovalbee dataset download "Street scenes" -o ./street-scenes
ovalbee model list --deployed
ovalbee deployment stop yolo-api
```

`dataset upload` imports files exactly like the [Import drag & drop](/node-library/nodes/import-ops-import-drag-and-drop) node, which it runs for you in a flow named *CLI uploads*: each upload adds a new version of the dataset, only images and videos are imported, and `--on-conflict skip|replace|rename` decides what happens to a path that's already there. Interrupting the upload before the import starts deletes the uploaded files and imports nothing.

`dataset download` saves the original files of a version (`--version`, the latest by default). Running it again skips files that are already there unchanged. Annotations are not included.

`deployment start` and `deployment stop` ask for confirmation; stopping never deletes the deployment.

### Secrets

```bash
ovalbee secret list
ovalbee secret set my-supervisely --type supervisely url=https://app.supervisely.com --value-stdin < token.txt
ovalbee secret delete old-smtp --replace-with new-smtp
```

Non-secret fields, such as an address, can be passed as `field=value`. Secret values — tokens, passwords, keys — are read only from standard input with `--value-stdin`, from `--from-file`, or from a hidden prompt, and are never printed. Updating a secret changes only the fields you give. Deleting a secret that nodes still use needs `--replace-with` another secret of the same type.

## In scripts and CI

* Results go to standard output and progress to standard error, so `--json` output can be piped as is.
* Without a terminal, commands that would ask for confirmation refuse instead of waiting. Pass `--yes` to confirm in advance.
* Confirmations are drawn as a Yes/No choice that defaults to No. With `TERM=dumb`, or with `OVALBEE_ACCESSIBLE` set, they are a plain `[y/N]` line instead, which reads well in logs and screen readers.
* Pass the credential through `OVALBEE_TOKEN`, and the target through `OVALBEE_URL` or `OVALBEE_CONTEXT`.

```bash
export OVALBEE_URL=https://app.ovalbee.com OVALBEE_TOKEN=$OVALBEE_API_TOKEN
task=$(ovalbee node run 42 evaluate)
ovalbee run wait "$task" --timeout 1h
```

## Develop OvalBee from source

Inside a checkout of the [OvalBee repository](https://github.com/oval-bee/ovalbee), `ovalbee dev` runs the development stack and `ovalbee node dev` works on node templates:

```bash
ovalbee dev up                     # write .env if missing, build and start the stack, sign in
ovalbee dev check                  # lint, typecheck and test suites; exits with 1 if any fails
ovalbee dev db generate            # migrations for an edited schema
ovalbee dev db reset               # delete the stack's database and start it empty (asks first)
ovalbee node dev regen             # regenerate node models and sync templates into the API
ovalbee node dev build node-runner # build a runner or node image into local Docker
ovalbee node dev run "My flow" my_node inputs.json
```

`dev up` records the checkout's stack as a context named after its Compose project, so `status`, `logs` and `restart` work on it too. What each command runs comes from the checkout's `tools/dev.json`, so a released CLI matches any checkout that has one; when the two are too far apart, the command names what is missing and which one to update. `--checkout DIR` or `OVALBEE_CHECKOUT` acts on a checkout other than the one you are in. The repository's `DEVELOPMENT.md` is the full guide.

## Related pages

* [Self-hosted installation](/administration/self-hosting) — what an installation needs and how it is configured.
* [Secrets and API tokens](/administration/secrets-and-tokens) — the tokens the CLI signs in with.
* [Compute](/administration/compute) — executors and machine classes.