Deployment
Deploy your noboil app to production — Convex Cloud, SpacetimeDB Maincloud, or self-hosted Docker.
Convex handles hosting, scaling, and backups automatically. Deploy to Convex Cloud or self-host with Docker. See convex.dev/docs for the full deployment guide.
Local development
Start SpacetimeDB with Docker Compose:
docker compose up -dThis starts SpacetimeDB at ws://localhost:4200 (WebSocket) and http://localhost:4200 (HTTP API). File uploads are stored inline as byte arrays.
Publish your module (replace my-app with your SpacetimeDB module name):
spacetime publish my-app --module-path backend/spacetimedb/Generate bindings:
spacetime generate \
--lang typescript \
--module-path backend/spacetimedb/ \
--out-dir backend/spacetimedb/module_bindings/Start your Next.js app:
bun devEnvironment variables (local)
NEXT_PUBLIC_SPACETIMEDB_URI=ws://localhost:4200
SPACETIMEDB_MODULE_NAME=my-appMaincloud
SpacetimeDB Maincloud is the managed cloud offering. It handles hosting, scaling, and backups.
Publish to Maincloud
spacetime login
spacetime publish my-app --server maincloud --module-path backend/spacetimedb/The module is now available at wss://maincloud.spacetimedb.com/my-app.
Environment variables (Maincloud)
NEXT_PUBLIC_SPACETIMEDB_URI=wss://maincloud.spacetimedb.com
NEXT_PUBLIC_MODULE_NAME=my-appRepublishing
spacetime publish my-app --server maincloud --module-path backend/spacetimedb/Republishing applies schema changes and updates reducer logic. Existing data is preserved (see schema evolution).
Maincloud limitations
ctx.http.fetch()may work on Maincloud (it panics in local Docker due to networking). Test before relying on it.- Latency will be higher than local Docker. Measure before deciding whether to add optimistic updates.
- Auth: Maincloud supports OIDC providers (Google, GitHub). Configure via the Maincloud dashboard.
Self-hosted with Docker
Run SpacetimeDB on your own server.
Docker Compose (production)
services:
spacetimedb:
image: clockworklabs/spacetime:latest
command: start --listen-addr 0.0.0.0:3000
ports:
- '3000:3000'
volumes:
- spacetimedb_data:/stdb
restart: always
environment:
- SPACETIMEDB_LOG_LEVEL=info
nginx:
image: nginx:alpine
ports:
- '80:80'
- '443:443'
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- /etc/letsencrypt:/etc/letsencrypt:ro
depends_on:
- spacetimedb
restart: always
volumes:
spacetimedb_data:Nginx configuration
Replace stdb.yourdomain.com with your actual domain throughout this configuration.
events {}
http {
upstream spacetimedb {
server spacetimedb:3000;
}
server {
listen 80;
server_name stdb.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name stdb.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/stdb.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/stdb.yourdomain.com/privkey.pem;
location / {
proxy_pass http://spacetimedb;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
}TLS with Let's Encrypt
apt install certbot python3-certbot-nginx
certbot certonly --standalone -d stdb.yourdomain.com
certbot renew --dry-runPublish to self-hosted
spacetime server add https://stdb.yourdomain.com --name myserver
spacetime publish my-app --server myserver --module-path backend/spacetimedb/Environment variables (self-hosted)
NEXT_PUBLIC_SPACETIMEDB_URI=wss://stdb.yourdomain.com
NEXT_PUBLIC_MODULE_NAME=my-appSelf-hosted manual install
For bare-metal or custom setups, see the official SpacetimeDB installation docs.
The SpacetimeDB binary can run without Docker. Review the script at the URL before executing. See https://spacetimedb.com/install for alternative installation methods.
curl -sSf https://install.spacetimedb.com | sh
spacetimedb start --listen-addr 0.0.0.0:3000 --data-dir /var/lib/spacetimedbDeploying the Next.js app
The Next.js frontend deploys independently from SpacetimeDB. Any Node.js hosting works.
Vercel
bun add -g vercel
vercel deploySet environment variables in the Vercel dashboard.
Docker
FROM oven/bun:1 AS builder
WORKDIR /app
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile
COPY . .
RUN bun run build
FROM oven/bun:1-slim
WORKDIR /app
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
EXPOSE 3001
CMD ["bun", "start"]Environment variables for production
NEXT_PUBLIC_SPACETIMEDB_URI=wss://stdb.yourdomain.com
SPACETIMEDB_MODULE_NAME=my-appCI/CD
Example GitHub Actions workflow:
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v1
- name: Install dependencies
run: bun install
- name: Install SpacetimeDB CLI
run: curl -sSf https://install.spacetimedb.com | sh
- name: Publish SpacetimeDB module
run: spacetime publish my-app --server maincloud --module-path backend/spacetimedb/
env:
SPACETIMEDB_TOKEN: ${{ secrets.SPACETIMEDB_TOKEN }}
- name: Regenerate bindings
run: |
spacetime generate \
--lang typescript \
--module-path backend/spacetimedb/ \
--out-dir backend/spacetimedb/module_bindings/
- name: Build Next.js
run: bun run build
env:
NEXT_PUBLIC_SPACETIMEDB_URI: wss://maincloud.spacetimedb.com
NEXT_PUBLIC_MODULE_NAME: my-app
- name: Deploy to Vercel
run: vercel deploy --prod
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}Health checks
SpacetimeDB exposes ping endpoints for health checks:
curl http://localhost:4200/v1/ping
curl http://localhost:4200/database/pingBoth endpoints are valid; use either in Docker health checks and load balancer probes.
Monitoring
SpacetimeDB logs to stdout. Collect logs with your preferred log aggregator (Datadog, Loki, CloudWatch, etc.).
Key metrics to watch:
- WebSocket connection count
- Reducer call latency
- Subscription count per connection
- Memory usage (SpacetimeDB keeps all subscribed data in memory)
Environment variables
Auto-generated from every process.env.X reference in lib/noboil/src/. Set these in your project's .env / runtime config.
10 environment variables read by lib/noboil/src/ (excluding tests). Set these in your project's .env / runtime config.
| Var | Files | Where |
|---|---|---|
CONVEX_URL | 1 | lib/noboil/src/convex/next/active-org.ts |
NEXT_PUBLIC_CONVEX_URL | 2 | lib/noboil/src/convex/create.ts, lib/noboil/src/convex/next/active-org.ts |
NEXT_PUBLIC_SPACETIMEDB_MODULE_NAME | 1 | lib/noboil/src/spacetimedb/server/test.ts |
NEXT_PUBLIC_SPACETIMEDB_URI | 1 | lib/noboil/src/spacetimedb/next/active-org.ts |
NOBOIL_TEST_TOKEN | 1 | lib/noboil/src/spacetimedb/next/active-org.ts |
NODE_ENV | 8 | lib/noboil/src/convex/react/devtools-panel.tsx, lib/noboil/src/convex/react/use-cache.ts, lib/noboil/src/convex/react/use-list.ts, lib/noboil/src/convex/react/use-mutate.ts, lib/noboil/src/shared/guard.ts, lib/noboil/src/spacetimedb/react/devtools-panel.tsx, lib/noboil/src/spacetimedb/react/use-cache.ts, lib/noboil/src/spacetimedb/react/use-mutate.ts |
SPACETIMEDB_MODULE_NAME | 2 | lib/noboil/src/spacetimedb/next/active-org.ts, lib/noboil/src/spacetimedb/server/test.ts |
SPACETIMEDB_TEST_TOKEN | 1 | lib/noboil/src/spacetimedb/next/active-org.ts |
SPACETIMEDB_URI | 2 | lib/noboil/src/spacetimedb/dev.ts, lib/noboil/src/spacetimedb/next/active-org.ts |
TEST_MODE | 2 | lib/noboil/src/convex/next/active-org.ts, lib/noboil/src/spacetimedb/next/active-org.ts |