Skip to content

Operations ​

This section is for the person who runs a Mankomail 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.

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.

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.