Deployment
Coolify builds the repository's Dockerfile from main and runs one container with the API, the worker and the web app; the environment it needs, what must be registered at SSO first, and the production addresses.
EvalBook deploys the way its sibling products do: Coolify watches the repository's main branch and auto-deploys every push, building the repository's own Dockerfile. Nixpacks is not used. The result is one container running three processes, backed by one PostgreSQL database. There are no GitHub Actions.
The production origin was decided on 25 October 2026: the application is https://app.nurobook.com (www.app.nurobook.com also points there) and this site is https://nurobook.com. Nothing in the application hard-codes a domain: SSO's seed registers EvalBook only when EVALBOOK_APP_ORIGIN is set in SSO's environment, and EvalBook learns its own addresses from EVALBOOK_APP_URL and from SSO. The product keeps its name, EvalBook.
What the container runs
The image is node:24-bookworm-slim with the web app built in at image build time, so a restart never waits on a build. scripts/coolify-start.sh is the entrypoint:
- Builds the database connection from
EVALBOOK_DB_*and exports it; no file with a password is written. A missing variable stops the start, naming it. - Creates any missing tables (
scripts/bootstrap.mjs coolify), then applies pending migrations (scripts/migrate-all.sh coolify). - Starts the API on
127.0.0.1:8080(internal;EVALBOOK_API_PORToverrides) and waits up to 60 seconds for/health. - Starts the worker. The API runs no jobs in the container.
- Starts the web app with
next starton$PORT(3000) on all interfaces. Next rewrites/api/*to the API on localhost, so the session cookie is first-party and nothing outside the container needs to know the API is a separate process.
If any of the three processes exits, the container exits and Coolify restarts it: a dead worker behind a live /health would otherwise hide. The image's health check probes the web port every 30 seconds after a 90-second start period. What /health and /ready answer is on Readiness and operations.
Environment variables in production
Set these in Coolify. Never print or commit a value.
| Variable | Purpose |
|---|---|
SSO_ORIGIN |
the Bookbag SSO API origin |
SSO_APP_TOKEN |
EvalBook's app token from SSO's app registry |
SSO_UI_ORIGIN |
only if the SSO UI is on a different origin from its API |
EVALBOOK_ENCRYPTION_KEY |
32 bytes as 64 hex characters or base64; readiness fails without it |
EVALBOOK_APP_URL |
the web origin, used in links EvalBook writes |
EVALBOOK_ALLOWED_ORIGINS |
CORS origins beyond the app's own, comma-separated, if any |
EVALBOOK_DB_HOST, EVALBOOK_DB_PORT, EVALBOOK_DB_NAME, EVALBOOK_DB_USER, EVALBOOK_DB_PASSWORD |
the PostgreSQL database; every context shares it |
EVALBOOK_DB_SSL=1 (and EVALBOOK_DB_SSL_INSECURE=1 only for a self-signed certificate) |
TLS to the database |
EVALBOOK_DIAGNOSTICS_TOKEN |
optional; lets a monitor read the /ready detail with a Bearer header; at least 32 characters |
NEXT_PUBLIC_SSO_ORIGIN |
the SSO UI origin the web app sends people to for sign-in, sign-out and account links |
master=coolify, NODE_ENV=production and PORT=3000 are set in the image. PEER_SECRET and the PEER_*_URL overrides are for local work only; production sets none and reads the peer directory from SSO.
Register EvalBook at SSO first
The container cannot serve a sign-in until SSO knows it. At SSO:
- Set
EVALBOOK_APP_ORIGINin SSO's environment to the web origin. SSO's seed then registers EvalBook (bookbag-evalbook) with the peer prefix/project/api/peer; the redirect URI is<web origin>/api/auth/sso/callback. - Add the same origin to
SSO_ALLOWED_ORIGINSand toSSO_CHAT_ORIGINS. - Issue the app token from SSO's app registry and set it as
SSO_APP_TOKENhere. It is shown once. - Give the people who will run EvalBook the per-product
adminrole for EvalBook at SSO; that is what makes them platform admins here. See Platform admin.
CodeBook, MadeBook and EvalBook find each other through SSO's peer directory; nothing about peers is configured in Coolify. See Peer links.
The runner is not in the container
Executable scorers never run in this container. The API and worker execute no customer code; the runner is a single file installed separately on the customer's machine, dials out to EvalBook with a runner token (evr_…) and opens no port. Deploying EvalBook deploys no runner. See Executable verification.
Verifying a deployment
After Coolify reports the container healthy:
GET /healthanswers200withstatus: "ok".GET /readyanswers200; with the diagnostics token, every check ispass.- Sign in through SSO and open Admin → Readiness as a platform admin; the same checks appear with their detail.
- Open an organization and create a project; the free plan allows 3 active projects per organization, and EvalBook is not yet billable at SSO, so every organization is on the free plan.
The topology decision calls for daily database backups, as the siblings have; backup and restore rehearsal is not yet recorded in the requirements ledger. Service-level targets are proposals until load tests run on this topology and are not advertised.