• Get started

    • Getting started
    • Concepts
    • Tour
  • Using shpyrd

    • Deploying
    • shpyrd.yaml
    • Resources
    • Databases and caches
    • Domains and exposure
    • Sign-in for your app
    • Teams, roles and security
    • AI assistants (MCP)
    • Logs
    • Dashboard
    • CLI reference
  • Running it yourself

    • Installation
    • Oracle Cloud (OKE)
    • AWS (EKS)
    • Extensions and sign-in
    • Platform backups
    • Architecture guide
  • Project

    • Design principles
    • Roadmap
    • How to contribute
    • Support the project
  1. Using shpyrd
  2. CLI reference
Add toClaudeClaude CodeClaudeClaudeOpenAICodexCursorCursorVisual Studio CodeVS Code

CLI reference

Every shpyrd command and its flags.

shpyrd is the CLI for people who deploy and run projects: it signs in to your workspace with shpyrd login - on shpyrd cloud, https://acme.shpyrd.app - and needs no kubeconfig: every developer command speaks the workspace API. shpyrd-ctl, installed alongside it, is for running shpyrd yourself: the operator who installs and runs the platform (the cluster, extensions, accounts, backups). With a kubeconfig named on the command line (--context, --kubeconfig) it goes through the cluster instead, as shpyrd-ctl always does. Project commands take --project <slug> or read project: from shpyrd.yaml in the current directory; -v prints verbose output. Commands contributed by extensions explain themselves when the extension is not enabled: pg and redis (a project's resources) live in shpyrd, users, auth and object-storage (the platform's) in shpyrd-ctl.

For scripts and agents

Every command takes --json: the result is printed as one JSON document on stdout and nothing else (progress and hints go to stderr), with the shapes the workspace API uses, so a script or an agent reads it instead of parsing a table. --jq <expression> filters that document the way gh --jq does: strings print raw, everything else as compact JSON. Interactive commands (shell, run, pg psql, redis cli, logs) stream as they always did.

shpyrd projects list --jsonshpyrd projects list --jq '.[].slug'shpyrd releases --project shop --jq '.[-1].number'shpyrd deploy --json | jq .release

Inputs can come from files too. shpyrd secrets set and shpyrd globals set take --from-file <path>: a dotenv file (one KEY=VALUE per line, # comments, optional export, single or double quotes) or, when it starts with {, a JSON object of strings; - reads stdin, and KEY=VALUE arguments on the same command line win over the file. Flags that carry a secret (login --token, users add --password, mail set --password, sso add --client-secret) take @path to read the value from a file instead of the shell history.

shpyrd secrets set --from-file .env.production --project shopshpyrd secrets set --from-file - --project shop < vars.jsonshpyrd login --url https://acme.shpyrd.app --token @token.txt

Signing in

CommandWhat it does
shpyrd login --signupCreate an account and your first workspace on shpyrd cloud from the terminal: the browser opens the signup with a code; you prove your email and name the workspace there, and when its door answers the CLI is signed in to it. shpyrd login with no URL at a terminal asks which of the two you want. --signup-url (or SHPYRD_SIGNUP_URL) points at another signup.
shpyrd login --url <workspace> [--token <token>]Sign the CLI in to a workspace (https://acme.shpyrd.app) and make it the current one; the credential is kept in ~/.shpyrd/sessions.json. Without --token the browser opens the workspace's sign-in: approve the code the terminal shows and the CLI is signed in as you for 30 days (--no-browser prints the link instead, for a shell over SSH); That creates a session token, listed under Workspace → API tokens as CLI on <host> and revoked there. With --token, a personal API token (below) or, for the operator, the admin token from shpyrd-ctl cluster token. SHPYRD_URL and SHPYRD_TOKEN work without a saved session: set them in CI. A token the workspace rejects is not saved.
shpyrd use [workspace]List the workspaces you are signed in to (* marks the current one), or switch. Commands talk to the current workspace; with several sessions and none current they ask you to pick.
shpyrd whoamiWho you are at the current workspace, checked live; fails when the token expired or was revoked.
shpyrd logoutForget the current workspace's credential (or --url another's).
shpyrd tokens create <name>Create an API token for CI or another machine: --platform-role platform-viewer|platform-admin or --project <slug> --role user|viewer|developer|admin, --expires 90d. The value is printed once. A token never carries more than you hold at the moment it is used, and a token cannot create tokens: run this signed in as yourself (or with the admin token), or use the dashboard's Workspace → API tokens tab.
shpyrd tokens list, tokens revoke <id>Your tokens with role, expiry and last use (platform admins see everyone's); a session token is listed as session (your roles). Revocation is immediate.

Every developer command works signed in with shpyrd login, with no kubeconfig: run, shell -- <cmd>, pg psql and redis cli go through the web terminal's bridge, the server starting the one-off instance or picking the database's pod. On shpyrd cloud, databases, caches and custom domains are also at hand in the dashboard: the project's Resources and Domains cards.

Cluster

Self-hosted: operator commands, for running shpyrd yourself (on shpyrd cloud, we run the cluster). They live in shpyrd-ctl (installed alongside shpyrd by Homebrew and the release archives) and also answer as shpyrd cluster … when a kubeconfig is available.

CommandWhat it does
shpyrd cluster createCreate a kind cluster and install the base stack. --name, --workers, --image, --http-port, --https-port, --domain, --profile, --skip, --only, --set SHPYRD_X=y, --no-init.
shpyrd cluster initInstall or upgrade the base stack on the current context. Same profile flags; --yes for non-kind contexts. Cloud profiles: --profile oci or --profile aws with --vars-file <name>.vars (written by contrib/*/terraform: domain, addresses, zone, storage; flags and --set win over it), --set SHPYRD_ACME_EMAIL=..., --platform-exposure internal, --dns-key-file (OCI key), --backup-target s3://bucket/prefix --backup-credentials-file <file> for platform backups, --set SHPYRD_DATABASE_URL=postgres://… to use a managed database for the control plane instead of the in-cluster one, --registry-host <host> --registry-user --registry-token-file for a provider registry. Without the file: --dns oci|aws with --dns-zone-id --dns-region (aws) or --dns-compartment --dns-tenancy --dns-region --dns-user (oci), --internal-lb-subnet <ocid>, and --set for the rest. Explicit settings are recorded, so re-runs need no flags.
shpyrd cluster registryThe image registry: mode, health, storage used, images held, garbage collection and certificate. registry gc reclaims deleted images now (--wait).
shpyrd cluster statusHealth of every component, with versions and install times. Exit code 1 when something is not ready.
shpyrd cluster dashboardOpen the dashboard in the browser, signed in as you through a one-time login ticket (60 s). --no-open prints the URL and the link.
shpyrd cluster tokenPrint the admin token (Secret shpyrd-system/shpyrd-admin-token). --rotate replaces it, --disable/--enable switch it off and on (disable needs a login provider and a platform-admin team).
shpyrd cluster trust-caInstall the platform CA in the OS trust store: the development CA (--ca-dir) for local clusters, the cluster's own CA when --context points at a cloud cluster. Alias trust.
shpyrd cluster exportRender the base stack manifests to a directory for GitOps tooling (-o, profile flags).
shpyrd cluster backupBack up the platform's state now: an encrypted archive to the configured bucket (--wait, default). cluster backup key prints the passphrase to keep outside the cluster.
shpyrd cluster backupsTarget, schedule, last good backup, the archives in the bucket and the recent runs.
shpyrd cluster restoreRestore an archive into a cluster that runs the platform: --from s3://bucket/prefix[/archive] (newest by default) or --file, --passphrase-file, --credentials-file/--endpoint/--region/--aws-profile for the bucket, --project <slug> (repeatable), --no-system, --overwrite, --dry-run. See Platform backups.
shpyrd cluster destroyDelete the kind cluster (--name, --yes); with --context on a cloud cluster, remove everything the platform created in the cloud (projects and their data, load balancers, disks) and print the infrastructure command to finish.
shpyrd extensions listExtensions known to this build and whether they are enabled on the cluster.
shpyrd extensions enable <name>Install the extension's component and restart the server with it (--set). Also cluster init --enable <name>.
shpyrd extensions disable <name>Remove the component (--yes); refused while resources of the extension exist.
shpyrd users add <email>Create a local account (extension auth-local); --name, --password (prompted when omitted).
shpyrd users list, passwd <email>, rm <email>Manage local accounts.
shpyrd peopleThe workspace's people: everyone who has signed in or holds a role, with their role, login method and last sign-in.
shpyrd people role <email> owner|admin|member|noneSet or remove someone's workspace role (they need not have signed in yet). Naming or demoting an owner takes an owner; the last owner stays.
shpyrd people suspend|reactivate|forget <email>Switch someone's access off everywhere at once, back on, or remove their sign-in record (role and grants stay).
shpyrd invite <email>Invite someone: --role member|admin|owner (member by default), --team <name>. Prints the link once (emailed too when shpyrd-ctl mail set was run); signing in with that address accepts it.
shpyrd invitations, invitations revoke <email>Pending invitations; revoke one. Inviting again makes a new link.
shpyrd teams create <name>Create or update a team: --member <email>, --group <idp group>, --platform-role platform-admin|platform-viewer, --description.
shpyrd teams list, add <team> <email...>, remove <team> <email...>, delete <team> --yesManage teams (--group for identity provider groups).
shpyrd members add <project> --user <email>|--team <name> --role reader|user|viewer|developer|adminGrant a role on a project (reader opens the app read-only, user opens it; see Sign-in for your app).
shpyrd projects describe <project> --description "…" [--featured|--unfeatured]What the launcher shows for a project: the line under its name, and whether it is shown first and larger.
shpyrd workspaceThe workspace you are signed in to: name, address, dashboard, owners. workspace address <label> moves it (owners; the old address redirects 30 days); workspace domains add|verify|primary|alias|remove <host> manage custom domains.
shpyrd sso add google|microsoft|github|oidc --client-id ... --client-secret <secret|@file> [--hosted-domain] [--tenant] [--org] [--issuer] [--label]Add a sign-in method of this workspace (its login page only). sso list, sso remove <id>, sso platform-methods on|off.
shpyrd members list [project], remove <project> --user|--teamList and remove grants.

Log drains

CommandWhat it does
shpyrd drains add <url> [--name] [--header "Name: value"]... [--processes web,worker] [--format json|syslog] --project <slug> | --workspace <slug> | --clusterForward a project's, a workspace's or every project's lines to an HTTPS or syslog receiver (extension logs-agent).
shpyrd drains list [--project | --workspace | --cluster]Drains with delivery status and last delivery.
shpyrd drains remove <name> [--project | --workspace | --cluster]Remove a drain and its stored headers.

Global config vars

CommandWhat it does
shpyrd globals set KEY=VALUE...Set config vars every project of the workspace receives (workspace admins; --workspace names one over a kubeconfig). A "Global config change" release follows in every project that has not opted out.
shpyrd globals unset KEY...Remove global config vars.
shpyrd globals listNames and when each was set; values are never shown.

Sign-in providers

Self-hosted: the platform-wide sign-in methods of a cluster you run yourself. A workspace's own sign-in, on shpyrd cloud too, is shpyrd sso (above) or the dashboard's Workspace › Sign-in tab.

CommandWhat it does
shpyrd auth oidc set --id <id> --label <text> --issuer <url> --client-id <id> --client-secret <secret|@file>Add or update a company identity provider (extension auth-oidc); --scopes replaces the extra scopes (- for none). Prints the redirect URIs to register.
shpyrd auth oidc list / remove <id>List or remove providers (roles are kept, they are keyed by email).
shpyrd auth oidc check <id|issuer-url>Fetch the issuer's discovery document: endpoints, PKCE, scopes, claims, sign-out support.
shpyrd auth connector add github|google|microsoft|oidc --client-id ... --client-secret ... [--org] [--hosted-domain] [--tenant] [--issuer]A sign-in method through the bundled issuer (extension auth-local): GitHub, Google, Microsoft or any OpenID Connect provider; the button appears at once. Also on the dashboard's Workspace › Sign-in tab.
shpyrd auth connector list / remove <id>List or remove connectors.

Plans and economics

Self-hosted: platform-level, for the operator:

CommandWhat it does
shpyrd-ctl plans create <name> --cpu-hour 0.02 --memory-gib-hour 0.005 --storage-gib-month 0.10 --egress-gib 0.05 [--min-monthly 0] [--currency USD] [--free] [--sleep-after 15m --sleep-resuming page] [--postgres-sleep-after 10m] [--monthly-budget 10] [--cost-budget 0.50] [--self-serve] [--projects N --instances N --cpu 2 --memory 1Gi --storage 10Gi]Define the unit prices a workspace is billed at, and optionally: --free (nothing to pay; the Billing card shows the consumption alone); the plan's default sleep for projects (they sleep after the quiet period unless they set their own; shpyrd sleep <project> --after off opts out) and for databases (shpyrd pg sleep the same way); two monthly caps, --monthly-budget at the plan's prices and --cost-budget on what the workspace costs the platform (OpenCost; the operator's number, shown nowhere), either of which warns the owners at 80% and pauses the workspace at 100% until the month ends; whether people may pick the plan when they sign up; and the ceilings a workspace starts with.
shpyrd-ctl plans update <name> [--effective-from YYYY-MM-DD] [the flags of create]Change a plan's prices or settings from a date on: a new version is written, and every five minutes of use is priced at the version in force at its time, so past months keep theirs. Only the flags given change.
shpyrd-ctl plans history <name>A plan's versions, oldest first.
shpyrd-ctl plans listPlans and their prices, the version in force of each.
shpyrd-ctl plans assign <plan> --workspace <slug>Bill a workspace at a plan (its history is kept).
shpyrd-ctl economics [--month YYYY-MM]Revenue at plan prices, infrastructure cost from OpenCost (extension opencost) and gross margin per workspace. Operator-only; customers see usage and their plan's prices, never cost.

Email

Self-hosted: the platform's sender, set by the operator.

CommandWhat it does
shpyrd-ctl mail set --host <smtp> --from "<name> <addr>" [--port N] [--user U --password <secret|@file>] [--tls|--plain]The SMTP sender the platform uses for invitations (extension mail); STARTTLS on 587 by default. The password is stored in the cluster and never printed.
shpyrd-ctl mail status, test <address>, unsetShow the settings (without the password), send a test message from the server, remove the settings.

Projects

CommandWhat it does
shpyrd projects create "<name>"Create the project. The name is free text ("My Shop"); its slug (my-shop) is derived from it and identifies the project in --project, URLs and the hostname. --slug chooses it, --domain adds custom domains, --save writes shpyrd.yaml. (shpyrd apps still works as an alias.) New projects ask visitors to sign in; --public makes a site anyone can open.
shpyrd projects rename <slug> "<name>"Change the display name. The slug never changes.
shpyrd projects listTable of projects: slug, name, phase, release, URL, age.
shpyrd projects info <slug>Phase and message, URL, build digest, source, processes (with sizes and failing reasons), recent releases, and every resource of the project (app, attached resources, volumes).
shpyrd projects destroy <name>Delete the project and its namespace (--yes).

Deploying and running

CommandWhat it does
shpyrd deployArchive the committed tree of the current directory, upload, build and release. --working-tree deploys the directory as is; --git <url> --ref <rev> --path <dir> builds from Git; --dockerfile [path] builds the Dockerfile (auto-detected for local deploys); --image <ref> runs a prebuilt image; --no-wait returns immediately. Applies shpyrd.yaml (processes, sizes, build, domains).
shpyrd scale web=N worker=MSet instance counts per process type.
shpyrd resize web=SIZE worker=SIZESet instance sizes per process type (a release).
shpyrd sizes listThe cluster's instance size catalog with kind, cpu, burst and memory.
shpyrd sizes set <name> --kind shared|dedicated --cpu <cores> --memory <bytes> [--default]Add or change a size; processes using it are resized.
shpyrd sizes delete <name>, shpyrd sizes default <name>Remove a size (not the default), choose the default.
shpyrd secrets set K=V ...Set config vars (new release, rolling restart).
shpyrd secrets unset K ...Remove config vars.
shpyrd secrets listNames and last-updated times, plus variables provided by attached resources. Values are never printed.
shpyrd shell [-- cmd...]Interactive shell in a running instance (--process, --instance web.2); with a command, runs it and returns its exit code.
shpyrd run <cmd...>One-off instance of the current release with the config vars: streams output, returns the exit code, removes the instance. --size, --detach. Signed in, the server starts the instance and attaches the terminal through the web terminal's bridge; piped input reaches the command and ends when the pipe does.
shpyrd volumes create <name> --size 5GiCreate a persistent volume in the project (--class, --shared, --from-snapshot). Cloud profiles round the size up to the provider's minimum and say so.
shpyrd volumes listVolumes with size, mode, status and what mounts them.
shpyrd volumes resize <name> --size 10GiGrow a volume (when the storage class allows expansion).
shpyrd volumes delete <name>Delete a volume and its data (--yes; --force while mounted).
shpyrd volumes snapshot <volume> [--name <snapshot>]Take a snapshot of the volume (where the profile supports snapshots; --no-wait).
shpyrd volumes snapshots <volume>List the volume's snapshots (also snapshot list); snapshot rm <volume> <snapshot> --yes deletes one.
shpyrd volumes restore <volume> --from <snapshot> [--to <new-volume>]Restore a snapshot into a new volume, or in place (--yes: the mounting instances stop while the disk is replaced).
shpyrd object-storage listBuckets of the platform's object store with usage (extension object-storage).
shpyrd pg create <name> --project <p>Create a PostgreSQL database (extension postgres): --backups/--retention/--backup-schedule, --version, --size, --storage, --instances.
shpyrd pg list|info|psql|deleteManage databases; psql <name> -- <args> opens psql on the primary; delete is refused while attached (--force).
shpyrd pg backups enable|disable|list <name>Backups of a database (needs extension object-storage): continuous WAL archiving and a scheduled base backup (--retention 14d, --schedule "0 2 * * *"); list shows the base backups and the recovery window.
shpyrd pg backup <name>Take a base backup now.
shpyrd pg sleep <name> --after 30mStop the database after 30 min without client connections and wake it on the first one (about 30–40 s on a cloud block volume; volume and data kept; single-instance databases only). --after off disables — also when the workspace's plan has a default for databases. Attached apps are re-released once. See Databases.
shpyrd pg suspend <name>, shpyrd pg resume <name>Stop a database now and refuse connections until resumed (data kept), and bring it back.
shpyrd pg restore <name> --as <new> [--to <RFC 3339>]Restore into a new database at a point in time (latest when omitted); attach the app to it when ready.
shpyrd redis create <name> --project <p>Create a Valkey or Redis store (extension redis): --engine, --version, --size, --persistent, --storage.
shpyrd redis list|info|cli|deleteManage stores; cli <name> -- <args> runs valkey-cli or redis-cli.
shpyrd attach <resource>Attach a database or store to the app as config vars (--kind when ambiguous, --prefix). A release.
shpyrd detach <resource>Remove the attachment (a release).
shpyrd logsTail logs of every instance (web.1, worker.2...). -f follow, -p <process>, -n <lines>, --build for the latest build output.
shpyrd releasesRelease history with digests and descriptions.
shpyrd rollback [N]Re-release N (default: the previous release) with its build and config vars. Refused while another release is rolling out unless --force; --no-wait.
shpyrd redeployTry the current release again without a new release: new instances of it, or, after a failed build or with --rebuild, the same source built again. --no-wait.
shpyrd domains add <host>Serve the project at a hostname you own; prints the DNS record to create (CNAME to the project hostname, or A to the front door) and waits until it serves (--no-wait).
shpyrd domains list, rm <host>Custom domains with DNS and certificate state; stop serving one.
shpyrd exposure internal|externalWhich front door serves the project on cloud profiles (public or private load balancer). Release-free.
shpyrd access [set public|authenticated|identified]Who may open the app: sign-in required (the default), public, or public with signed-in visitors identified; without set, shows the mode and the roles that open it.
shpyrd sleep <project> --after 15m [--resuming page|wait]Scale the web process to zero after a quiet period (5m to 24h); the first request wakes it (about 6–7 s), either behind a branded "resuming" page or by holding the connection. --after off disables — also when the workspace's plan has a default. Needs the sleep extension on the cluster (shpyrd-ctl extensions enable sleep); the command says so otherwise. Nothing sleeps unless a project or its plan says so. While a project sleeps, its page and projects info say so instead of "0 of 1 running".
shpyrd billingMonth-to-date usage of the workspace and the estimate at its plan's prices, one line per project and component: web/worker (CPU core-hours, memory GiB-hours, egress GiB), postgres/<name>, redis/<name>, volume/<name> and build-cache (storage in GiB-months of provisioned capacity — on cloud profiles that is the provider's minimum volume size), build (build instances). Informational: no money changes hands until a payment provider is connected.
shpyrd openOpen the project URL in the browser.

Where things are

Self-hosted: where things are on your machine and on a cluster you run yourself.

~/.shpyrd/ca/development root CA (rootCA.pem, key); ~/.shpyrd/clusters/<name>/ the CA fetched from a cloud cluster
~/.kube/configkind writes the kind-shpyrd context here
namespace shpyrd-systemserver, registry (with its credential and certificate), node trust DaemonSet, ExternalDNS, admin token, install record, sessions mirror, Dex and its accounts when auth-local is enabled
namespace app-<name>one per project (label shpyrd.io/project): App, Volumes and their claims, Deployments, Services, Ingress and one Certificate per host that needs one, kpack Image and Builds or BuildKit Jobs, config var Secret, <app>-bindings and release snapshots
contrib/oci/Terraform for the Oracle Cloud network and cluster, kubeconfig.sh, tunnel.sh

On this page

  • For scripts and agents
  • Signing in
  • Cluster
  • Log drains
  • Global config vars
  • Sign-in providers
  • Plans and economics
  • Email
  • Projects
  • Deploying and running
  • Where things are
  • Docs

shpyrd is open source under MPL-2.0, and in beta.