odx CLI
Manage Odinex Cloud from your terminal and scripts.
odx is the command-line client for Odinex Cloud. If you know Hetzner's hcloud, you will feel at home: named
contexts hold project API tokens, every resource has list, describe, create, update and delete, and
long-running operations wait for their action and show progress.
Install
odx is written in Go. With Go 1.25 or newer:
go install odinex.cloud/odx@latestShell completion:
source <(odx completion bash) # bash
odx completion zsh > "${fpath[1]}/_odx" # zsh
odx completion fish | source # fishAuthenticate with a context
odx uses a project API token (odx_…). Create one in the console under
Projects → your project → API tokens, then create a context; the token is read from a hidden prompt:
$ odx context create my-project
Token: ********
Context my-project created and activated
$ odx context list
ACTIVE NAME ENDPOINT
* my-project https://api.odinex.cloud/v1
$ odx context use staging # switch
$ odx context active # print the active context
$ odx context delete stagingContexts are stored in ~/.config/odx/config.toml with file mode 0600.
Settings are taken from these sources, highest precedence first:
| Setting | Sources |
|---|---|
| context | --context, ODX_CONTEXT, the active context |
| token | ODX_TOKEN, the context's token |
| endpoint | --endpoint, ODX_ENDPOINT, the context's endpoint, https://api.odinex.cloud/v1 |
| config file | --config, ODX_CONFIG, ~/.config/odx/config.toml |
So ODX_TOKEN=odx_… odx server list works without any configuration file, which is handy in CI.
Examples
# Catalog
odx location list
odx server-type list
odx image list --type system
# SSH key and server
odx ssh-key create --name laptop --public-key-from-file ~/.ssh/id_ed25519.pub
odx server create --name web-1 --type t1 --image ubuntu-24.04 --location fra1 \
--ssh-key laptop --label role=web --user-data-from-file cloud-init.yaml
odx server list -l role=web
odx server describe web-1
odx server ssh web-1 # runs: ssh -l root <ipv4>
odx server metrics --type cpu web-1 # min/avg/max/last of the last hour
odx server poweroff web-1 && odx server change-type --type t2 --upgrade-disk web-1
odx server create-image --description "before upgrade" web-1
odx server set-rdns --hostname web-1.example.com web-1
# Volume attached to the server
odx volume create --name data --size 10 --server web-1
odx volume resize --size 20 data
# Firewall applied by label
cat > rules.json <<'JSON'
[{"direction": "in", "protocol": "tcp", "port": "22", "source_ips": ["0.0.0.0/0", "::/0"]}]
JSON
odx firewall create --name web --rules-file rules.json
odx firewall add-rule --direction in --protocol tcp --port 443 --source-ips 0.0.0.0/0,::/0 web
odx firewall apply-to-resource --type label_selector --label-selector role=web web
# Floating IP
odx floating-ip create --type ipv4 --name ip-1 --location fra1
odx floating-ip assign ip-1 web-1
# Load balancer with a label target
odx load-balancer create --name lb-1 --type lb11 --location fra1
odx load-balancer add-service --protocol http --listen-port 80 --destination-port 8080 lb-1
odx load-balancer add-target --label-selector role=web lb-1
# Clean up
odx load-balancer delete lb-1
odx floating-ip delete ip-1
odx volume detach data && odx volume delete data
odx server delete web-1Resources can be referred to by name or ID. Every command is listed in the command reference.
Output
List commands print a table. Change the format with the repeatable -o flag:
odx server list -o columns=id,name,ipv4,labels # pick columns (see odx server list --help)
odx server list -o noheader -o columns=id # for scripts
odx server list -o json # API objects as JSON
odx server describe web-1 -o yaml-l / --selector filters by labels: env=prod, env!=prod, env, !env; commas mean AND.
Actions and waiting
Commands that start an action (create, power, attach, …) poll GET /actions/{id} and show a progress line on stderr
until it finishes. --no-wait returns right after the request; odx action list and odx action describe <id> show
the state later. A failed action exits with code 1 and prints the action's error code and message.
Errors and exit codes
Errors are printed as error: <message> (<code>) on stderr. The codes are those of the API.
| Exit code | Meaning |
|---|---|
| 0 | Success |
| 1 | API error, failed action, network or file error |
| 2 | Usage error: unknown command or flag, bad argument, missing token |
--debug prints every HTTP request and response, including the rate limit headers, to
stderr. When the API answers 429, odx waits for Retry-After (at most 60 seconds) and retries up to 3 times.