Deployment Overview

How Nebutra ships in production — Cloudflare edge, Vercel for marketing/docs, ECS for app/auth/API — plus Docker self-host options.

Deployment options

OptionBest forComplexityCost
Split (recommended for Nebutra.com)Marketing on Vercel + app/API on a Cloud VMMediumInfrastructure + optional Vercel
Vercel (frontends only)Docs, landing, optional web/auth cutoverLowHobby/Pro usage limits
Docker / PM2 self-hostedData residency, full controlMediumYour VMs
Cloudflare Workers (gateway)Edge API entry (see monorepo target config)MediumWorkers free tier + paid overages

Production architecture (nebutra.com today)

Public DNS sits on Cloudflare (CDN / WAF). Origins are split:

User


Cloudflare DNS + proxy

  ├─── apps/landing     nebutra.com           → Vercel
  ├─── apps/sailor-docs      nebutra.com/docs      → Vercel

  ├─── apps/web              app.nebutra.com       → ECS (PM2 Next standalone)
  ├─── apps/auth             auth.nebutra.com      → ECS (PM2 auth-center)
  ├─── backends/gateway      api.nebutra.com       → ECS (PM2 Hono / Node)
  └─── apps/idp              sso.nebutra.com       → ECS (OIDC issuer; keep stable)

              ├─── PostgreSQL (Supabase / Neon / RDS)
              ├─── Redis / KV (Upstash or Cloudflare KV)
              └─── ClickHouse (metering / analytics)
HostnameAppSteady-state host
nebutra.comapps/landingVercel
nebutra.com/docsapps/sailor-docsVercel
app.nebutra.comapps/webECS (Next standalone). Vercel project nebutra-web is optional cutover
auth.nebutra.comapps/authECS. Vercel project nebutra-auth is optional cutover
api.nebutra.combackends/gatewayECS (not Vercel Functions in production)
sso.nebutra.comapps/idpECS (permanent issuer — move carefully)

See also monorepo ops: docs/DOMAINS.md and docs/ops/nebutra/web-auth-vercel-cutover.md.

Web build note

apps/web default pnpm build is Vite. Production ECS (and Vercel if you cut over) must use pnpm --filter @nebutra/web run build:next so .next / standalone is produced. Official workflow: .github/workflows/deploy-ecs.yml.

Service-to-service auth

Internal x-service-token is a short-lived HS256 JWT (@nebutra/auth signServiceToken / verifyServiceToken). Legacy hex-HMAC tokens are rejected. Same contract on Python and Go helpers.

Before you deploy

Run database migrations

Always run migrations before shipping a schema-dependent app version:

pnpm db:migrate

Validate environment variables

Required env vars are validated at startup. Missing secrets should fail fast. At minimum for auth + app:

VariableNotes
AUTH_PROVIDER / NEXT_PUBLIC_AUTH_PROVIDERProduction: better-auth
BETTER_AUTH_SECRETSame value on auth + web
BETTER_AUTH_URL / NEXT_PUBLIC_AUTH_URLhttps://auth.nebutra.com
AUTH_COOKIE_DOMAIN.nebutra.com
DATABASE_URLShared Postgres
SERVICE_SECRETS2S JWT signing

CI/CD with GitHub Actions

WorkflowRole
ci.ymllint → typecheck → build → test on PR/push
deploy-ecs.ymlManual fallback: Next standalone + gateway tarball → VM PM2
Vercel Git integrationAuto-deploy landing + docs (and optional web/auth projects)
deploy-gateway.yml / deploy-origin-ecs.ymlPer-service adapters, gated by DEPLOY_TARGET_GATEWAY / DEPLOY_TARGET_PYTHON_AI; no workflow deploys to Kubernetes

Hobby Vercel has a daily deployment quota (~100 deployments/day; canceled/skipped can still count). Each linked project may open a deployment slot per push, so:

  • scripts/vercel-ignore-build.sh only builds when that app’s scope changed (app dir + its workspace deps), not the whole monorepo.
  • ECS-primary surfaces (web / auth / gateway) skip Vercel auto-deploy unless you set VERCEL_ALLOW_ECS_OPTIONAL=1 or commit with [vercel:apps/web] (etc.).
  • On Hobby, prefer Git-connected only for landing + docs; keep optional cutover projects disconnected or optional.

Zero-downtime

  • Vercel frontends: promote after green build; rollback via previous deployment.
  • ECS PM2: release directories + current symlink (ecs-deploy-remote.sh); keep previous release for one-step rollback.

How is this guide?

Edit on GitHub

Last updated on

On this page