Hostodo CLI

Deploy, manage, and SSH into your VPS instances from the command line. Available for macOS, Linux, and Windows.

Quick Start

Get up and running in 3 commands:

# Install via Homebrew
brew install hostodo/tap/odo

# Login to your account
odo login

# List your instances and SSH in
odo list
odo ssh my-server

Installation

Homebrew (macOS & Linux)

The recommended way to install the Hostodo CLI:

# Add the Hostodo tap and install
brew tap hostodo/tap
brew install hostodo/tap/odo

# Or install directly
brew install hostodo/tap/odo

Download Pre-built Binary

Download binaries from the releases page. Available for macOS (Intel & Apple Silicon), Linux (amd64, arm64), and Windows (amd64).

# macOS (Apple Silicon)
curl -L https://github.com/hostodo/odo-cli/releases/latest/download/odo_Darwin_arm64.tar.gz | tar xz
sudo mv odo /usr/local/bin/

# Linux (amd64)
curl -L https://github.com/hostodo/odo-cli/releases/latest/download/odo_Linux_x86_64.tar.gz | tar xz
sudo mv odo /usr/local/bin/

Package Managers

# Debian / Ubuntu
wget https://github.com/hostodo/odo-cli/releases/latest/download/odo_Linux_x86_64.deb
sudo dpkg -i odo_Linux_x86_64.deb

# RHEL / CentOS / Fedora
wget https://github.com/hostodo/odo-cli/releases/latest/download/odo_Linux_x86_64.rpm
sudo rpm -i odo_Linux_x86_64.rpm

From Source

Requires Go 1.25 or higher:

git clone https://github.com/hostodo/odo-cli.git
cd odo-cli
make install

Authentication

The CLI uses OAuth device flow for secure authentication. When you run odo login, a browser window opens where you authorize the CLI with your Hostodo account. Your tokens are securely stored in the OS keychain (macOS Keychain, Linux Secret Service). On systems without a keychain, a plain token file is stored at ~/.odo/token with strict 0600 permissions.

Login

odo login

This opens your default browser to authorize the CLI. Once approved, you're authenticated and ready to go.

FlagDescription
--api-urlUse a custom API URL (default: https://api.hostodo.com)

Logout

Clear stored credentials:

odo logout

Current User

Display information about the authenticated user:

odo whoami

Active Sessions

View your active CLI sessions:

odo auth sessions

Security: Tokens are stored in the OS keychain, never in plain-text config files. The config file (~/.odo/config.json) only stores the API URL and device ID. File permissions are set to 0600 automatically.

Listing Instances

List all your VPS instances. Aliases: ls, ps.

# Interactive TUI (default)
odo list

# JSON output for scripting
odo list --json

# Simple ASCII table
odo list --simple

# Detailed view with all info
odo list --details
FlagDescription
--jsonOutput as JSON
--simpleOutput as simple ASCII table
--detailsShow detailed information
--limitMax instances to fetch (default: 100)
--offsetOffset for pagination (default: 0)

The default interactive TUI supports keyboard navigation:

Instance Status

Get detailed information about a specific instance:

odo status my-server
odo status my-server --json

Displays basic info, network configuration, resource allocation (RAM, CPU, disk, bandwidth), plan details, billing information, and timestamps.

Example output:

Instance: abc123 Hostname: server1.hostodo.com IP Address: 192.168.1.100 Status: provisioned Power: running Resources: 4096 MB RAM, 2 CPU, 50 GB Disk Bandwidth: 45.20 / 1000 GB Plan: Starter VPS Template: Ubuntu 22.04 Region: US-East Billing: $5.00 / monthly Next Due: 2025-12-08

Power Control

Start

Start a stopped instance. Waits up to 30 seconds for the instance to boot:

odo start my-server

Stop

Stop a running instance. Waits up to 60 seconds for graceful shutdown:

# Graceful shutdown
odo stop my-server

# Force immediate shutdown
odo stop my-server --force

Restart

Restart an instance. Waits up to 90 seconds:

# Graceful restart
odo restart my-server

# Force restart
odo restart my-server --force
FlagApplies ToDescription
-f, --forcestop, restartForce immediate shutdown without graceful stop

SSH Access

Connect to an instance via SSH using the system ssh binary. The SSH user is auto-detected from the OS template. If key-based auth fails and the instance has a default password, the CLI automatically retries using sshpass.

# SSH with auto-detected user
odo ssh my-server

# Specify a different user
odo ssh my-server --user ubuntu

# Pass extra flags to the ssh binary (after --)
odo ssh my-server -- -L 8080:localhost:8080
odo ssh my-server -- -A -v
FlagDescription
-u, --userSSH user (default: auto-detected from OS template)

New instances: Host keys for freshly deployed instances are accepted automatically (StrictHostKeyChecking=accept-new). Changed keys on known hosts are still rejected for security.

Password fallback: Requires sshpass to be installed. Install with brew install hudochenkov/sshpass/sshpass on macOS or sudo apt install sshpass on Linux. Skip this by adding an SSH key with odo keys add.

Rename

Rename an instance by updating its hostname:

odo rename my-server new-name

Reinstall

Wipe and reinstall the OS on an existing instance. Optionally specify a different OS template and SSH key. This is destructive — all data on the instance will be lost.

# Interactive — prompts for OS and SSH key
odo reinstall my-server

# Specify OS template
odo reinstall my-server --os "Debian 12"

# Specify OS and SSH key
odo reinstall my-server --os "Ubuntu 22.04" --ssh-key mykey
FlagDescription
--osOS template name (skips OS prompt)
--ssh-keySSH key name to inject
-y, --yesSkip confirmation prompt

Note: Reinstall is a long-running operation (stop + wipe + rebuild). The CLI waits up to 10 minutes for completion. The new root password is displayed on success.

Hostname Resolution

All instance commands accept hostnames as the primary identifier. The CLI resolves hostnames using a three-step fallback:

  1. Exact match — Full hostname match (e.g., my-server)
  2. Prefix match — Unambiguous prefix (e.g., my-s resolves to my-server if unique)
  3. Instance ID fallback — Direct instance ID (e.g., ins::abc123)

Tab completion for hostnames is available when shell completions are enabled.

Deploy Instances

Deploy a new VPS instance with an interactive wizard or by passing flags. Aliases: new, create.

Interactive Mode

Run odo deploy without flags for a guided experience. The wizard walks you through selecting an OS template, region, plan, hostname, and optional SSH key.

odo deploy

Non-interactive Mode

Skip prompts by passing flags:

# Deploy with specific options
odo deploy --os "Ubuntu 22.04" --region DET01 --plan EPYC-2G1C32GN

# Custom hostname
odo deploy --hostname my-server

# Apply a promo code
odo deploy --promo LETCLI

# Skip confirmation
odo deploy --os "Ubuntu 22.04" --region DET01 --plan EPYC-2G1C32GN --yes

# Fully scripted deploy with promo
odo deploy --os "Ubuntu 22.04" --region DET01 --plan EPYC-2G1C32GN --billing-cycle monthly --promo LETCLI --yes

# JSON output (requires --os, --region, --plan)
odo deploy --os "Ubuntu 22.04" --region DET01 --plan EPYC-2G1C32GN --json
FlagDescription
--osOS template name (skips OS prompt)
--regionRegion name: DET01, LV01, TPA01
--planPlan name (e.g. EPYC-2G1C32GN)
--hostnameCustom hostname (skips auto-generation)
--ssh-keySSH key name to use for authentication
--billing-cycleBilling cycle: monthly, annually, semiannually, biennially, triennially
--promoPromo code for a discount (e.g. LETCLI)
-y, --yesSkip confirmation prompt
--jsonJSON output (requires --os, --region, --plan)

Invoices

List your invoices with optional filtering. Alias: bills.

# List all invoices
odo invoices

# Show only unpaid invoices
odo invoices --status=unpaid
FlagDescription
--statusFilter by status (e.g., unpaid)

Pay Invoice

Pay an invoice by its ID using your default payment method:

odo pay INV-12345

# Skip confirmation prompt
odo pay INV-12345 --yes
FlagDescription
-y, --yesSkip confirmation prompt

SSH Key Management

List Keys

odo keys list

Add a Key

# Add key inline
odo keys add mykey "ssh-rsa AAAAB3NzaC1yc2EAAA... user@host"

# Add key from file
odo keys add mykey --file ~/.ssh/id_rsa.pub
FlagDescription
--fileRead public key from file

Remove a Key

Aliases: rm, delete.

odo keys remove mykey

Output Formats

Commands that display data support multiple output modes:

Interactive TUI (default)

A keyboard-navigable, color-coded table that adapts to your terminal size. Use arrow keys or j/k to navigate, Enter to view details.

JSON (--json)

Structured JSON output, perfect for scripting and piping to tools like jq:

# Get running instances as JSON
odo list --json | jq '.[] | select(.status == "running")'

Simple Table (--simple)

Clean ASCII table for quick viewing or piping:

ID HOSTNAME IP ADDRESS STATUS POWER RAM (MB) CPU DISK (GB) abc123 server1.hostodo.com 192.168.1.100 provisioned running 4096 2 50 def456 server2.hostodo.com 192.168.1.101 provisioned stopped 2048 1 25

Detailed View (--details)

Comprehensive, human-readable output per instance:

Instance: abc123 Hostname: server1.hostodo.com IP Address: 192.168.1.100 Status: provisioned Power: running Resources: 4096 MB RAM, 2 CPU, 50 GB Disk Bandwidth: 45.20 / 1000 GB Plan: Starter VPS Template: Ubuntu 22.04 Region: US-East Billing: $5.00 / monthly Next Due: 2025-12-08

Configuration

Config File

Configuration is stored at ~/.odo/config.json:

{
  "api_url": "https://api.hostodo.com",
  "device_id": "a1b2c3d4-..."
}

Access tokens are stored separately in the OS keychain. On systems without a keychain, a plain token file is stored at ~/.odo/token with 0600 permissions.

Permissions: Config file permissions are automatically set to 0600 (owner read/write only) and directory permissions to 0700.

Environment Variables

VariableDescription
HOSTODO_API_URLOverride the default API URL (must be https://)
HOMEUsed to locate the config directory
# Use a custom API endpoint
export HOSTODO_API_URL=https://custom-api.example.com
odo login

Shell Completion

Generate completion scripts for your shell. This enables tab-completion for commands and hostnames.

# Bash
odo completion bash > /etc/bash_completion.d/odo

# Zsh
odo completion zsh > "${fpath[1]}/_odo"

# Fish
odo completion fish > ~/.config/fish/completions/odo.fish

Global Flags

All commands support these flags:

FlagDescription
--configConfig file path (default: $HOME/.odo/config.json)
-h, --helpShow help for any command
-v, --versionShow CLI version