Skip to content

cpctl CLI

The cpctl CLI is the command-line interface for Compute Portal. It lets you deploy GPU workloads, manage services, databases, and infrastructure entirely from a terminal — scriptable, agent-friendly, and designed for full CI/CD integration.

Installation

bash
# Linux / macOS (recommended)
curl -fsSL https://install.computeportal.io | sh

# Install a specific version
CP_VERSION=v0.2.0 curl -fsSL https://install.computeportal.io | sh

# Install to a custom directory (no sudo)
CP_INSTALL_DIR=~/.local/bin curl -fsSL https://install.computeportal.io | sh

Or download a binary directly from GitHub Releases:

PlatformBinary
Linux x86_64cpctl-linux-amd64
Linux ARM64cpctl-linux-arm64
macOS x86_64cpctl-darwin-amd64
macOS Apple Siliconcpctl-darwin-arm64

After installation verify it works:

bash
cpctl version

Authentication

Login with API token

The recommended method for CI/CD and agents:

bash
cpctl login --token <api-token>

Get your API token from computeportal.io/user/orders after purchasing a subscription.

You can also set the token via environment variable — useful in containers and CI pipelines:

bash
export CP_API_TOKEN=<api-token>

Run cpctl login without flags for instructions on getting your token.

Logout

bash
cpctl logout           # revokes token locally and server-side

Show current user

bash
cpctl whoami
email             alice@example.com
user_id           usr_abc123
org               example-org
plan              pro
token_expires_at  2027-01-01T00:00:00Z

Global Flags

These flags apply to every command:

FlagDescription
--region <region>Pin all API calls to a specific region (eu-west, us-east, ap-south)
--jsonOutput results as machine-readable JSON
--yes, -ySkip all confirmation prompts

Project Setup

Initialize a project

Creates a cp.json in the current directory via interactive prompts:

bash
cpctl init
Initialising Compute Portal project...

Project name: my-inference-api
Docker image: myorg/inference:latest
Region (eu-west / us-east / ap-south) [eu-west]: eu-west
Replicas [1]: 2

Generated cp.json:

json
{
  "project": "my-inference-api",
  "image": "myorg/inference:latest",
  "region": "eu-west",
  "replicas": 2
}
bash
cpctl link my-inference-api
# Linked to service my-inference-api (wrote .cp-link)

This writes a .cp-link file so subsequent commands (deploy, logs, env) know which service to target.

bash
cpctl unlink
# Unlinked (removed .cp-link)

Open a service in the browser

bash
cpctl open                   # reads service from .cp-link
cpctl open my-inference-api  # explicit service name

List all services

bash
cpctl list
NAME               IMAGE                         STATUS   REGION    URL
my-inference-api   myorg/inference:latest        running  eu-west   https://my-inference-api.cpctl.app
postgres-db        postgres:16                   running  eu-west   —

Deploy

Deploy a Docker image or GitHub repo to CP hardware.

bash
# Deploy from Docker image
cpctl deploy --image nginx:latest

# Deploy with GPU
cpctl deploy --image myorg/inference:latest --gpu rtx4090

# Deploy with multiple GPUs
cpctl deploy --image myorg/trainer:latest --gpu rtx5090 --gpu-count 4

# Deploy from a GitHub repo (no Dockerfile needed)
cpctl deploy --repo https://github.com/org/repo

# Deploy from cp.json in the current directory
cpctl deploy

Deploy from a local directory or existing image

If you have a local Dockerfile or an existing image, choose one of these options:

Option 1 — Push to a registry first, then deploy:

bash
docker build -t myorg/myapp:latest .
docker push myorg/myapp:latest
cpctl deploy --image myorg/myapp:latest --name my-app

Option 2 — Push to GitHub and use --repo:

bash
git push origin main
cpctl deploy --repo https://github.com/myorg/myapp --name my-app

Public access only

Both options currently require public access — public Docker Hub/GHCR images for --image, and public GitHub repos for --repo. If you need to deploy from a private registry or private GitHub repo, contact Compute Portal to discuss secure options.

Deploy from a GitHub repo

Pass --repo with a public GitHub URL and CP handles the rest — no Docker knowledge required:

bash
cpctl deploy --repo https://github.com/your-org/your-app --name my-app
→ Deploying https://github.com/your-org/your-app...
✓ Deployed my-app

service  my-app
id       my-app
url      https://my-app.cpctl.app
status   running

What happens behind the scenes:

  1. CP clones your repo
  2. Detects and uses the Dockerfile at the repo root
  3. Builds the Docker image on CP infrastructure
  4. Pushes it to the internal registry
  5. Deploys the resulting image as a running service

The registry is fully internal — no Docker Hub account or image push required from your side.

Dockerfile required

Your repo must contain a Dockerfile at the root. CP uses it to build the image.

Deploy flags

FlagDescription
--image <image>Docker image to deploy (e.g. nginx:latest)
--repo <url>GitHub repo URL to build and deploy
--name <name>Service name (default: derived from image or repo name)
--env <environment>Target environment (default: production)
--region <region>Region to deploy to (eu-west, us-east, ap-south)
--gpu <type>GPU to attach (rtx4090, rtx5090)
--gpu-count <n>Number of GPUs (default: 1)
--node <id>Pin to a specific node ID

When --image and --repo are both absent, cpctl deploy reads cp.json from the current directory.

Deploy output

Deploying myorg/inference:latest...
✓ Deployed my-inference-api

service   my-inference-api
id        svc_abc123
url       https://my-inference-api.cpctl.app
status    running

Service Lifecycle

The most common lifecycle commands are available at the top level:

bash
cpctl stop <name>               # stop a running service
cpctl start <name>              # start a stopped service
cpctl delete <name> --force     # permanently delete a service

The full cpctl machine subcommand offers additional operations:

bash
cpctl machine list              # list all services
cpctl machine status <name>     # show health and resources
cpctl machine start <name>      # start a stopped service
cpctl machine stop <name>       # stop a running service
cpctl machine restart <name>    # restart a service
cpctl machine destroy <name>    # permanently destroy a service (alias: cpctl delete)

machine status

bash
cpctl machine status my-inference-api
name    my-inference-api
id      svc_abc123
image   myorg/inference:latest
status  running
region  eu-west
node    node-eu1-001
cpu     4.00
memory  16g
url     https://my-inference-api.cpctl.app
gpu     rtx4090

machine destroy

bash
cpctl machine destroy my-inference-api --force

--force is required to confirm the destructive operation.

Logs

Stream or tail logs from any service:

bash
cpctl logs <name>               # last 100 lines
cpctl logs <name> --tail 500    # last 500 lines
cpctl logs <name> --follow      # stream in real time
cpctl logs <name> -f            # shorthand for --follow

Status

Check platform health or the status of a specific service:

bash
# Platform-wide health
cpctl status

# Per-service status
cpctl status <name>

Example output for the service form:

name    my-inference-api
status  running
image   myorg/inference:latest
region  eu-west
node    node-eu1-001
url     https://my-inference-api.cpctl.app
cpu     
memory  
gpu

Scale

Adjust replicas or resource limits for a service:

bash
cpctl scale <name> --replicas 3           # set replica count
cpctl scale <name> --cpu 4               # set CPU limit in vCPUs
cpctl scale <name> --ram 16g             # set memory limit
cpctl scale <name> --replicas 2 --ram 8g  # combine flags
FlagDescription
--replicas <n>Number of replicas
--cpu <n>CPU limit in vCPUs (e.g. 2, 0.5)
--ram <size>Memory limit (e.g. 4g, 512m)

Exec & SSH

exec — run a command inside a container

bash
cpctl exec <name> -- <command> [args...]

cpctl exec my-api -- sh                   # open shell
cpctl exec my-api -- python manage.py migrate
cpctl exec my-api -- /bin/bash

ssh — open a shell in a container

bash
cpctl ssh <name>

Alias for cpctl exec <name> -- sh. Opens an interactive shell inside the running container.

Processes

List running processes in a service:

bash
cpctl ps <name>

Environment Variables

Set variables

bash
cpctl env set <service> KEY=VALUE [KEY=VALUE ...]

# Single variable
cpctl env set my-api DATABASE_URL=postgres://...

# Multiple variables
cpctl env set my-api DEBUG=false LOG_LEVEL=info

# Import from .env file
cpctl env set my-api --file .env

List variables

bash
cpctl env list <service>
KEY            VALUE
DATABASE_URL   postgres://user:pass@host/db
LOG_LEVEL      info
DEBUG          false

Values longer than 40 characters are masked for safety.

Remove variables

bash
cpctl env unset <service> KEY [KEY ...]

cpctl env unset my-api DEBUG
cpctl env unset my-api DEBUG LOG_LEVEL

variable (alias)

cpctl variable is an alias for cpctl env:

bash
cpctl variable list <service>
cpctl variable set <service> KEY=VALUE
cpctl variable delete <service> KEY

Environments

Environments let you isolate deployments (e.g. production, staging, pr-123).

bash
cpctl environment list             # list all environments
cpctl environment create <name>    # create a new environment
cpctl environment delete <name>    # delete an environment (--force to confirm)
cpctl environment switch <name>    # set active environment in .cp-link

Switch environment

bash
cpctl environment switch staging
# Switched to environment staging (updated .cp-link)

The active environment is stored in .cp-link and used automatically by deploy and env commands.

Deployment History

Inspect past deployments for a service:

bash
cpctl deployment list <service>           # list all deployments
cpctl deployment status <service> <id>    # show a specific deployment
bash
cpctl deployment list my-inference-api
ID            STATUS     IMAGE                         CREATED_AT
dep_abc123    success    myorg/inference:v2.1.0        2026-07-01T12:00:00Z
dep_xyz789    success    myorg/inference:v2.0.0        2026-06-28T09:15:00Z
dep_def456    failed     myorg/inference:v1.9.0        2026-06-20T18:30:00Z

Redeploy

Re-trigger the current deployment:

bash
cpctl redeploy <service>

Rollback

Roll back to a previous deployment:

bash
cpctl rollback <service>              # roll back to previous
cpctl rollback <service> <dep-id>    # roll back to a specific deployment ID

Custom Domains

Attach your own domain to a service:

bash
cpctl domain add <service> <domain>        # attach a domain
cpctl domain list <service>                # list attached domains
cpctl domain status <service> <domain>     # check DNS and TLS status
cpctl domain remove <service> <domain>     # detach a domain

domain add

Before running this, add a CNAME record at your DNS provider:

NameTypeTargetProxy
apiCNAMEcpctl.appDNS only

Then attach the domain:

bash
cpctl domain add my-api api.example.com
✓ Domain api.example.com attached to my-api

domain   api.example.com
service  my-api
status   active
tls      pending

TLS is provisioned automatically via Let's Encrypt within a minute or two.

If DNS hasn't propagated yet, use --skip-dns to bypass the CNAME check:

bash
cpctl domain add my-api api.example.com --skip-dns

domain status

bash
cpctl domain status my-api api.example.com
domain          api.example.com
status          active
tls             yes
dns_configured  yes
cname_target    cpctl.app
created_at      2026-07-01T10:00:00Z

Volumes

Attach persistent storage volumes to a service:

bash
cpctl volume list <service>                  # list attached volumes
cpctl volume add <service> <mount-path>      # attach a new volume
cpctl volume delete <service> <name>         # delete a volume (--force to confirm)
bash
# Attach a volume mounted at /data
cpctl volume add my-api /data

# List volumes
cpctl volume list my-api
NAME         MOUNT   SIZE   CREATED_AT
vol_abc123   /data   10GB   2026-07-01T10:00:00Z

Databases

Create a database

bash
cpctl db create postgres               # PostgreSQL
cpctl db create redis                  # Redis
cpctl db create mysql                  # MySQL
cpctl db create mongo                  # MongoDB

With options:

bash
cpctl db create postgres \
  --name my-postgres \
  --region eu-west \
  --size 50
FlagDescription
--name <name>Database name (default: <type>-db)
--region <region>Region (default: account default)
--size <gb>Storage size in GB (default: 10)

List databases

bash
cpctl db list

Get connection URL

bash
cpctl db url <name>

Prints the full connection URL to stdout — useful for piping into your app's config.

Destroy a database

bash
cpctl db destroy <name> --force

Interactive database shell

bash
cpctl connect <database-name>

Automatically selects the right client:

Database typeClient used
postgrespsql
mysqlmysql
redisredis-cli
mongomongosh

The client must be installed locally.

Metrics

View resource metrics for a service:

bash
cpctl metrics <service>
service   my-inference-api
cpu       12%
memory    4.2 / 16.0 GB
network   ↑ 1.2 MB/s  ↓ 0.4 MB/s

GPU (CP Exclusive)

CP's GPU commands give you direct control over bare-metal GPU inventory — an exclusive capability beyond standard PaaS platforms.

List GPU inventory

bash
cpctl gpu list                          # all available GPU nodes
cpctl gpu list --region eu-west        # filter by region
cpctl gpu list --type rtx4090          # filter by GPU type
NODE             GPU       AVAIL/TOTAL  REGION    UTIL   VRAM              TEMP
node-eu1-001     rtx5090   4 / 4       eu-west   0%     0.0 / 24.0 GB     45°C
node-eu1-002     rtx4090   2 / 8       eu-west   18%    12.4 / 64.0 GB    67°C
node-us1-001     rtx5090   0 / 4       us-east   100%   24.0 / 24.0 GB    82°C

GPU status for a service

bash
cpctl gpu status my-inference-api
service      my-inference-api
gpu_type     rtx5090
node         node-eu1-001
utilization  34.2%
vram         8.3 / 24.0 GB
temperature  58°C
power        220W

Reserve GPU capacity

Pre-reserve GPUs for guaranteed capacity at a fixed rate:

bash
cpctl gpu reserve --type rtx5090 --count 2 --duration 24h --region eu-west
FlagDescription
--type <gpu>GPU type: rtx4090, rtx5090 (required)
--count <n>Number of GPUs (default: 1)
--duration <d>Duration: 1h, 4h, 24h, 7d, etc. (default: 1h)
--region <region>Region (default: account default)

One-shot GPU jobs

Run a script on a GPU and exit — billed per second, ideal for training runs:

bash
cpctl gpu run \
  --image pytorch/pytorch:2.3-cuda12.1 \
  --script "python train.py --epochs 10" \
  --gpu rtx5090 \
  --gpu-count 1

Logs stream in real time and billing stops when the job exits.

FlagDescription
--image <image>Docker image to run (required)
--script <cmd>Command to run inside the container
--gpu <type>GPU type (default: rtx4090)
--gpu-count <n>Number of GPUs (default: 1)
--region <region>Region

Infrastructure

Nodes

bash
cpctl node list                    # list all compute nodes
cpctl node status <node-id>        # show node health and resources

Regions

bash
cpctl region list                  # list available regions

Hosts

bash
cpctl host list                    # list registered hosts

Policy

bash
cpctl policy list                  # list scheduling policies

Billing

bash
cpctl billing usage                # current billing cycle usage
cpctl billing history              # past invoices

Machine Payments

cpctl pay enables per-call, agent-native payments for ComputePortal API operations. AI agents and automated clients can pay for individual API calls using a linked card or USDC wallet — no human checkout, no pre-loaded balance.

pay setup

Link a payment method. Card details are entered securely in your browser via Stripe — raw card numbers never touch the CP server.

bash
cpctl pay setup --method card --limit 1.00

This opens a Stripe-hosted checkout page in your browser. Enter your card there, then return to the terminal. The CLI polls until the card is saved.

For USDC payments on the Base network:

bash
cpctl pay setup --method usdc --limit 0.50

Output (card):

→ Spend limit: $1.00 per call

Open this URL in your browser to enter your card details:

  https://checkout.stripe.com/c/pay/...

Waiting for card setup to complete...

✓ Card linked
  cardholder   CHOI YOON IL
  method       card
  last4        6880
  exp          05/2029
  spend_limit  $1.00 per call
  currency     USD

pay status

bash
cpctl pay status

Output:

  last4        6880
  type         card
  spend_limit  $0.50 per call
  currency     USD
  active       yes

pay authorize

Generate a short-lived payment token for a specific API call. For card payments, the charge is confirmed immediately when you run this command.

bash
cpctl pay authorize <service> <amount> [--action deploy]
bash
cpctl pay authorize my-api 0.10

Output:

✓ Payment authorized
  token       mpp_tok_xxxxxxxxxxxxxxxxxxxx...
  service     my-api
  amount      $0.10 USD
  action      deploy
  expires_at  2026-07-08T07:06:08Z
  charged     yes — card charged
  stripe_pi   pi_3Rxxxxxxxxxxxxxxxxxxxxxxxx

Use this token with your next deploy:
  cpctl deploy --image <image> --name my-api --pay-token mpp_tok_xxxxxxxxxxxxxxxxxxxx...

The token expires in 5 minutes. Pass it to cpctl deploy via --pay-token:

bash
cpctl deploy --image nginx:latest --name my-api --pay-token mpp_tok_...

pay history

bash
cpctl pay history [--limit 20]

Output:

ID                  SERVICE   ACTION   AMOUNT   STATUS    STRIPE PI                        CHARGED AT
pay_xxxxxxxxxxxx    my-web    deploy   $0.50    settled   pi_3Rxxxxxxxxxxxxxxxxxxxxxxxx    2026-07-08T07:01:10Z

Flags

FlagDefaultDescription
--methodcard or usdc (required for setup)
--limit1.00Per-call spend limit in USD
--actiondeployAction being authorized: deploy, start, domain-add
--limit20Records to return (history)

Sandboxes

Sandboxes are ephemeral environments for short-lived experiments:

bash
cpctl sandbox create               # create a sandbox
cpctl sandbox list                 # list active sandboxes
cpctl sandbox destroy <id>         # destroy a sandbox

Utility

Open documentation

bash
cpctl docs

Opens docs.computeportal.io in your default browser.

Upgrade the CLI

bash
cpctl upgrade

Fetches the latest binary from the CP API and atomically replaces the running binary.

current   0.1.14
latest    0.1.15
Downloading https://install.computeportal.io/releases/v0.1.15/cpctl-darwin-arm64...
✓ Upgraded to v0.1.15

Version

bash
cpctl version
# cpctl version v0.1.15

Configuration Files

cp.json

The project configuration file, created by cpctl init:

json
{
  "project": "my-inference-api",
  "image": "myorg/inference:latest",
  "region": "eu-west",
  "replicas": 2,
  "resources": {
    "cpu": 4,
    "memory": "16g",
    "gpu": "rtx5090"
  },
  "env": {
    "LOG_LEVEL": "info"
  },
  "domains": ["api.example.com"]
}

When cpctl deploy is run without --image or --repo, it reads cp.json automatically.

Written by cpctl link and cpctl environment switch. Stores the linked service and active environment:

json
{
  "service": "my-inference-api",
  "environment": "production"
}

Add .cp-link to .gitignore if different team members link different environments.

Environment Variables

VariableDescription
CP_API_TOKENAPI token — takes precedence over stored credentials
CP_API_URLOverride the API base URL (for self-hosted or regional endpoints)

CI/CD Integration

GitHub Actions

yaml
- name: Deploy to Compute Portal
  env:
    CP_API_TOKEN: ${{ secrets.CP_API_TOKEN }}
  run: |
    cp deploy --image ${{ env.IMAGE_TAG }} --region eu-west

Docker build + deploy

bash
docker build -t myorg/inference:$SHA .
docker push myorg/inference:$SHA
cpctl deploy --image myorg/inference:$SHA

Blue-green with rollback

bash
cpctl deploy --image myorg/inference:v2.0.0

# Verify
cpctl status my-inference-api

# Roll back if needed
cpctl rollback my-inference-api

Complete Command Reference

CommandDescription
cpctl loginAuthenticate with Compute Portal
cpctl logoutLog out and revoke credentials
cpctl whoamiShow current authenticated user
cpctl initInteractively create cp.json
cpctl link <service>Link directory to a service
cpctl unlinkRemove .cp-link
cpctl open [service]Open service URL in browser
cpctl listList all services
cpctl deployDeploy a service
cpctl redeploy <service>Re-trigger current deployment
cpctl rollback <service> [id]Roll back to a previous deployment
cpctl machine listList services
cpctl machine start <name>Start a service
cpctl machine stop <name>Stop a service
cpctl machine restart <name>Restart a service
cpctl machine destroy <name>Permanently destroy a service
cpctl machine status <name>Show service health
cpctl logs <name>Stream service logs
cpctl status <name>Show platform health, or service status if a name is given
cpctl scale <name>Scale replicas or resources (--replicas, --cpu, --ram)
cpctl exec <name> -- <cmd>Run command inside container
cpctl ssh <name>Open interactive shell in container (alias: exec -- sh)
cpctl ps <name>List running processes
cpctl env set <service>Set environment variables
cpctl env list <service>List environment variables
cpctl env unset <service>Remove environment variables
cpctl variableAlias for cpctl env
cpctl environment listList environments
cpctl environment createCreate an environment
cpctl environment deleteDelete an environment
cpctl environment switchSwitch active environment
cpctl deployment list <service>List deployment history
cpctl deployment status <service> <id>Show deployment details
cpctl domain add <service> <domain>Attach custom domain
cpctl domain list <service>List domains
cpctl domain status <service> <domain>Check domain/TLS status
cpctl domain remove <service> <domain>Remove domain
cpctl volume list <service>List volumes
cpctl volume add <service> <path>Attach a volume
cpctl volume delete <service> <name>Delete a volume
cpctl db create <type>Create a managed database
cpctl db listList databases
cpctl db url <name>Print connection URL
cpctl db destroy <name>Destroy a database
cpctl connect <name>Open interactive database shell
cpctl metrics <service>View service metrics
cpctl gpu listList GPU inventory
cpctl gpu status <service>Show GPU utilization
cpctl gpu reserveReserve GPU capacity
cpctl gpu runRun a one-shot GPU job
cpctl node listList compute nodes
cpctl node status <id>Show node health
cpctl region listList regions
cpctl host listList hosts
cpctl policy listList scheduling policies
cpctl billing usageShow billing usage
cpctl billing historyShow invoice history
cpctl pay setupLink a card or USDC wallet for machine payments
cpctl pay statusShow linked payment method
cpctl pay authorize <service> <amount>Pre-authorize a per-call charge
cpctl pay historyList per-call payment charges
cpctl sandbox createCreate a sandbox
cpctl sandbox listList sandboxes
cpctl sandbox destroy <id>Destroy a sandbox
cpctl docsOpen documentation in browser
cpctl upgradeUpgrade the CLI
cpctl versionPrint CLI version

GPU Compute Platform