Architecture

How MailCue runs as a single Docker container, plus the libraries and services it is built from.

Architecture

graph TB
    subgraph external["External Clients"]
        browser["Browser / HTTP Client"]
        smtp_client["SMTP Client / MTA"]
        imap_client["IMAP / POP3 Client"]
    end

    subgraph container["Single Docker Container - managed by s6-overlay"]
        direction TB

        subgraph web["Web Layer"]
            nginx["Nginx
:80 - Reverse Proxy"] spa["React SPA
/var/www/mailcue"] uvicorn["Uvicorn + FastAPI
:8000 - REST API + SSE"] end subgraph mail["Mail Stack"] postfix["Postfix
:25 SMTP · :587 Submission"] dovecot["Dovecot
:143/:993 IMAP · :110/:995 POP3 · LMTP"] opendkim["OpenDKIM
milter - DKIM sign/verify"] opendmarc["OpenDMARC
milter - DMARC verify"] spamassassin["SpamAssassin
spamd - spam scoring"] spf["policyd-spf
SPF checking"] end subgraph storage["Persistent Storage"] sqlite[("SQLite / SQLCipher
/var/lib/mailcue/mailcue.db")] maildir[("Maildir
/var/mail/vhosts/")] gpg[("GPG Keyring
/var/lib/mailcue/gpg/")] end end browser -- ":80 /*" --> nginx smtp_client -- ":25 / :587" --> postfix imap_client -- ":143/:993 / :110/:995" --> dovecot nginx -- "static files" --> spa nginx -- "/api/*" --> uvicorn uvicorn -- "IMAP
master-user" --> dovecot uvicorn -- "local SMTP" --> postfix uvicorn --> sqlite uvicorn --> gpg postfix -- "LMTP" --> dovecot postfix -- "milter" --> opendkim postfix -- "milter" --> opendmarc postfix -- "policy" --> spf postfix -- "spamc" --> spamassassin dovecot --> maildir style container fill:none,stroke:#6c47ff,stroke-width:2px,color:#6c47ff style web fill:none,stroke:#3b82f6,stroke-width:1px style mail fill:none,stroke:#f59e0b,stroke-width:1px style storage fill:none,stroke:#10b981,stroke-width:1px style external fill:none,stroke:#94a3b8,stroke-width:1px,stroke-dasharray:5 5

Request flow: Nginx serves the React SPA for all non-API routes and proxies /api/* to Uvicorn. The FastAPI backend talks to Dovecot via IMAP (using a master-user credential for mailbox impersonation) and to Postfix via local SMTP. All services are supervised by s6-overlay, which handles startup ordering and automatic restarts.

Tech Stack

Backend

  • Python 3.12 with FastAPI and Uvicorn (async)
  • SQLAlchemy 2 (async) + aiosqlite (SQLite by default, swappable to PostgreSQL)
  • Alembic for database migrations
  • Argon2id password hashing, JWT (HS256) authentication
  • aioimaplib and aiosmtplib for async IMAP/SMTP operations
  • python-gnupg for GPG key management and PGP/MIME operations
  • sse-starlette for Server-Sent Events

Frontend

  • React 19 with TypeScript
  • Vite 8 build tool with SWC
  • Tailwind CSS 4 for styling
  • TanStack React Query for server-state management
  • React Router 7 for client-side routing
  • Tiptap rich text editor for composing HTML emails
  • Zustand for UI state
  • Zod + React Hook Form for validation

Infrastructure

  • Postfix: SMTP server (ports 25 and 587)
  • Dovecot: IMAP/POP3/LMTP server (ports 143, 993, 110, 995)
  • OpenDKIM: DKIM signing and verification
  • OpenDMARC: DMARC policy verification (milter)
  • SpamAssassin: Spam scoring and filtering
  • postfix-policyd-spf-python: SPF record verification
  • Nginx: Reverse proxy and static file server
  • s6-overlay v3: Process supervisor (PID 1)
  • SQLCipher: Optional AES-256 database encryption (drop-in SQLite replacement)
  • Debian Bookworm slim base image