Skip to content
BetaShare feedback
Sahabti

Projects

A project 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 Projects.

Projects 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 — projects that were relying on it show as Disconnected with a Reconnect action.

Import a repository

Projects → New Project lists the repositories the installation can see. Pick one and fill in:

  • Branch — the production branch. Pushes here trigger a deploy.
  • Project name — lowercase letters, numbers, and inner dashes. It becomes part of your app's URL, so pick something you'll recognise.
  • Root directory — the subdirectory to build from; leave it at ./ for a repository root. This is the field for a monorepo.
  • 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.
  • Build settings (optional) — leave them empty and the platform detects everything.

Hit Deploy and the first build starts immediately.

Your app's URL

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

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

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

Serving a project under your own domain isn't available yet — the panel says so rather than accepting a domain it can't route.

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 a project builds, and the higher one always wins:

  1. sahabti.json in your repository — config committed next to the code.
  2. The project'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 verbatim — the platform generates nothing and gets out of the way.

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

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 in Settings → General and the branch still tracks: the project 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 project 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

Settings → Environment holds the variables injected into the project 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.

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

Delete

Settings → General → Danger zone deletes the project, its container, and its deployment history. The GitHub installation stays connected for your other projects.

Next steps