# CLI

> Cordium documentation. Canonical page: <https://octelium.com/docs/cordium/latest/use/cli>.

The `cordium` CLI is the primary tool for day-to-day Workspace management from a terminal. It provides access to the full Cordium API with a command structure designed around common workflows.

## Authentication

Before using the CLI, authenticate with your Cordium installation:

```sh
export OCTELIUM_DOMAIN=<DOMAIN>
cordium login
```

This opens a browser window to complete the Octelium authentication flow. You can also log out later as follows:

```sh
cordium logout
```

> **Note:**
>
> The CLI reads the Cordium domain from the `OCTELIUM_DOMAIN` environment variable or from the configuration file written by `cordium login`. Use `--domain` on any command to specify the target installation explicitly when working with multiple Cordium deployments.

## cordium run

`cordium run` is the primary workflow command. It creates a Workspace (if no name is given) or attaches to an existing one, starts it if stopped, waits for it to b ready if needed, and opens an interactive terminal session. Here are some examples:

```sh
# Create from the default Template and attach a terminal
cordium run

# Attach to an existing Workspace (starts it if stopped)
cordium run abc

# Create from a specific Template
cordium run --template ml-env.my-project

# Create from a YAML configuration file
cordium run --file workspace.yaml

# Create from a container image
cordium run --image python:3.11-slim

# Create from a Dockerfile
cordium run --dockerfile ./Dockerfile

# Create from a git repository, cloning a specific branch
cordium run --repository https://github.com/myorg/my-project --branch develop

# Create in a specific Space using that Space's default Template
cordium run --space my-project

# Create an ephemeral Workspace
cordium run --ephemeral

# Create an ephemeral Workspace that is deleted when the terminal session ends
cordium run --ephemeral --rm

# Ephemeral AI agent sandbox with resource limits and a secret
cordium run --ephemeral --rm \
  --image python:3.11-slim \
  --env-from-secret ANTHROPIC_API_KEY=anthropic-key \
  --cpu 2000 --memory 4096

# Set environment variables
cordium run --image node:20 -e NODE_ENV=development -e PORT=3000

# Source a variable from a Space Secret
cordium run --template backend.my-project \
  --env-from-secret DATABASE_URL=staging-db-url

# Clone the primary repository and an additional repository
cordium run --repository https://github.com/myorg/api-service \
  --additional-repo shared-lib=https://github.com/myorg/shared-lib

# Override resource limits
cordium run --template ml-env.research --cpu 8000 --memory 16384 --storage 50000

# Expose named ports
cordium run --image node:20 \
  --repository https://github.com/myorg/fullstack \
  --port web:3000:default \
  --port api:8080

# Pass variable overrides to a parameterized Template
cordium run --template go-build.my-project --ephemeral \
  --var SERVICE=services/payments \
  --var BRANCH=main
```

When a Workspace name is given and the Workspace is already running, `cordium run` opens a terminal immediately. If the Workspace is stopped, it starts it then it opens a terminal.

## cordium terminal

`cordium terminal` opens an interactive terminal in a running Workspace. Unlike `cordium run`, it does not create or start a Workspace; the Workspace must already be running.

```sh
cordium terminal abc
# Or simply
cordium term abc
```

Multiple `cordium terminal` invocations against the same Workspace each create independent terminal sessions within that Workspace.

## cordium exec

`cordium exec` runs a single command in a running Workspace and streams its output. It is designed for scripted, non-interactive command execution. Here are some examples:

```sh
# Run a command
cordium exec abc -- make test

# Run in a specific working directory
cordium exec abc -w /workspace/repo -- go build ./...

# Run as root
cordium exec abc --root -- apt-get install -y ripgrep

# Set per-command environment variables
cordium exec abc -e GOOS=linux -e GOARCH=amd64 -- go build ./...

# Run a shell pipeline
cordium exec abc -- sh -c "cat /etc/os-release | grep VERSION_ID"


# Pipe local input to a remote command
echo "SELECT version();" | cordium exec abc -- psql mydb

# Capture remote output to a local file
cordium exec abc -- cat /workspace/repo/output.json > local-output.json

# Stream logs from a remote background process
cordium exec abc -- tail -f /var/log/app.log


cordium exec abc -w /workspace/repo -- npm test
if [ $? -ne 0 ]; then
  echo "Tests failed"
  exit 1
fi
```

## cordium ssh

`cordium ssh` opens an SSH session to a running Workspace using the SSH protocol. This enables use cases that require real SSH: local port forwarding, dynamic SOCKS5 proxying, SCP/SFTP file transfer, and compatibility with tools that assume SSH connectivity (VS Code Remote SSH, JetBrains Gateway, Zed remote development, `rsync`). It's important to understand that you first need to connect to the Octelium Cluster as follows:

```bash
octelium connect -d
# Or
sudo octelium connect
```

Here are some examples:

```sh
cordium ssh abc

cordium ssh abc -- uptime
cordium ssh abc -- sh -c "ps aux | grep python"

# Forward local :5432 to Workspace's PostgreSQL
cordium ssh abc -L 5432:localhost:5432

# Multiple port forwards without an interactive shell
cordium ssh abc -N \
  -L 5432:localhost:5432 \
  -L 6379:localhost:6379 \
  -L 8080:localhost:8080

# Route traffic through the Workspace network via SOCKS5
cordium ssh abc -D 1080 -N
# Then
curl --socks5 localhost:1080 https://checkip.amazonaws.com

# Generate and append SSH config
cordium ssh abc --print-config >> ~/.ssh/config

# Then use VS Code Remote SSH
code --remote ssh-remote+cordium-abc /workspace/repo

# Then use rsync
rsync -avz ./dist/ cordium-abc:/workspace/repo/dist/

# Then use scp
scp cordium-abc:/workspace/repo/output.csv ./output.csv
```

## cordium cp

`cordium cp` copies files and directories between the local filesystem and a Workspace, or between two Workspaces, using SFTP over SSH. Workspace paths are specified as `<workspace>:<path>`. As with the `cordium ssh` command, you first need to connect to the Cluster via the `octelium connect` command first.

```sh
# Copy a local file to a Workspace
cordium cp ./config.json abc:/workspace/repo/config.json

# Copy a file from a Workspace to local
cordium cp abc:/workspace/repo/output.csv ./output.csv

# Copy directories recursively
cordium cp -r ./src/ abc:/workspace/repo/src/
cordium cp -r abc:/workspace/repo/dist/ ./dist/

# Copy between two Workspaces
cordium cp abc:/workspace/repo/model.pt def:/workspace/repo/model.pt

# Copy a directory from one Workspace to another
cordium cp -r abc:/workspace/data/ def:/workspace/data/
```

## cordium logs

`cordium logs` streams build and lifecycle logs from a Workspace. Logs cover image pull and build output, repository clone output, and the stdout and stderr of all lifecycle tasks.

```sh
# Stream logs
cordium logs abc

# Stream logs with timestamps
cordium logs abc --timestamp

# Stream logs without color (useful for CI/CD log capture)
cordium logs abc --no-color
```

## Workspace Lifecycle Commands

```sh
# Start a stopped Workspace without attaching a terminal
cordium start abc

# Stop a running Workspace
cordium stop abc

# Delete a stopped Workspace
cordium delete workspace abc

# Delete a Template
cordium delete template ml-env.my-project

# Delete a Space and all its contents
cordium delete space my-project
```

> **Note:**
>
> Deleting a Space deletes all Workspaces, Templates, Secrets, and GitProviders within it.

## List Commands

```sh
# List all Workspaces
cordium get workspaces

# Or
cordium get ws

# Get a specific Workspace
cordium get ws abc

# List Workspaces in a specific Space
cordium get workspaces --space my-project

# List all Spaces
cordium get spaces

# List Templates in a Space
cordium get templates --space my-project

# List Secrets in a Space
cordium get secrets --space my-project
```

## Space and Template Management

```sh
# Create a Space
cordium create space my-project --display-name "ML Research Project"

# Create a Template with inline flags
cordium create template ml-env.my-project \
  --image python:3.11-slim \
  --repository https://github.com/myorg/ml-project \
  --branch main \
  --env-from-secret WANDB_API_KEY=wandb-secret \
  --cpu 8000 --memory 16384 --storage 50000 \
  --git-provider github.my-project

# Create a Template from a YAML file
cordium create template ml-env.my-project --file template.yaml

# Trigger a Template pre-build
cordium build ml-env.my-project

# Cancel a running pre-build
cordium build cancel ml-env.my-project
```

## Secret and GitProvider Management

```sh
# Create a Secret from a value
cordium create secret my-api-key.my-project --value "sk-..."

# Create a Secret from a file
cordium create secret my-tls-cert.my-project --from-file ./cert.pem

# Create a Secret interactively (prompts for value without echo)
cordium create secret my-db-password.my-project

# Create a GitHub GitProvider
cordium create gitprovider github.my-project \
  --type github \
  --client-id <oauth-app-client-id> \
  --client-secret-from-secret github-client-secret
```
