Skip to content

Guides

Apps

Markdown

Deploy from a source directory or a prebuilt image. Rolling deploys, secrets, logs, releases and rollbacks.

An app is a name with an address. It runs one or more machines from an image you deploy, or, for a static site, no machine at all. Machines, deploys, secrets, logs and releases all belong to an app.

App names are unique across all of Rytiv: 2 to 63 characters, lowercase letters, digits and hyphens, starting with a letter. A few names are reserved for the platform (for example api, console, docs and www, and every name that is rytiv or starts with rytiv-).

An app answers on https://<app>.rytiv.app. Extra ports of a machine answer on https://<port>-<app>.rytiv.app.

Point the CLI at a directory. Rytiv reads the project, builds it on its own machines and deploys the result:

ry deploy web --source .

Or run ry alone in the directory: it signs you in if needed, shows what it detected, asks for an app name and deploys.

ry

What is detected. Node.js projects with these frameworks: Next.js, SvelteKit, Nuxt, Remix, TanStack Start, SolidStart, Analog, Astro, Vite, Gatsby, Docusaurus, Create React App, VitePress, Eleventy and Angular, plus plain Node.js. A Dockerfile or Containerfile at the root of the directory wins over the detection; anything that is not Node.js needs one. ry detect shows the finding without changing anything.

Static sites (for example Astro without an adapter, Next.js with output: "export", Vite, or a folder with an index.html) need no machine: the built files are served directly.

ry deploy reads a rytiv.json in the current directory or above it, so a deploy needs no flags. ry config init <app> writes one. A flag on the command line always wins over the file.

{
"app": "web",
"source": ".",
"port": 3000,
"memoryMb": 512,
"vcpus": 1
}

Other keys: image (instead of source), diskMb, buildMemoryMb, count, start, healthPath, healthTimeoutS, restart, killSignal, killTimeoutS, sleep and env. An unknown key is an error.

ry deploy web --image nginx:alpine --port 80

POST /v1/apps answers 201, or 409 with name-taken if the name is used anywhere on Rytiv. POST /v1/apps/:name/deploy answers 202 with the deploy. Poll GET /v1/deploys/:id until status is done or error. On error, the answer names the reason in error and carries the last lines of the machine’s console in bootLog.

Field Type Default Notes
image string required An OCI reference such as nginx:alpine, or build:<id> for a build of yours
internalPort integer 3000 The port your app listens on
memoryMb integer kept, 512 for a new app 128 to 16384
vcpus integer kept, 1 for a new app 1 to 16
diskMb integer kept 512 to 131072
count integer kept, 1 for a new app Machines, 1 to 20
env object {} Plain environment variables. Use secrets for credentials.
start string Start command, run through /bin/sh -c
healthCheck object path for an HTTP check (empty: the port only), timeoutMs, intervalMs, healthyThreshold, maxWaitMs
restart object policy: never or on-failure, with retries 1 to 10. Without it, a crashed machine is restarted.
killSignal string the image’s, else SIGTERM Sent before a machine is stopped or replaced
killTimeoutS integer 30 Seconds between that signal and SIGKILL, 1 to 300

“Kept” means: a deploy that does not name the field keeps what the app’s machines have. Every other field comes from the request or its default, so send internalPort, env and start with every deploy.

A deploy starts a new machine, waits until it runs and answers on its port (and passes the health check, if you set one), then takes one old machine out of traffic and removes it, one at a time. If a new machine fails, the deploy stops, the new machine is discarded and the old version keeps serving.

An app with a volume works differently: its single machine stops before the new one starts, so there is a short gap.

An app sleeps only if you give it a sleep rule. Without one, its machines run until you stop them. Name the idle time on a deploy:

ry deploy web --sleep 5m

A machine that has had no requests and no CPU load for that long goes to sleep, and the next request wakes it. Up to 2 GB of memory it sleeps with its memory and resumes in about a quarter of a second; a larger machine stops instead and boots cold, and its files stay. --sleep off takes the rule away again, for a worker or a cron app that has to stay awake. In a deploy request the same rule is suspendPolicy, for example {"mode": "suspend", "idleSeconds": 300}.

Secrets are environment variables stored encrypted. Nobody can read them back, not even you: the API lists names, never values.

ry secrets set web API_KEY=example-value OTHER_KEY=other-value
Method Path What it does
PUT /v1/apps/:name/secrets {secrets, staged}. With staged: true (the default) the values apply at the next deploy. With staged: false Rytiv rolls the app now if a machine lacks the new value.
GET /v1/apps/:name/secrets name, updatedAt and managed for every secret. Never a value.
DELETE /v1/apps/:name/secrets/:key Removes one secret. 204.

Secrets that Rytiv manages for you, such as the DATABASE_URL of an attached database, cannot be changed or removed this way. Each secret carries a build choice: whether the next source build sees it. A new secret is marked for the build only when its name starts with a public prefix such as NEXT_PUBLIC_ or VITE_; ry secrets set <app> KEY --build marks one, --no-build takes the mark away.

ry logs web -f

GET /v1/apps/:name/logs answers {app, machines}, one entry per machine with the console output of that machine in text and a cursor. Pass cursor.<machineId>=<cursor> on the next call to get only what is new, and machine=<id> for one machine.

Logs are what your app’s machines write to their console.

Method Path What it does
GET /v1/apps/:name/machines The app’s machines
GET /v1/machines/:id One machine
POST /v1/machines/:id/start Start a stopped or suspended machine
POST /v1/machines/:id/stop Stop it
POST /v1/machines/:id/suspend Suspend it
POST /v1/machines/:id/destroy Remove it

A machine is requested, scheduled, starting, running, suspending, suspended, stopping, stopped, deleted or failed.

ry machines web
ry exec web -- ls -la /app

Every deploy is a release. A rollback deploys an earlier release’s image again, without a rebuild, with the app’s current settings. Secrets, volumes and databases stay as they are.

ry releases web
ry rollback web
Method Path What it does
GET /v1/apps/:name/releases The releases, which one runs, and which one a rollback would bring back
POST /v1/apps/:name/rollback {} for the previous release that went live, or {version} or {releaseId}. Answers 202 with the deploy.
ry apps destroy web

DELETE /v1/apps/:name removes the app and all its machines and answers 204. It cannot be undone. The CLI asks before it does this; pass --yes in scripts. An app that runs a database is removed with the database, not on its own.

Status Code When
400 name-reserved The name is reserved for the platform
409 name-taken The name is used somewhere on Rytiv
403 org-limit-apps An account on the starting credit can have 10 apps, computers included. See Credit and pricing.
402 credit-blocked The credit is used up: nothing new starts until a top-up. See Credit and pricing.
404 build-not-found build:<id> is not a build of your organization
409 deploy-in-flight Another deploy of this app is running
409 volume-needs-single-machine An app with a volume runs exactly one machine

See the CLI reference for every flag of ry deploy, and Apps and Deploys and releases in the API reference for every route with its fields. The guide Deploy a Next.js app walks the path from a directory to a URL.