noboil

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 -d

This 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 dev

Environment variables (local)

NEXT_PUBLIC_SPACETIMEDB_URI=ws://localhost:4200
SPACETIMEDB_MODULE_NAME=my-app

Maincloud

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-app

Republishing

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-run

Publish 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-app

Self-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/spacetimedb

Deploying the Next.js app

The Next.js frontend deploys independently from SpacetimeDB. Any Node.js hosting works.

Vercel

bun add -g vercel
vercel deploy

Set 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-app

CI/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/ping

Both 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.

VarFilesWhere
CONVEX_URL1lib/noboil/src/convex/next/active-org.ts
NEXT_PUBLIC_CONVEX_URL2lib/noboil/src/convex/create.ts, lib/noboil/src/convex/next/active-org.ts
NEXT_PUBLIC_SPACETIMEDB_MODULE_NAME1lib/noboil/src/spacetimedb/server/test.ts
NEXT_PUBLIC_SPACETIMEDB_URI1lib/noboil/src/spacetimedb/next/active-org.ts
NOBOIL_TEST_TOKEN1lib/noboil/src/spacetimedb/next/active-org.ts
NODE_ENV8lib/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_NAME2lib/noboil/src/spacetimedb/next/active-org.ts, lib/noboil/src/spacetimedb/server/test.ts
SPACETIMEDB_TEST_TOKEN1lib/noboil/src/spacetimedb/next/active-org.ts
SPACETIMEDB_URI2lib/noboil/src/spacetimedb/dev.ts, lib/noboil/src/spacetimedb/next/active-org.ts
TEST_MODE2lib/noboil/src/convex/next/active-org.ts, lib/noboil/src/spacetimedb/next/active-org.ts

On this page