A live preview URL for every branch you push
BTS turns every git branch into a running copy of your app — complete with its own Postgres, Redis, and storage — in under 60 seconds. Stop sharing one staging server. Start reviewing real working software on every pull request.
Connect a repo · Live URL in under a minute
$ git push origin feature/new-checkout
[nexos] webhook received
[nexos] building image on node eu-west-2
[nexos] provisioning postgres · redis · s3
[nexos] restoring seed (v3-with-orders) 4.2 MB
[nexos] container started · health check passed
preview → https://feature-new-checkout-acme.test.buildingswell.com
ready in 47sShipping software without preview URLs is a tax on your team
Most teams know they should have previews. Most teams do not, because the tooling makes it painful. Here is what that costs:
Waiting on staging
Your team shares one staging server. Every code review blocks on the last person who deployed — and nobody tested their branch in isolation.
Preview URLs cost a fortune
Spinning up a full stack on AWS for every pull request burns thousands of dollars a month on idle compute. Most teams give up and ship blind.
Databases reset on every push
You set up test data, find a bug, push a fix — and watch your seed wipe everything. Preview environments are unusable without persistent data.
Preview environments that actually act like production
A preview environment is a full, running copy of your application — not a static build, not a frontend-only deploy, but the actual stack. Your app container, your database with seeded data, your cache, your object storage — all wired together at a URL you can share.
BTS gives every git branch its own preview environment, automatically, the moment you push. No pipelines to author. No Kubernetes manifests to maintain. A webhook fires, a container starts, a URL goes live.
And because capacity is governed by fixed vCPU, vRAM, and build-minute ceilings rather than a meter, full-stack previews cost a fraction of what they do on AWS or GCP. You can afford one per branch, not one per team.
From git push to live URL in three steps
You write code. BTS does the rest.
Push to a branch
A GitHub webhook fires the moment you push. No CLI, no YAML pipelines, no extra config.
We build and provision
The scheduler picks a node with free capacity. BuildKit builds your image. Postgres, Redis, and storage come up in parallel.
Share the URL
Drop the preview link into a PR or Slack. Reviewers, designers, and QA all click through the real app — live data and all.
No DevOps. No pipelines. No infra to maintain.
Spinning up a BTS project is one config file — nexos.yaml at the root of your repo. It captures your Dockerfile, your port, the services you need, and your migrations. BTS reads it on every push and does the rest.
Don't want to write it yourself? Hand your AI assistant this link — test.buildingswell.com/docs/nexos-yaml/ai — and ask it to configure the project. The page is a self-contained spec written for AI agents. They detect your stack, generate the YAML, and (when your existing Dockerfile isn't preview-ready) create a Dockerfile.nexos that meets our requirements.
name: my-app
build:
dockerfile: ./Dockerfile
app:
port: 3000
services:
postgres: true
redis: true
hooks:
on_deploy: npx prisma migrate deployCommit it. Push. You have a preview URL.
$ git commit -am "tweak checkout" && git push
[nexos] fetching delta → feature/new-checkout
[nexos] web changed · rebuilding
[nexos] api, worker, migrations untouched · skipped
ready in 14s
preview → https://feature-new-checkout-acme.test.buildingswell.comA loop fast enough for humans — and AI agents
Every node keeps a persistent mirror of your repo, so a push fetches only the new commits — never a full clone — and BTS diffs the push to rebuild only what changed. Services whose files are untouched keep their running containers, and migrations re-run only when their files change.
Iteration time drops from minutes to seconds. That makes BTS the natural target for AI coding agents: point one at a live, full-stack environment with a real database and let it iterate with fast feedback — not against mocks.
- Incremental git fetches — persistent per-node mirrors, no full clones
- Unchanged services skip the rebuild — their containers keep serving
- Migrations re-run only when their files change
- Real Postgres, Redis, and storage, persisted across deploys
What you do with a URL per branch
Preview environments unlock workflows that are impossible with a single shared staging server.
Pull request reviews
Every PR gets a URL. Reviewers click through working changes instead of squinting at diffs.
Bug reproduction
Reproduce a customer bug on their exact seed data, fix it on a branch, share the fixed URL back.
Designer handoff
Designers see the real app on the real data, not a Figma mock. Feedback lands in hours, not sprints.
QA verification
QA sets up a test scenario once and verifies fixes across every subsequent push — data persists.
AI coding agents
Point an agent at a live, full-stack environment and let it iterate against a real database — not a mock.
Product demos
Show a WIP feature to stakeholders from a branch URL. Throw the environment away when you are done.
Everything a real preview environment needs
Not a static build. Not a frontend-only deploy. The full stack.
60-second deploys
Push to any branch. A live URL with your app, database, and storage is ready before you can finish your coffee.
Full-stack previews
Every branch gets its own Postgres, Redis, and any managed addon you enable — wired up automatically to your app container.
Persistent databases
Incremental deploys rebuild only your app container. Your data, user sessions, and test state survive every push.
Encrypted secrets
Environment variables are AES-256-GCM encrypted at rest with per-value initialization vectors. Never stored in plaintext.
Predictable resource ceilings
Every workspace carries hard vCPU, vRAM, and build-minute quotas. Hit a cap and deploys pause instead of quietly eating the whole node.
Live build logs
Stream BuildKit output and container logs into your dashboard over WebSocket. See exactly what is happening as it happens.
Questions, answered
The things teams ask before their first deploy.
What can I deploy on BTS?
Anything with a Dockerfile — Node, Python, Go, Rails, Elixir, you name it. No framework lock-in. Multi-service projects (app plus background workers, plus Postgres and Redis) work too.
Do my databases really persist across pushes?
Yes. Incremental deploys rebuild only the app container. Your Postgres, Redis, and object storage survive every push until you reset or destroy the environment — so test data and sessions stick around.
How do database migrations run?
Declare them as hooks in nexos.yaml (for example, on_deploy: npx prisma migrate deploy). They run automatically on each deploy. Migration jobs re-run only when their files actually change — unrelated pushes skip them.
Can I bring my own compute or self-host?
Yes. The node agent is a single Go binary you run on any server — join the shared global pool or keep nodes private to your team. The control plane and agent are open, so you are never locked in.
Still have a question? Email us or read the docs.
Give every branch its own URL
Connect a GitHub repo, push a commit, share the link. That is the whole workflow.
Connect a repo and ship your first preview
Get the BTS newsletter
Product updates, preview-environment tips, and the occasional deep dive. One email a month. No spam, unsubscribe anytime.