Skip to content

Commit 544892a

Browse files
authored
Merge pull request #235 from objectstack-ai/copilot/evaluate-vercel-deployment
2 parents 1d9959e + ec43b6b commit 544892a

File tree

4 files changed

+206
-5
lines changed

4 files changed

+206
-5
lines changed

DEPLOYMENT.md

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
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+
```

README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,20 +214,27 @@ with API proxy to ObjectStack at `:5320`.
214214
### Production
215215

216216
```bash
217-
# Build frontend assets
218-
pnpm web:build
219-
pnpm site:build
217+
# Build all packages and apps
218+
pnpm build
220219

221220
# Start single-process server
222221
# Serves API + /console (SPA) + /docs (static)
223222
pnpm start
224223
```
225224

225+
### Deploy to Vercel
226+
227+
The project includes `vercel.json` and `api/index.ts` for Vercel deployment.
228+
Static assets are served from CDN; the API runs as a serverless function.
229+
230+
See [Deployment Guide](./DEPLOYMENT.md) for full details.
231+
226232
---
227233

228234
## Documentation
229235

230236
- [Architecture Guide](./ARCHITECTURE.md)
237+
- [Deployment Guide](./DEPLOYMENT.md)
231238
- [Development Plan](./DEVELOPMENT_PLAN.md)
232239
- [Contributing Guide](./CONTRIBUTING.md)
233240

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"dev:all": "concurrently -n api,web,site -c blue,green,yellow \"pnpm objectstack:serve\" \"pnpm web:dev\" \"pnpm site:dev\"",
2121
"start": "pnpm objectstack:serve",
2222
"build": "turbo run build",
23+
"build:vercel": "turbo run build && cp -r apps/site/out apps/web/dist/docs",
2324
"test": "turbo run test --concurrency=3",
2425
"lint": "turbo run lint",
2526
"clean": "turbo run clean",

vercel.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
{
22
"$schema": "https://openapi.vercel.sh/vercel.json",
3-
"buildCommand": "pnpm run build",
3+
"buildCommand": "pnpm run build:vercel",
44
"outputDirectory": "apps/web/dist",
55
"installCommand": "pnpm install --no-frozen-lockfile",
66
"framework": null,
7+
"cleanUrls": true,
78
"functions": {
89
"api/**/*.ts": {
910
"maxDuration": 30
1011
}
1112
},
1213
"rewrites": [
1314
{ "source": "/api/v1/(.*)", "destination": "/api" },
14-
{ "source": "/((?!api/).*)", "destination": "/index.html" }
15+
{ "source": "/((?!api/|docs/).*)", "destination": "/index.html" }
1516
]
1617
}

0 commit comments

Comments
 (0)