Bonsai Cloud
Git push → live. Connect a repo and Bonsai Cloud provisions the web app, DNS, TLS, and the deploy webhook — then every push after that deploys itself.
Introduction
Bonsai Cloud is managed hosting for landing pages and small sites. You point it at a GitHub repository and a domain; it creates everything needed to serve that site and wires up continuous deployment. There's no dashboard clicking and no infrastructure to babysit.
It handles the whole loop for you:
- The web app on tuned Nginx (native for static, hybrid for PHP)
- A database, provisioned automatically for Laravel & WordPress
- The DNS record (auto-created for Cloudflare-managed domains)
- A Let's Encrypt certificate, renewed automatically
- An auto-deploy webhook so every push goes live
- Instant, non-destructive rollback when you need it
Deploy to any of your servers by name. Static sites (plain HTML plus Astro, Vite, Eleventy, Hugo, Gatsby, SvelteKit, Next, Nuxt, Jekyll), PHP landers, Laravel and WordPress, and long-running Node services are all first-class.
Quickstart
From zero to a live, HTTPS site in three commands.
1. Install the CLI
npm install -g @bonsaicloud/cli
2. Connect your account
bonsai init stores your token and picks your default server and team. It's interactive and only needs to run once.
bonsai init
bonsai doctor # verify connectivity
3. Deploy
bonsai deploy acme \
--repo edgedigital/acme-lander \
--domain acme.example.com
✓ Web app created
✓ DNS record created (acme.example.com → 77.42.25.95)
✓ Repo attached · webhook registered
✓ SSL issued (Let's Encrypt, dns-01)
✓ Deployment triggered
Done. acme → https://acme.example.com · ~50s
That's it — the site is live over HTTPS, and every push to the branch redeploys it. Run it from inside the repo and the preset is auto-detected; you can omit the name too.
The deploy command
bonsai deploy <name> --repo <owner/repo> --domain <fqdn> [options]
A single deploy runs the full provisioning sequence:
- Creates the web app on your server
- Grants the deploy user read access to the repo
- Attaches the repo and registers the push webhook
- Adds the domain and requests a certificate
- Triggers the first deployment
- Writes a
bonsai.jsonto the repo so later commands know the target
Options
| Flag | Description |
|---|---|
--repo | GitHub repository, owner/repo or a full URL. Required (except wordpress). |
--domain | Domain or subdomain to serve on. Required. |
--preset | See the presets table. Auto-detected from a local checkout if omitted. |
--server | Target server, by alias or id. Defaults to your default server. |
--branch | Branch to deploy. Defaults to main. |
--start | Entry script for a Node service (--preset node). Defaults to server.js. |
--no-ssl | Skip certificate issuance (serve over HTTP only). |
Presets
A preset tells Bonsai how to build (if at all) and which directory to serve. It's auto-detected from your repo; pass --preset to be explicit.
| Preset | Build | Served |
|---|---|---|
html | — | files as-is |
astro | npm ci && npm run build | /dist |
vite | npm ci && npm run build | /dist |
eleventy | npm ci && npm run build | /_site |
hugo | hugo --minify | /public |
gatsby | npm ci && npm run build | /public |
sveltekit | npm ci && npm run build | /build |
next | npm ci && npm run build | /out (static export) |
nuxt | npm ci && npm run generate | /.output/public |
jekyll | bundle exec jekyll build | /_site |
php | — | Apache + PHP-FPM |
laravel | composer install · artisan migrate | /public + database |
wordpress | native install | Apache + PHP-FPM + database |
node | npm ci && npm run build | long-running process |
php preset runs on a hybrid Nginx + Apache stack, so a lander's .htaccess and form handler work as-is. Secrets live in a server-side config.php (git-ignored) that you create once — see the FAQ.
Servers
Bonsai deploys across all of your servers. Register each one once, then target it by a short alias on any deploy.
bonsai server add overpass # pick the server + user interactively
bonsai server ls # list configured servers (* = default)
bonsai server use overpass # set the default target
bonsai deploy acme --repo edge/acme --domain acme.co --server atlas
Omit --server and the deploy goes to your default. Every site remembers which server it lives on, so logs, redeploy, rollback, and rm always act on the right one.
Frameworks & apps
Beyond static sites and PHP landers, Bonsai provisions database-backed frameworks and long-running apps.
Laravel
Bonsai creates the web app on a hybrid stack, provisions a dedicated database and user, and sets a deploy script that runs composer install, artisan migrate, and the config caches. It prints the database credentials for your one-time server-side .env, then you deploy for real:
bonsai deploy shop --repo edge/shop --domain shop.co --preset laravel
# → add the printed DB creds + APP_KEY to .env on the server, then:
bonsai redeploy shop
WordPress
WordPress uses a native install that provisions the site and its database for you. Bonsai asks for the site title and admin details, generates the admin password, and requests SSL — no repo needed.
bonsai deploy blog --domain blog.co --preset wordpress
.env or generated passwords — they're shown once and live only on your server. Add API keys and other secrets to that file, then redeploy.
Node services
Run long-running Node apps — SSR servers (Next, Nuxt), Express APIs, anything that listens on a port. Bonsai builds the app, then keeps the process alive under a supervisor with auto-restart.
bonsai deploy api --repo edge/api --domain api.co --preset node --start server.js
The build seeds a port into .env; add any other environment there and reload the process to pick it up:
bonsai restart api # reload after a new build or an .env change
restart ships it.
Domains & SSL
Pass any domain to --domain. For domains on a connected Cloudflare account, Bonsai creates the DNS record for you and issues the certificate via DNS-01 validation — no manual steps. For other providers, point an A record at your server first; Bonsai checks that it resolves before requesting the certificate.
Certificates are Let's Encrypt and renew automatically. HTTPS is typically live within a minute of deploying.
Auto-deploy & rollback
After the first deploy, the push webhook is live: every push to the branch builds and goes live automatically. No dashboards, no manual redeploys.
Shipped something you'd like to undo? Roll back to any previous commit — non-destructively (a new commit restores the old content, so history is preserved):
bonsai rollback acme # pick from recent commits
bonsai rollback acme --to 85e6c46 # or target a specific commit
Roll "forward" again with a normal push.
CLI reference
| Command | What it does |
|---|---|
bonsai init | Configure the CLI (token, default server, team). |
bonsai doctor | Verify configuration and connectivity. |
bonsai server <add·ls·use·rm> | Manage the servers you deploy to. |
bonsai deploy <name> | Provision + deploy a site in one command. |
bonsai list | List the sites you've deployed. |
bonsai logs [name] | Show the latest deploy / activity log. |
bonsai redeploy [name] | Trigger a deployment manually. |
bonsai restart [name] | Reload a Node service's process (new build / .env). |
bonsai rollback [name] | Roll the live site back to a previous commit. |
bonsai open [name] | Open the live URL in your browser. |
bonsai rm [name] | Delete a site (guarded by a confirmation). |
Commands that take [name] default to the bonsai.json in the current directory, so inside a repo you can just run bonsai redeploy.
Configuration
Config lives in ~/.bonsai/config.json (written by bonsai init). Every value can be overridden with an environment variable — handy for CI:
| Variable | Purpose |
|---|---|
BONSAI_TOKEN | API token for your account. |
BONSAI_GITHUB_TOKEN | GitHub token for repo access + the webhook. |
BONSAI_SERVER | Default server alias to deploy to. |
BONSAI_SERVER_ID | Override the default server's id (for CI). |
BONSAI_DEPLOY_TEAM | GitHub team granted read access to lander repos. |
BONSAI_BASE_DOMAIN | Default base domain for new sites. |
FAQ
No. Static (HTML + any generator — Astro, Hugo, Next, Nuxt, SvelteKit, Gatsby, Jekyll, Vite, Eleventy), PHP landers, Laravel, WordPress, and long-running Node services are all supported. Database-backed frameworks get a database provisioned automatically.
Yes — --preset node builds your app and keeps the process alive under a supervisor with auto-restart. SSR servers (Next, Nuxt) and Express APIs all work. A one-time proxy step points your domain at the process; Bonsai prints it after deploying.
Yes. Register each server with bonsai server add and target any of them with --server <alias>. Each site remembers its own server, so lifecycle commands always hit the right box.
The webhook URL and other secrets live in a server-side config.php that's git-ignored and created once on the server. It survives redeploys, and Bonsai keeps it (and the lead store) out of public reach.
Yes — bonsai rollback restores a previous version in seconds, without rewriting history.
On tuned Nginx on dedicated hardware — no cold starts, no per-request billing, no noisy neighbours.
It's free during early access. We'll introduce plans down the line; nothing you deploy now will be pulled out from under you.