Run your server

Self-hosting

How a server set up with the script is laid out, and how to look after it day to day.

imbox docs

This page is for the person who runs the server. It assumes imbox is already installed. If it is not, start with Install.

imbox is built for one owner on one small machine. Everything it knows about your mail lives in one PostgreSQL database, so looking after it comes down to four things: keep it running, keep it updated, keep a backup, and keep the secret.

Loading diagram...

What you need

MinimumComfortable
CPU and memory1 CPU, 2 GB2 CPUs, 4 GB
Disk20 GB40 GB
SystemDebian 12 or 13, Ubuntu 22.04 or 24.04Ubuntu 24.04
NetworkA public address and a domain, ports 80 and 443 openThe same

imbox keeps message text in the database and fetches attachments from your mail provider when you open them, so the disk stays small even after years of mail.

Where things live

On a server set up with the script:

WhatWhere
Settings/etc/imbox/imbox.env
The running release/opt/imbox/current, a link to a folder in /opt/imbox/releases
Older releases/opt/imbox/releases, the five newest
Nightly backups/var/backups/imbox
Servicesinbox (the app), imbox-docs (this documentation, when the release carries it), caddy and postgresql

Day to day

sudo systemctl status imbox            # running, or why it stopped
sudo journalctl -u imbox -f            # the log, live
curl -s http://127.0.0.1:8787/healthz  # {"ok":true} when the app is up

A background job that fails logs a line with job in it, such as job mail-sync error. The sync history of each mailbox is also in Settings → Accounts.

If something is wrong, go to Troubleshooting.

Keep the secret

Copy SESSION_SECRET now

SESSION_SECRET in /etc/imbox/imbox.env encrypts your saved mailbox passwords, AI keys, app secrets and two-factor secrets. Keep a copy in a password manager. If it is lost, those can't be read again and you have to enter them again. See Security.

Harden the server

Run these once after the install. Keep your current SSH session open and test a second login before you close it.

sudo bash imbox/deploy/harden.sh         # key-only SSH, fail2ban, automatic security updates, swap
sudo bash imbox/deploy/tune-postgres.sh  # database memory settings and the search indexes

tune-postgres.sh assumes about 4 GB of memory. For a different size, set RAM_MB, for example sudo RAM_MB=8192 bash imbox/deploy/tune-postgres.sh.

Deploy from GitHub

The repository includes a workflow, .github/workflows/deploy-selfhost.yml, that tests, builds and deploys on every push to main. It is off until you set it up.

  1. In GitHub, create an environment named production.
  2. Add these secrets:
    • DEPLOY_HOST: your server address.
    • DEPLOY_USER: the SSH user.
    • DEPLOY_SSH_KEY: a private key the server accepts.
    • DEPLOY_KNOWN_HOSTS: the output of ssh-keyscan -H imbox.example.com.
  3. Add these variables:
    • DEPLOY_URL: your address, https://imbox.example.com.
    • SELFHOST_DEPLOY: true.

The deploy user needs the password-free permission from Install.

Live updates

The app pushes new mail and sync status to open tabs over a long-lived connection at /api/events. Your proxy must not hold that response back. The Caddyfile the script writes already handles it with flush_interval -1. For nginx, add:

location /api/events {
    proxy_pass http://127.0.0.1:8787;
    proxy_buffering off;
    proxy_read_timeout 1h;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    gzip off;
}

Using a connection pooler

If DATABASE_URL goes through a pooler in transaction mode, such as PgBouncer, set LISTEN_DATABASE_URL to a direct connection to PostgreSQL. Live events need it.

A busier server

One process is enough for one person. If you have several cores and a lot of mailboxes, add this to /etc/imbox/imbox.env:

WEB_CONCURRENCY=4   # web processes; leave a core for PostgreSQL
PG_POOL_MAX=10      # database connections per process

With more than one process, a coordinator applies migrations and runs the once-a-minute sync, and the others share the web traffic on port 8787. Restart with sudo systemctl restart imbox.

Next