Skip to content

Deploy a static site

A static app is files. The CLI packs a directory, uploads the archive, and waits until https://<slug>.tori.cloud serves those files. Nothing runs in a container, so environment variables do not apply. The CLI refuses tori env set on a static site; see Environment variables.

An app is static or a service for its whole life. A static site cannot later become a service. Create a new app with --service or --image in a directory that has no tori.json if you need a container — see Deploy a container service.

From the project root:

Terminal window
npx tori.host

or, with an explicit directory:

Terminal window
npx tori.host deploy ./dist

Detection, when you omit the directory, is documented in the quickstart. Flags live on tori deploy.

The first deploy writes tori.json with the app slug. Later deploys from that directory update the same app. Put tori.json in git; do not hand-edit the slug to a name you do not own.

If the machine has no saved token, deploy opens a browser (or prints a device code). In CI set TORI_TOKEN. Revoke a token in the console under Settings → API tokens. See Sign in.

The upload can take minutes on a slow link. The progress line on stderr is how you tell a wait from a hang; when stderr is a pipe (CI), progress is periodic lines instead.

Archives over the CLI’s local size cap are refused before the request starts. The server also enforces the plan’s artefact limit, a per-file size cap, and a limit on how many members the archive may contain. A single file that is too large fails after upload with a reason such as artifact contains a file larger than 64 MB. Unsafe paths (.., absolute names) are refused the same way.

A very slow upload can be closed by the API with HTTP 408 before the last byte arrives. That is a server request deadline, not a broken connection. Retry from a faster link; nothing was deployed.

live means the files of this deploy are the ones the URL serves. Ctrl+C stops watching; it does not cancel an upload that already finished. There is no separate “promote” step.

If another deploy of the same app is already in progress, the server refuses the new upload with HTTP 409 and nothing is sent. Wait, or inspect it with npx tori.host deploy status.

In the console, open the app → deploys for the same history. Rollback is offered there for a previous static deploy whose files have not been reclaimed yet.

An app can use a hostname you already own if the plan includes custom hostnames. The console hides Add domain when the plan has none; the API refuses with a message that names the plan. tori whoami and Settings show the plan.

When the plan allows it:

  1. In the console, open the app → domains, or run npx tori.host domains add www.example.com from the directory that holds tori.json.
  2. Create the DNS record the command prints — a CNAME to the app’s *.tori.cloud name for a subdomain, or an A record to the zone’s addresses for a two-label name.
  3. npx tori.host domains check www.example.com re-runs the check (at most once per 30 seconds). A certificate is issued only after the record points here.

See tori domains for flags. Do not point a hostname at Tori until the add command has reserved it — the printed record is the one to create.

Terminal window
export TORI_TOKEN=tori_# Settings → API tokens
npx tori.host deploy ./dist

Progress becomes periodic lines because stderr is not a terminal. The deploy still waits until the URL is live.

See tori deploy for flags and the API for the HTTP side of the same flow.

Download this page as Markdown.