# CLI reference

> Every sitesolide command and flag, grouped by what it acts on, from the server to a project, access, tokens and agents.

The `sitesolide` CLI is one executable. Commands that act on a project run from its folder, the one holding its `sitesolide.json`.

## Global options

| Option | Effect |
|---|---|
| `--json` | Prints one JSON event per line, ending with a `result` or an `error`. Every command takes it but `init` and `run`: see [Agents](agents.md). |
| `--dry-run` | Shows what the command would do, and changes nothing. Taken by `setup`, `upgrade`, `refresh`, `deploy`, `lock`, `unlock` and `remove`. |
| `--api` | Sends the command through the dashboard's API, even when a server is configured. |
| `--help` | After any command, prints help instead of running it. |
| `SITESOLIDE_CONFIG_DIR=<dir>` | Before any command, reads that installation's configuration folder instead of `~/.config/sitesolide`. |

## Server

| Command | Effect |
|---|---|
| `sitesolide setup <user@host> --zone <dns.zone> --email <you@example.com>` | Installs a fresh Debian 13 server: hardening, DNS records and every component. Resumable, and a no-op once done. |
| `sitesolide setup <user@host> --contact <you@example.com>` | Sets the address shown on the page that asks for a preview code. |
| `sitesolide setup <user@host> --user <name>` | Names the account that deploys, `deploy` by default. |
| `sitesolide setup <user@host> --skip-dns` | Lists the DNS records to create by hand, and waits for them. |
| `sitesolide setup <user@host> --dns-replace` | Replaces DNS records that point elsewhere, on your decision alone. |
| `sitesolide setup <user@host> --cloudflare-token-stdin` | Reads the Cloudflare token from standard input. |
| `sitesolide setup <user@host> --minimal` | Leaves out backups, the installer and the egress proxy. |
| `sitesolide setup <user@host> --any-os` | Goes on with a system other than Debian 13, at your own risk. |
| `sitesolide setup <user@host> --config-dir <dir>` | Keeps a second installation's configuration in its own folder. |
| `sitesolide upgrade` | Brings every installed component to this release's code, redeploying only what differs. Resumable. |
| `sitesolide refresh <slug>` | Writes a project's units again from the manifest on the server, without sending code. |
| `sitesolide refresh --all` | Refreshes every project, one at a time, stopping at the first that fails. |
| `sitesolide init --server <user@host> --zone <dns.zone> --email <you@example.com>` | Writes `~/.config/sitesolide/config.json` for a server already set up. Takes `--contact` too. |
| `sitesolide init --sites <path>` | Names your sites repository, whose manifests may point `source` outside their own repository. |
| `sitesolide help` | Prints the list of commands, with or without a configuration. |
| `sitesolide --version` | Prints the release this binary was built from. |

## Cloud machine

Each command reads the Hetzner token from `HCLOUD_TOKEN`, or from standard input with `--token-stdin`.

| Command | Effect |
|---|---|
| `sitesolide machine create --provider hetzner --name <name>` | Orders a VM with its firewall and your SSH key, ready for `setup`. |
| `sitesolide machine create --provider hetzner --name <name> --type <type>` | Picks the server type, `cx23` by default. |
| `sitesolide machine create --provider hetzner --name <name> --location <location>` | Picks the location, `fsn1` by default. |
| `sitesolide machine create --provider hetzner --name <name> --image <image>` | Picks the image, `debian-13` by default. |
| `sitesolide machine create --provider hetzner --name <name> --backups` | Turns on the provider's daily backups, about 20% on the price. |
| `sitesolide machine create --provider hetzner --name <name> --ssh-key <path.pub>` | Uploads that public key instead of the default one in `~/.ssh`. |
| `sitesolide machine list --provider hetzner` | Lists the machines sitesolide created, with their addresses and price. |
| `sitesolide machine destroy <name> --provider hetzner` | Deletes the machine and its firewall, for good. |
| `sitesolide machine destroy <name> --provider hetzner --confirm <name>` | Takes the name typed back, where no terminal can ask for it. |
| `sitesolide machine destroy <name> --provider hetzner --delete-key` | Deletes the SSH key uploaded for it too. |

## Project

| Command | Effect |
|---|---|
| `sitesolide detect` | Prints the `sitesolide.json` this folder implies, and writes nothing. |
| `sitesolide detect --write` | Writes it, never over an existing one. |
| `sitesolide detect --slug <name>` | Names the project, rather than after its folder. |
| `sitesolide deploy` | Prepares, builds, pushes, installs, restarts and verifies the project. |
| `sitesolide deploy --dry-run` | Shows the systemd unit and the Caddy block, and builds and installs nothing. |
| `sitesolide deploy --dry-run --build` | Runs the build too, on your workstation. |
| `sitesolide deploy --dry-run --compare` | Builds, then lists what would change on the server. |
| `sitesolide deploy --force` | Switches a hand-written unit to the generated one. |
| `sitesolide deploy --yes --slug <name>` | In a folder with no `sitesolide.json`, writes the inferred one, then deploys. |
| `sitesolide status` | Shows what the server actually runs, one line per unit. |
| `sitesolide logs` | Shows the project's journal, every service interleaved by time. |
| `sitesolide logs --follow` | Keeps following the journal. |
| `sitesolide logs --lines <n>` | Goes `<n>` lines back, 50 by default. |
| `sitesolide backups` | Lists the project's data snapshots, read only. |
| `sitesolide domain` | Shows where the project's own domain stands. |
| `sitesolide domain --activate` | Switches the site onto its domain, then rebuilds the domain table. `--force` switches even before the DNS points at the server. |
| `sitesolide domain --deactivate` | Puts the site back on its preview address. |
| `sitesolide remove --confirm <slug>` | Takes the project off the server, for good. |
| `sitesolide run -- <command>` | Loads the secret files the manifest declares from `~/.config/sitesolide/secrets/`, then runs the command. |

> [!WARNING]
> `remove` and `machine destroy` cannot be undone. Run `remove` with `--dry-run` first.

## Access

| Command | Effect |
|---|---|
| `sitesolide share` | Shows the project's general access, and its people with access with their roles. |
| `sitesolide share <email>...` | Gives people access, Can open by default. A whole domain is written `@example.com`. |
| `sitesolide share <email>... --role <role>` | Gives the role named: `can-open`, `viewer`, `developer` or `admin`. |
| `sitesolide share <email> --expires 30d` | Sets how long password access lasts: `24h`, `7d` (the default), `30d` or `never`. |
| `sitesolide share --remove <email>...` | Takes their access away, from their next request. Takes a `@domain` too. |
| `sitesolide people` | Lists everyone with access, their roles, and who may create projects. |
| `sitesolide people <email> --may-create` | Lets them create projects, as Admin of what they create. |
| `sitesolide people <email> --no-create` | Takes that right back. |
| `sitesolide people --migrate-without-portal` | Carries access over without the portal's database, when it does not read. |
| `sitesolide lock` | Sets the site to Anyone with the code, and prints the code once. On a site with a code, prints the one in force. |
| `sitesolide lock --status` | Shows the lock wanted, installed and measured, without touching it. |
| `sitesolide lock --new-code` | Draws a new code: the old link stops opening the site. |
| `sitesolide unlock` | Makes the site Public again, its code dropped. |

Restricted is set from the dashboard's **Access** section only.

## With a token

A workstation with a token and no server goes through the dashboard, never SSH. `deploy`, `status`, `logs` (500 lines at most) and `share` work there too; `share` gives Can open alone, and `deploy` takes no `--dry-run`.

| Command | Effect |
|---|---|
| `sitesolide login --url https://dashboard.<zone>` | Keeps the token, typed at a prompt that does not echo it, and checks it. |
| `sitesolide login --url https://dashboard.<zone> --token-stdin` | Reads the token from standard input. |
| `sitesolide secrets` | Lists the project's secret files and variable names, never a value. |
| `sitesolide secrets set <NAME>` | Sets a variable of `<slug>.env`, typed at a prompt that does not echo it. |
| `sitesolide secrets set <NAME> --stdin` | Reads the value from standard input, one trailing line break dropped. |
| `sitesolide secrets remove <NAME>...` | Takes variables out of `<slug>.env`. |
| `sitesolide secrets set <NAME> --restart` | With `set` or `remove`, restarts the service afterwards and says whether it holds. |
| `sitesolide restart` | Restarts the project's service, and says whether it holds. |

The `secrets` commands need a token minted with **Manage secrets**. `SITESOLIDE_API` and `SITESOLIDE_TOKEN`, both in the environment, win over the files.

## Agents

| Command | Effect |
|---|---|
| `sitesolide mcp` | Serves the commands to an agent, over MCP on standard input and output. |

See [Agents](agents.md) for the `--json` events and the MCP tools.

## Related

- [Manifest reference](manifest.md): every key of `sitesolide.json`.
- [Deploy a project](deploy.md): the deploy loop, step by step.
- [Teammates and tokens](tokens.md): deploy without SSH.

Full reference: https://github.com/cthiriet/sitesolide/blob/main/docs/commands.md
