DocsCLI

CLI

The ruust command line: sign in, hatch an Egg from a repo, list your Eggs, read logs, open a shell in a container, and drive the rest over the versioned /api/v1 REST API.

The ruust command line is a small Go binary that talks to the Ruust control plane over the versioned /api/v1 REST API. It is deliberately focused: sign in, hatch an Egg from a Git repo, list the Eggs you own, read their logs, open an interactive shell in a container, and open an Egg in your browser. Running ruust with no subcommand opens an interactive dashboard of your Eggs when you are signed in, where pressing s on a selected Egg opens its shell. Anything the CLI does not yet have a command for (setting environment variables, adding a custom domain) is done in the dashboard or by calling the same REST API directly, which this page shows.

Install it

The CLI is open source at [github.com/RuustRun/cli](https://github.com/RuustRun/cli). The quickest way to install it on macOS or Linux is Homebrew. You can also grab a prebuilt binary for your platform from the latest release, or build it yourself with Go 1.24 or later.

bash
brew install ruustrun/tap/ruust

ruust version
Install with Homebrew and check it runs.
bash
git clone https://github.com/RuustRun/cli.git
cd cli
go build -o ruust .
mv ruust /usr/local/bin/ruust

ruust version
Or build the ruust binary from source.

Sign in

Run ruust login. It opens your browser, you sign in on the website and approve this computer, and no password is ever typed into the terminal. The returned session token is written to ~/.config/ruust/config.json with owner-only permissions, and every other command reads it from there. Use ruust whoami to confirm who you are signed in as, and ruust logout to forget the token on this machine (your Eggs keep running). For CI, pass --email and --password to sign in without a browser, or set RUUST_TOKEN directly (see Configuration).

bash
ruust login
# --no-browser prints the sign-in link instead of opening it.
# For CI, sign in without a browser:
ruust login --email [email protected] --password "$RUUST_PASSWORD"
Sign in through the browser, or non-interactively for CI.

Deploy it

  1. Push your app to a Git repository Ruust can reach.
  2. Run ruust login if you have not signed in on this machine.
  3. Run ruust create --repo <git url> to hatch a new Egg, adding --region and --tier if you want something other than the defaults.
  4. Watch it go from incubating to hatched with ruust logs <name>.
  5. Open the live Egg with ruust open <name>.
bash
ruust create \
  --repo https://github.com/you/app.git \
  --branch main \
  --region eu-west \
  --tier standard
Hatch a new Egg. Only --repo is required; branch defaults to main, region to eu-west, tier to standard.

The --repo flag is the only required one. --branch defaults to main, --region to eu-west (London; us-east is Virginia), and --tier to standard. ruust deploy is an alias of ruust create, so either name works.

List and inspect Eggs

Run ruust ls (aliases ruust eggs and ruust list) to see every Egg you own as a table of name, region, tier, lifecycle state, and URL, with the flat monthly total in GBP. Read an Egg's recent log lines with ruust logs <name>, narrow the output with --lines N, and jump straight to a hatched Egg in your browser with ruust open <name>.

bash
ruust ls
ruust logs my-egg --lines 100
ruust open my-egg
ruust status
List Eggs, read the last 100 log lines, open one, and check region availability.

Shell into a container

Run ruust shell <name> to open an interactive shell inside an Egg's running container, like docker exec -it but to a container on a Ruust host. It is a real terminal, so tab completion, colours, and resizing work, and you land as the container's user (usually root) in its working directory. Type exit or press Ctrl-D to leave. The first connection can pause for up to about ten seconds while the host picks the session up on its next poll, which is normal, not a hang. The dashboard has the same thing behind a Shell tab on the Egg page. See [Shell access](/docs/shell) for the full picture.

bash
ruust shell my-egg
# root@36cb0f65a247:/app# ls
# root@36cb0f65a247:/app# exit
Open a shell in a running Egg, then exit.

The port

The CLI hatches the Egg, but the same port contract still decides whether it comes to life. Ruust sets a PORT environment variable, and your app must listen on it and bind to 0.0.0.0, not localhost. Binding to localhost or a hard-coded port is the top reason an Egg builds cleanly but never hatches, and it will show up as a stuck hatching state in ruust logs.

javascript
const port = process.env.PORT || 3000;
app.listen(port, '0.0.0.0');
Read PORT from the environment and bind to 0.0.0.0.

Environment variables and domains

The CLI does not yet have commands to set environment variables or add a custom domain. Set both in the dashboard, or drive the same versioned REST API the CLI uses. Every endpoint sits under /api/v1/ and takes your session token as a Bearer header. Variables set on an Egg are available at build and run time, are encrypted at rest, and are never printed in logs.

bash
HOST="${RUUST_HOST:-http://localhost:3939}"
TOKEN="$RUUST_TOKEN"

# Read an Egg, including its env keys and domains
curl -sS "$HOST/api/v1/eggs/$EGG_ID" \
  -H "Authorization: Bearer $TOKEN"
Call the same /api/v1 API the CLI uses, with a Bearer token.

Configuration and scripting

Config lives at ~/.config/ruust/config.json (honouring XDG_CONFIG_HOME) and holds the API host, session token, and email. For scripts and CI, two environment variables override the file without touching it: RUUST_HOST sets the API host (also settable per run with the global --host flag) and RUUST_TOKEN supplies the session token. The environment variables win over the stored config, so a CI job can point at a host and authenticate without ever running ruust login.

bash
export RUUST_HOST=https://api.eu-west.ruust.run
export RUUST_TOKEN="$RUUST_CI_TOKEN"

ruust ls
ruust create --repo "$CI_REPO_URL" --tier small
Drive the CLI in CI with env overrides, no interactive login.