Skip to content
Beta

Web apps

A web app is an app the platform builds from a GitHub repository and runs for you. Push to the tracked branch and a new build ships; if it breaks, roll back to the exact image that was serving before. Everything on this page is in the dashboard under Web apps.

Web apps run on the same isolation model as instances: each app is its own container, and nothing is shared with another workspace.

Connect GitHub first

Open Integrations in your workspace and connect GitHub. That installs the Sahabti GitHub App on the account or organisation you pick and grants this workspace access to the repositories you select — you choose them, not us, and you can widen or narrow the selection later from the same page.

The grant belongs to the workspace. Another workspace you're a member of doesn't inherit it, and revoking the installation on GitHub stops deploys immediately — apps that were relying on it show as Disconnected with a Reconnect action.

Import a repository

Web apps → Deploy an app lists the repositories you can see on GitHub within the installation — read with your own GitHub account, so a repository the installation covers but you can't open on GitHub is neither offered nor accepted. Pick one and fill in:

  • Branch — the production branch. Pushes here trigger a deploy.
  • Root directory — the subdirectory to build from; leave it at ./ for a repository root. This is the field for a monorepo.
  • Automatic deployments — on by default; see Deploy on push.
  • App name — lowercase letters, numbers, and inner dashes. It becomes part of your app's URL, so pick something you'll recognise.
  • Connected resources — link instances of the workspace, and each one's connection string is added as an environment variable that points at its private name.
  • Environment variables — the config and secrets your app needs. Paste a whole .env file into a key field and every line is added at once.

Hit Deploy and the first build starts immediately. Build settings are on the app's General page once it exists; leave them empty and the platform detects everything.

Your app's URL

Every web app is served over HTTPS at a hostname of its own:

text
https://<app-name>-<suffix>.sahabti.app

The short suffix keeps the hostname unique across the platform, so two workspaces can both have an app called web. The URL appears on the app's page as soon as it is created, and Visit opens it.

To serve it under your own domain too, add the hostname on the app's Domains page: it lists a TXT record that proves you own the domain and a CNAME that points the hostname at the platform, and the certificate follows on its own. The default URL keeps working.

How the build works

The platform detects your stack and generates the build for it. Detected frameworks:

JavaScriptNext.js, Nuxt, Astro, SvelteKit, React Router, Vite, Node.js
Other runtimesPython, Go
No frameworkStatic sites, and any repository with its own Dockerfile

Three layers decide how an app builds, and the higher one always wins:

  1. sahabti.json in your repository — build configuration committed next to the code.
  2. The app's Build settings — the dashboard override layer: framework, install/build/start commands, output directory, Dockerfile path.
  3. Auto-detection — what runs when neither of the above says anything.

Choosing the Docker framework, or setting a Dockerfile path, builds your repository's own Dockerfile — the platform generates nothing. Your environment variables are never build arguments, so an ARG receives nothing from the dashboard; they reach build steps as a mounted secret instead, which keeps them out of image layers. Build configuration covers what that means for a Dockerfile you maintain.

Every app gets the platform's standard container footprint. There is no size to pick and none to pay per app.

Watch it deploy

The Deployments tab lists every build, newest first, and each row expands to its live build log. A deployment moves through five steps:

  1. Cloning repository — at the exact commit the deploy was triggered by.
  2. Detecting framework — resolving the three layers above into one build plan.
  3. Building image — the image is built away from the app container and pushed to the platform registry.
  4. Deploying container — the new image starts alongside the old one and has to answer a health check before it takes over. If it doesn't, the previous version is restored and the deployment is marked failed — your app keeps serving throughout.
  5. Live — the new version is serving.

A failed step is named, with the build output right there. Build logs are kept for 30 days; after that the row keeps its steps, status and commit, and the log reads expired.

Deploy on push

Automatic deployments is on by default. Every push to the production branch queues a deployment tagged Git push, matched on the repository itself rather than its name — renaming the repo on GitHub doesn't break the link.

Turn it off on the app's General page and the branch still tracks: the app shows New changes not deployed when the branch has moved past what's live, and you deploy when you're ready.

Redeploy, roll back, cancel

  • Redeploy runs a fresh build of the tracked branch and replaces the current version once it succeeds. One redeploy per app per minute — pushes aren't rate-limited.
  • Rollback re-ships the exact image a past successful deployment shipped. Nothing is rebuilt, so it's the same code that was serving before, and it lands as a new deployment at the top of the timeline rather than rewriting history.
  • Cancel removes a queued deployment from the queue, or stops a running build. Once a build has finished and the container swap has started, cancel is refused — that window is the one place where stopping halfway would take your app down. Roll back once it's live instead.

Environment variables

The app's Environment page holds the variables injected into the app at build and at runtime. Values marked secret are masked in the UI. Bulk add takes a pasted KEY=value block, skipping blank lines and # comments.

Each value is a single line. JSON works as long as it is on one line (a service-account key, for example — quotes and braces arrive in the container exactly as typed); pretty-printed JSON and multi-line PEM keys are refused rather than truncated. For a certificate or key, store it base64-encoded, or as a JSON string with \n escapes, and decode in the app.

Saving offers Save & redeploy: variables are baked into the build, so they take effect on the next deploy, not on the running container.

Delete

Delete app, in the Danger zone of the app's General page, deletes the app, its container, and its deployment history. The GitHub installation stays connected for your other apps.

Next steps