oxid/ docs

// cli

Global options

Every command accepts these flags. Resolution order for both values is: flag > environment variable > active context > built-in default.

FlagEnvDefaultDescription
--api <url> OXID_API http://127.0.0.1:8080 Daemon base URL.
--token <t> OXID_TOKEN Bearer token for daemons configured with OXID_API_TOKEN. Sent as Authorization: Bearer … on every request.
--json off Machine-readable JSON on stdout; errors stay as plain text on stderr. Pair with exit codes (below) for scripts and CI.

Contexts (oxid context) persist both values per named daemon at ~/.config/oxid/config.toml, kubectl config-style.

Lifecycle

oxid up <branch> [--repo <url> --git-token <pat>]

Registers the repository (idempotent) and deploys branch: clone → build → inject secrets → run → route. Without --repo, registers the current directory (how a locally-run daemon sees your checkout). With --repo https://… the daemon clones the URL itself — how you register against a containerized daemon. Scp-style git@host:org/repo.git is normalized server-side; --git-token is stored encrypted for private repos. If the host is at capacity, the deploy is queued and retried automatically.

oxid up feature-login
[+] Environment live at: http://127.0.0.1:41253/
# against a containerized daemon:
oxid up main --repo https://github.com/you/app.git
oxid up main --repo https://github.com/you/private.git --git-token ghp_xxx

oxid rollback <branch> [--to <sha>]

Redeploys a branch at a prior commit. Without --to, rolls back to the deploy immediately before the current live one.

oxid pause <branch> · oxid wake <branch>

Manual scale-to-zero. pause suspends the container and returns its RAM; wake brings it back. With Traefik configured, the first HTTP request also wakes the environment on its own.

oxid down <branch> [--force] [--purge-secrets]

Destroys a branch's environment permanently. Asks for confirmation unless --force. Branch secrets are kept by default so a recurring branch's config survives a later redeploy; --purge-secrets removes them too.

OptionDescription
--forceSkip the confirmation prompt.
--purge-secretsAlso delete this branch's scoped secrets.

oxid rm-project [--force]

Deletes the project registered for the current directory — every environment, its secrets and the daemon's git cache for the repo.

Observation

oxid status [--sort key] [--filter text]

Environments for the current project: one row per branch, latest deploy wins.

OptionDescription
--sort branch|state|updatedRow order. Default is server order.
--filter <text>Keep rows whose state matches exactly or whose branch contains the text (case-insensitive).

oxid ps [--sort] [--filter]

Every registered project across the daemon. Same flags, applied to project names.

oxid logs <branch> [-f]

Container logs for a branch. One-shot snapshot by default; -f attaches to the daemon's SSE stream and prints lines as they're written — a real live tail, not polling. Ctrl+C detaches without touching the container.

oxid logs -f feature-login
listening on 0.0.0.0:3000 ...

oxid audit [branch] [filters]

The audit trail — every deploy, pause, wake and destroy, with operator and timing. With branch: the full history of that one environment. Without: the most recent events across every project.

OptionDescription
--limit <n>Max events without a positional branch (default 50).
--project <id>Only this project id.
--branch <name>Server-side branch filter for the cross-project feed.
--since / --until <rfc3339>Time window, e.g. 2026-08-01T00:00:00Z.
--kind <kind>Event type: deploy, pause, wake, destroy, …

oxid queue

Deploys waiting for host capacity, oldest first. Non-empty means admission control is doing its job, not that something is broken.

Secrets & configuration

oxid env set|list|delete

Environment variables with three resolution scopes — global, project, branch — resolved Global → Project → Branch at container start. Values are encrypted at rest (AES-GCM) and never shown back by list: names and scopes only.

oxid env set DATABASE_URL=postgres://... --scope project
oxid env set STRIPE_API_KEY=sk_... --scope branch --branch feature-login
oxid env list --scope project
oxid env delete STRIPE_API_KEY --scope branch --branch feature-login
OptionDescription
--scope global|project|branchScope of the operation (default global).
--project <id>Project id; auto-registered from the current directory when omitted.
--branch <name>Required when --scope branch.

oxid configure [--pause-after d] [--destroy-after d] [--git-token t]

Changes the current project's lifetime policy and private-repo access. oxid.toml only ever seeds these at first registration — later changes go through here and take effect on the next GC sweep, no redeploy.

OptionDescription
--pause-afterIdle timeout before scale-to-zero pause, e.g. 45m.
--destroy-afterMax lifetime before permanent teardown, e.g. 3d.
--git-tokenPAT for a private repository; empty string clears it. Write-only — never echoed back.

oxid context add|use|list|current|remove

Named daemon contexts, persisted at ~/.config/oxid/config.toml. Switch once, stop repeating --api/--token. Purely local — no daemon round-trip.

oxid context add staging --api https://oxid.internal:8080 --token eyJ...
oxid context use staging
oxid context list          # tokens masked to their last 4 chars
oxid context remove staging --force

Operations

oxid doctor

Health check: daemon reachability, version, latency, and whether the configured token authenticates. The first thing to run when anything feels off.

oxid backup <file> · oxid restore <file>

Consistent snapshot of the daemon's database + secret key as a .tar. Restore stages the upload and applies it on the daemon's next restart — the live database is never touched in place. Restoring requires OXID_ALLOW_RESTORE=1 on the daemon (see Daemon).

oxid rotate-key

Rotates the master encryption key, re-encrypting every secret under a fresh one with zero downtime. Requires the master OXID_API_TOKEN.

oxid token create|list|revoke

Named API tokens for handing out access without sharing the master credential. Repeatable --project <id> scopes a token to those projects only — every other project answers 404, and node-wide operations (stats, infra, backups, token management) are rejected. Unscoped tokens keep full access; audit events attribute actions to the token's name. create prints the raw token once — it is never retrievable again. Requires the master token.

oxid token create ci-bot --project 1 --project 3
oxid token list
oxid token revoke 3

oxid infra status · oxid infra setup

Inspect/bootstrap the Docker network + built-in Traefik container that real wake-on-request scale-to-zero needs. setup is idempotent — an already-satisfied step is left untouched, safe to re-run.

oxid completions <shell>

Prints a completion script to stdout, for zsh, bash, fish and friends.

oxid completions zsh > ~/.zfunc/_oxid

Exit codes

Scripts can branch on the failure kind instead of parsing stderr. With --json, successful output is a single JSON value on stdout.

CodeMeaning
0Success.
1Generic failure (bad input, daemon rejected the request).
2Not found — e.g. no environment for the given branch.
3Daemon unreachable (connection refused, DNS, timeout).
4Unauthorized — missing/invalid token (401/403).