TotalBase
Operations

Deployment

Running TotalBase in production: one process, one port.

TotalBase is one server process on one port, connected to one PostgreSQL database. That process serves the Data API, the Admin API, the admin and the App, and the MCP server, and runs the background work: workflow runs, data events, async executions, maintenance. Queues live in PostgreSQL: there's no Redis, message broker or Kubernetes to run.

Installation gets an instance running with Docker Compose. This page covers what changes in production.

The container

The image, totalbase/totalbase on Docker Hub (amd64 and arm64), runs the server as a non-root user on TOTALBASE_PORT (3050 by default), with a health check on /health/ready. Pin a version in production (totalbase/totalbase:0.1.0-beta.1) rather than :beta, so an upgrade is a change you make. Its data directory, /var/lib/totalbase, holds the uploaded files (Settings › Features › Files) and a generated master key: mount it on persistent storage and back it up.

services:
  totalbase:
    image: totalbase/totalbase:0.1.0-beta.1
    env_file: .env
    ports: ["127.0.0.1:3050:3050"]
    volumes: ["totalbase-data:/var/lib/totalbase"]
    restart: unless-stopped
volumes:
  totalbase-data:

Publish the port only to the reverse proxy, as above, not to the internet.

In front of it: a reverse proxy

Put TotalBase behind a reverse proxy (Caddy, nginx, a cloud load balancer) that terminates TLS. Then:

  1. Set the Public URL to the address people use, https://ops.acme-field.example.
  2. Turn on Trust reverse proxy headers, so the audit log and the rate limit see the real client IP.
  3. List the sites allowed to call the API from a browser in Allowed origins, if any.

See Public URL, Proxy and CORS.

Health

RouteAnswers
GET /health/live200 as soon as the process responds
GET /health/ready200 once PostgreSQL is reachable, migrations are current, the master key matches and the catalog is read; 503 with a reason otherwise

Use /health/ready for the load balancer and the orchestrator. The server only starts listening after its startup checks pass, so a failed start never takes traffic. See What happens on startup.

One instance

An instance is one process. To restart it, the usual container restart is enough: in-flight runs are recovered on the next start (a run that was running is marked interrupted), and queued work waits in PostgreSQL.

Logs

The server writes structured JSON logs to standard output, at LOG_LEVEL (info by default). Collect them with your platform's log driver. They never contain secrets.

Checklist

  • PostgreSQL 15-18, with a role that isn't a superuser: PostgreSQL.
  • The master key - TOTALBASE_MASTER_KEY, or the generated /var/lib/totalbase/master.key - copied outside the server, in your secrets manager.
  • TLS at the proxy, Public URL set, Trust reverse proxy headers on.
  • SMTP configured, so invitations and resets reach people.
  • Database and files volume backed up, and a restore tried: Backup and restore.
  • /health/ready wired to your monitoring.

Next steps