|
| 1 | +# Deployment Guide |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +ObjectOS can run in two modes: |
| 6 | + |
| 7 | +| Mode | Command | Description | |
| 8 | +|---|---|---| |
| 9 | +| **Self-hosted** | `pnpm start` | Single Node.js process serving API + static assets | |
| 10 | +| **Vercel** | Push to Git | Serverless function (API) + CDN (static assets) | |
| 11 | + |
| 12 | +--- |
| 13 | + |
| 14 | +## Build Outputs (dist folders) |
| 15 | + |
| 16 | +| Output | Path | Contents | |
| 17 | +|---|---|---| |
| 18 | +| Admin Console (SPA) | `apps/web/dist` | Vite build — HTML/JS/CSS | |
| 19 | +| Documentation (static) | `apps/site/out` | Next.js static export — HTML/CSS | |
| 20 | +| Server Plugins | `packages/*/dist` | tsup bundles — ESM + CJS | |
| 21 | + |
| 22 | +Run `pnpm build` (Turborepo) to build everything. Build order is managed |
| 23 | +automatically via workspace dependency graph. |
| 24 | + |
| 25 | +--- |
| 26 | + |
| 27 | +## Self-Hosted Deployment (`pnpm start`) |
| 28 | + |
| 29 | +### How it works |
| 30 | + |
| 31 | +``` |
| 32 | +pnpm start |
| 33 | + └─ pnpm objectstack:serve |
| 34 | + └─ objectstack serve --port 5320 |
| 35 | + └─ Hono + @hono/node-server |
| 36 | +``` |
| 37 | + |
| 38 | +`objectstack serve` boots the ObjectStack Kernel: |
| 39 | + |
| 40 | +1. Reads `objectstack.config.ts` for plugin list and metadata patterns |
| 41 | +2. Loads all plugins (Auth, RBAC, Workflow, Automation, etc.) |
| 42 | +3. Starts the Hono HTTP server on the configured port |
| 43 | +4. Mounts static directories for the Admin Console and docs |
| 44 | + |
| 45 | +### URL Routing |
| 46 | + |
| 47 | +| URL Pattern | Served By | |
| 48 | +|---|---| |
| 49 | +| `/api/v1/*` | Hono API routes (plugins register handlers) | |
| 50 | +| `/console/*` | `apps/web/dist` — Vite SPA (static mount, SPA fallback) | |
| 51 | +| `/docs/*` | `apps/site/out` — Next.js static HTML (static mount) | |
| 52 | + |
| 53 | +### Production Steps |
| 54 | + |
| 55 | +```bash |
| 56 | +# 1. Install dependencies |
| 57 | +pnpm install |
| 58 | + |
| 59 | +# 2. Build everything (packages + apps) |
| 60 | +pnpm build |
| 61 | + |
| 62 | +# 3. Start single-process server |
| 63 | +pnpm start |
| 64 | +# → http://localhost:5320/api/v1/health |
| 65 | +# → http://localhost:5320/console/ |
| 66 | +# → http://localhost:5320/docs/ |
| 67 | +``` |
| 68 | + |
| 69 | +### Docker |
| 70 | + |
| 71 | +```bash |
| 72 | +docker compose up -d |
| 73 | +# → http://localhost:5320 |
| 74 | +``` |
| 75 | + |
| 76 | +See `Dockerfile` for multi-stage build and `docker-compose.yml` for |
| 77 | +PostgreSQL + Redis services. |
| 78 | + |
| 79 | +### Environment Variables |
| 80 | + |
| 81 | +| Variable | Default | Description | |
| 82 | +|---|---|---| |
| 83 | +| `PORT` | `5320` | Server listen port | |
| 84 | +| `LOG_LEVEL` | `info` | Pino log level | |
| 85 | +| `CORS_ORIGINS` | `http://localhost:5321,http://localhost:5320` | Comma-separated allowed origins | |
| 86 | +| `NODE_ENV` | — | Set to `production` for production | |
| 87 | + |
| 88 | +--- |
| 89 | + |
| 90 | +## Vercel Deployment |
| 91 | + |
| 92 | +### Architecture |
| 93 | + |
| 94 | +On Vercel, the single-process server is split into two parts: |
| 95 | + |
| 96 | +``` |
| 97 | +Vercel CDN (Edge) Vercel Serverless (Node.js) |
| 98 | +┌──────────────────────┐ ┌───────────────────────────┐ |
| 99 | +│ apps/web/dist │ │ api/index.ts │ |
| 100 | +│ ├── index.html │ │ └─ bootstraps Kernel │ |
| 101 | +│ ├── assets/ │ │ └─ Hono app │ |
| 102 | +│ └── docs/ │ │ └─ /api/v1/* │ |
| 103 | +│ └── (site/out) │ │ │ |
| 104 | +└──────────────────────┘ └───────────────────────────┘ |
| 105 | +``` |
| 106 | + |
| 107 | +- **Static assets** (`apps/web/dist` + `apps/site/out`) are served by |
| 108 | + Vercel's global CDN. |
| 109 | +- **API** (`api/index.ts`) runs as a Vercel Serverless Function that |
| 110 | + bootstraps the ObjectStack Kernel on cold-start, then handles requests |
| 111 | + via the Hono adapter (`@hono/node-server/vercel`). |
| 112 | + |
| 113 | +### Files |
| 114 | + |
| 115 | +| File | Purpose | |
| 116 | +|---|---| |
| 117 | +| `vercel.json` | Build command, output directory, rewrites, function config | |
| 118 | +| `api/index.ts` | Serverless function — kernel bootstrap + Hono handler | |
| 119 | +| `apps/web/vite.config.ts` | Sets `base: '/'` when `VERCEL` env is detected | |
| 120 | + |
| 121 | +### Build Flow |
| 122 | + |
| 123 | +``` |
| 124 | +pnpm run build:vercel |
| 125 | + └─ turbo run build # Builds packages → apps (dependency order) |
| 126 | + ├─ packages/*/dist # Server plugins (tsup) |
| 127 | + ├─ apps/web/dist # Admin Console (Vite) |
| 128 | + └─ apps/site/out # Docs (Next.js static export) |
| 129 | + └─ cp -r apps/site/out apps/web/dist/docs # Combine into single output |
| 130 | +``` |
| 131 | + |
| 132 | +Output directory: **`apps/web/dist`** (includes `docs/` subfolder) |
| 133 | + |
| 134 | +### URL Routing on Vercel |
| 135 | + |
| 136 | +| URL Pattern | Destination | Type | |
| 137 | +|---|---|---| |
| 138 | +| `/api/v1/*` | `api/index.ts` serverless function | Rewrite | |
| 139 | +| `/docs/*` | Static files from `apps/web/dist/docs/` | CDN | |
| 140 | +| `/*` (other) | `index.html` (SPA fallback) | Rewrite | |
| 141 | + |
| 142 | +### Vercel Setup |
| 143 | + |
| 144 | +1. **Import the repository** in the Vercel dashboard |
| 145 | +2. **Framework Preset**: Other (not Next.js — this is a monorepo) |
| 146 | +3. Vercel auto-detects `vercel.json` and applies the configuration |
| 147 | +4. Push to the connected branch to trigger a deployment |
| 148 | + |
| 149 | +### Key Differences from Self-Hosted |
| 150 | + |
| 151 | +| Aspect | Self-Hosted (`pnpm start`) | Vercel | |
| 152 | +|---|---|---| |
| 153 | +| API runtime | Long-running Node.js process | Serverless function (cold-start) | |
| 154 | +| Static assets | Served by Hono static mounts | Served by Vercel CDN (Edge) | |
| 155 | +| SPA base path | `/console/` | `/` (root) | |
| 156 | +| Docs path | `/docs/` (static mount) | `/docs/` (CDN subfolder) | |
| 157 | +| WebSocket | Supported (`@objectos/realtime`) | Not supported (Vercel limitation) | |
| 158 | +| Background Jobs | In-process queues | Limited by function timeout (30s) | |
| 159 | + |
| 160 | +### Limitations on Vercel |
| 161 | + |
| 162 | +- **No WebSocket support** — `@objectos/realtime` requires a persistent |
| 163 | + connection. Use a separate WebSocket provider (e.g., Ably, Pusher) or |
| 164 | + self-host for realtime features. |
| 165 | +- **Cold-start latency** — The kernel bootstraps on first request to a |
| 166 | + serverless function instance. Subsequent requests reuse the warm instance. |
| 167 | +- **Function timeout** — Default 30 seconds (`maxDuration` in `vercel.json`). |
| 168 | + Long-running workflows or jobs should use external queues. |
| 169 | +- **No filesystem persistence** — Use external databases (PostgreSQL, MongoDB) |
| 170 | + instead of SQLite. The default `InMemoryDriver` works for demos but data |
| 171 | + is lost on cold-start. |
| 172 | + |
| 173 | +--- |
| 174 | + |
| 175 | +## Summary: Where is `dist`? |
| 176 | + |
| 177 | +``` |
| 178 | +objectos/ |
| 179 | +├── apps/ |
| 180 | +│ ├── web/ |
| 181 | +│ │ └── dist/ ← Admin Console (Vite SPA) |
| 182 | +│ │ ├── index.html |
| 183 | +│ │ ├── assets/ |
| 184 | +│ │ └── docs/ ← (Vercel only: copied from apps/site/out) |
| 185 | +│ └── site/ |
| 186 | +│ └── out/ ← Documentation (Next.js static export) |
| 187 | +└── packages/ |
| 188 | + ├── audit/dist/ ← @objectos/audit plugin |
| 189 | + ├── workflow/dist/ ← @objectos/workflow plugin |
| 190 | + ├── ... ← (all other packages) |
| 191 | + └── ui/dist/ ← @objectos/ui plugin |
| 192 | +``` |
0 commit comments