Skip to content

Operations ​

This section is for the person who runs a Loop & Roll instance: you installed it with Self-hosting, and now you need to configure it, back it up, upgrade it and keep an eye on it.

PageWhat it covers
ConfigurationHow an instance is configured, secrets in files, the public address and HTTPS, the encryption key, sending, AI models, splitting API and workers.
BackupsBack up and restore step by step with the scripts shipped with the source code, and test a restore without touching production.
UpgradesMove to a new version, how database migrations run, the order of processes, and how to roll back.
MonitoringHealth endpoints, logs, what to watch, sizing, and what the instance does after a restart or a database outage.
White labelYour name, logos, colors and sign-in page, by environment variables or from a control plane; what the link to a control plane sends and receives, and suspension.

Every environment variable, with its default and accepted values, is listed in Environment variables.

The components of an instance ​

A self-hosted instance is made of a small number of parts. There is no Redis, no message broker and no separate scheduler.

A self-hosted instance: one application container, PostgreSQL, object storage, and your reverse proxyBrowsers, MCP and API clients, and webhook senders reach your reverse proxy over HTTPS (Caddy, nginx, Traefik…), which forwards to the application on 127.0.0.1:3000. The application container serves the API, the web interface and the real-time channel, and runs the background work: synchronisation, runs, sending, schedules. It keeps all its state, including the job queue, in PostgreSQL, and email bodies and attachments in an S3-compatible object storage (MinIO in the reference Compose file). Neither PostgreSQL nor MinIO is published outside the Compose network. The application calls the mail providers, the AI providers and the integrations itself. There is no Redis, no broker, no separate scheduler.Docker ComposeBrowsers, API andMCP clients,webhooksReverse proxyTLS · Caddy, nginx,TraefikApplicationAPI, interface, WebSocket + workers · APP_ROLE=all ·127.0.0.1:3000PostgreSQLall state + job queueObject storageMinIO or any S3Mail, AI, integrationsoutgoing callsHTTPSHTTP
A self-hosted instance: one application container, PostgreSQL, object storage, and your reverse proxy
ComponentRoleRequired
ApplicationOne process that serves the HTTP API, the web interface and the real-time channel, and runs the background work: mailbox synchronisation, workflow runs, sending, scheduled tasks, maintenance.Yes
PostgreSQLHolds all the state of the instance, including the job queue.Yes
S3-compatible object storageHolds email bodies, attachments and files added to runs. The reference Docker Compose file runs MinIO; any S3-compatible service works.Yes
Reverse proxyTerminates HTTPS in front of the application, which does not speak TLS itself.Yes, for any instance reached over a network

The application is a single Docker image. The same image runs every role: what a process does is decided by the APP_ROLE variable.

Process roles ​

APP_ROLE decides what one application process runs.

Splitting the API and the workers: every process takes its work from the same queue, with no leaderThe same image runs every role. Processes started with APP_ROLE=api serve HTTP and the interface only; processes with APP_ROLE=worker run the background work; APP_ROLE=all, the default, does both. Every process talks to the same PostgreSQL database, whose job queue hands each job to one worker at a time. Workers can be added side by side without any coordination setting; at least one worker or all process is needed for synchronisation, runs and sending.Reverse proxyAPP_ROLE=apiHTTP, interfaceAPP_ROLE=apiHTTP, interfacePostgreSQLstate + job queueAPP_ROLE=workersync, runs, sendsAPP_ROLE=workersync, runs, sendsclaims jobs
Splitting the API and the workers: every process takes its work from the same queue, with no leader
APP_ROLEHTTP API and web interfaceBackground work
all (default)YesYes
apiYesNo
workerThe process still listens on its HTTP port, which lets a health probe reach itYes
  • all is what the reference Compose file runs: one container does everything. It is the right choice for most instances.
  • api and worker let you scale the two sides separately. A process started with APP_ROLE=api logs a warning at boot (APP_ROLE=api: this process runs no worker), because without at least one worker or all process, nothing synchronises, no workflow runs and nothing is sent.
  • There is no leader. Every background process takes its work from the queue in PostgreSQL, so you can run several of them side by side without any coordination setting.

See Split the API and the workers to set this up.

Where each piece of data lives ​

DataWhere it livesIn the backup made by the scripts
Members, sessions, mailboxes and their synchronisation state, message metadata, workflows and their versions, runs, the job queue, tables, the audit logPostgreSQLYes, as a database dump
Stored credentials: mailbox OAuth tokens, IMAP passwords, AI provider keys, other connections, OAuth application secretsPostgreSQL, encrypted with ENCRYPTION_KEYYes, still encrypted
Email bodies, attachments, files added to runsObject storageYes, as a copy of every object
ENCRYPTION_KEY, database and storage passwords, PUBLIC_BASE_URLYour .env file or your secret storeNo

The mirror keeps a local copy of each connected mailbox: if you lose the whole instance, the emails themselves still exist at the mail provider. What exists only in your instance is everything else: workflows, runs, tables, settings, the audit log.

What you must back up ​

Three things, and the backup scripts only cover the first two:

  1. The PostgreSQL database.
  2. The object storage bucket.
  3. ENCRYPTION_KEY, kept somewhere else than the backups, for example in a password manager. Without the exact same key, a restored instance shows every email, but every stored credential is unreadable and every mailbox has to be reconnected.

Keep a copy of the rest of the .env file too: the database and storage passwords, and the public address. See Backups.

What the instance does on its own ​

Several operations need no action from you:

  • Database migrations run automatically when the application starts, under a PostgreSQL lock, so that several processes can start at the same time. See Upgrades.
  • Waiting for the database. At boot, the application waits up to 60 seconds for PostgreSQL to accept connections, which covers a stack where the application starts first.
  • Maintenance. An hourly maintenance job deletes data older than its retention period (runs, test runs, the audit log, outbound operations, and so on) and removes the objects that deleted data no longer needs. The retention periods are listed in Environment variables.
  • Crash recovery. A background job held by a process that died is handed back to the queue once its lease expires, and picked up by another process. See Monitoring.
  • Database outages. A PostgreSQL restart or outage does not stop the application: requests fail during the outage, and everything resumes when the database comes back, without restarting the application.

Before you put an instance in production ​

  • Set PUBLIC_BASE_URL to the exact HTTPS address of the instance, behind a reverse proxy. See Configuration.
  • Keep a copy of ENCRYPTION_KEY outside the server.
  • Schedule backups, then restore one on a copy to prove it works. See Test a restore without touching production.
  • Point a health probe at /healthz and an external check at /readyz. See Monitoring.
  • Check that the logs do not fill the disk, and that the disk has room for the mailboxes you synchronise.

Loop & Roll — the workflow builder for email.