Installation
How to run Orbit locally for development, with Docker Compose, and on Dokploy.
Components
| Service | Tech | Default port | Role |
|---|---|---|---|
api |
Hono (Node 22) | 8000 | REST API /v1; runs migrations at start-up; bootstraps the first superadmin |
worker |
Node 22 | – | Background jobs: imports, reminders, report schedules, cleanup |
web |
Next.js | 3100 (3000 in container) | Tenant dashboard and public portal; proxies /v1 to the API |
overseer |
Next.js | 3101 (3000 in container) | Superadmin console |
docs |
Node 22 | 3102 (3000 in container) | This documentation as a website |
postgres |
PostgreSQL 16 | 5462 → 5432 | Data. Schema-per-tenant |
seaweedfs |
SeaweedFS S3 | 8334 → 8333 | File storage (any S3-compatible store works) |
createbucket |
aws-cli | – | One-off: creates the bucket |
Local development
Requirements: Node 22, pnpm 11, Docker.
cp .env.example .env
pnpm install
pnpm infra:up # postgres (:5462) + SeaweedFS S3 (:8334) + bucket
pnpm migrate # public + all tenant schemas
pnpm --filter @orbit/api dev:setup acme medium # tenant "acme" with demo data and admin@acme.test
pnpm dev # api :8000, worker, web :3100, overseer :3101
- Dashboard: http://localhost:3100, sign in as
admin@acme.test/Password123!, tenantacme. - Public portal: http://localhost:3100/jobs/acme, http://localhost:3100/events/acme.
- Overseer: http://localhost:3101, using
SUPERADMIN_EMAIL/SUPERADMIN_PASSWORDfrom.env. - API docs: http://localhost:8000/v1/docs.
With SMTP_HOST empty, emails (sign-in codes, confirmation links, password resets) are written to the API log instead of being sent:
[mail:disabled] to=someone@example.org subject="Orbit: confirm your application"
Please confirm your application within 72 hours:
http://localhost:3100/confirm/acme/…
Full stack in Docker
cp .env.example .env # edit secrets first
docker compose up -d --build # postgres, seaweedfs, api, worker, web, overseer, docs
docker compose run --rm setup acme medium # optional demo tenant
- Every app container reads
.env. Compose overrides only what differs inside its network:DATABASE_URL,S3_ENDPOINT_URL, the API URL that web and overseer use on the server side, andPORT. NEXT_PUBLIC_*values are baked into the web and overseer bundles at build time. Rebuild (--build) after changing them.- Host ports are defined only in
docker-compose.override.yml, whichdocker composeloads automatically locally. - Data lives in the
pgdataands3datavolumes.
Dokploy (hosted / QA)
- Create a Compose service (type Docker Compose, not Stack) pointing at the repository and
docker-compose.yml. - Paste a customised
.env.exampleinto the Environment tab; Dokploy writes it to.env. - Add domains for
web(port 3000) andoverseer(port 3000). The API doesn't need a public domain: browsers reach it through web's/v1proxy. - Dokploy doesn't load
docker-compose.override.yml, so no host ports are published.
Production checklist
- [ ] Strong
JWT_SIGNING_KEY(long random string), unique per environment. - [ ] Strong
POSTGRES_PASSWORDand S3 keys. - [ ]
SUPERADMIN_PASSWORDchanged after first sign-in;REQUIRE_SUPERADMIN_MFA=true. - [ ]
APP_BASE_URLandPUBLIC_PORTAL_BASE_URLset to the public HTTPS address (they're used in email links). - [ ] SMTP configured, then a test password reset sent.
- [ ]
cors_originrestricted to your domains;debug_mode=false. - [ ] HTTPS terminated at the proxy.
- [ ] Backups of Postgres and the S3 bucket.
- [ ] The worker container is running (imports, reminders, schedules depend on it).
Documentation website
This documentation can be served as a searchable website with navigation and dark mode. It runs as the docs service in Compose: docker compose up -d --build docs, then open http://localhost:3102. To run the image on its own:
docker build -f infra/Dockerfile.docs -t orbit-docs .
docker run --rm -p 3000:3000 orbit-docs
Open http://localhost:3000. To preview Markdown edits without rebuilding, mount the folder: add -v "$PWD/documentation:/docs:ro" to docker run. Without Docker, run npm install && npm start in infra/docs-site/. With the site running, npm run check reports broken links and anchors.