How atsh-here/genmail-vm works
genmail is a self-hosted transactional mail forwarder: SMTP mail is filtered on the VM, routed through a Cloudflare Worker, and delivered to a verified destination. Its main workflow separates SMTP ingress, recipient filtering, route resolution, MIME delivery, and logging. The repository also supports Git-driven filter and routing-data updates. The Worker and milter excerpts are partial; documented capabilities are included, while uncertain internal wiring is omitted.
Main entry points: index.js Worker API · genmail_milter.py Milter · app.py Config webhook · db-sync.py DB sync script
Components 20
SMTP ingress
- Postfix SMTP
postfix/main.cf
Filtering and config
- Milter
milter/genmail_milter.py - OLD allowlist
config/OLD.yaml - MAR rules
config/MAR.yaml
Routing and data
- Worker API
worker/src/index.js - Route resolution
worker/src/index.js - Route tables
DB/datafiles - D1 database
Delivery and logging
- MIME parsing and rewrite
worker/src/index.js - Cloudflare Email Sending
- Mail log
DB/schemas/mail_log.sql
Git-based updates
- Config webhook
webhook/app.py - Config sync workflow
.github/workflows/genmail-config.yml - Config push script
.github/scripts/push-all-configs.py - DB sync workflow
.github/workflows/db-sync.yml - DB sync script
.github/scripts/db-sync.py - Routing CSVs
DB/datafiles
Other components
- Internet mail
- Git repository
- Cloudflare Tunnel
Connections 25
- Internet mail → Postfix SMTP: SMTP sends
- Postfix SMTP → Milter: dispatches mail
- Milter → OLD allowlist: reads
- Milter → MAR rules: reads
- Milter → Worker API: requests /route
- Worker API → Route resolution: dispatches
- Route resolution → D1 database: queries routes
- D1 database → Route resolution: returns matches
- Worker API → Mail log: writes decisions
- Milter → Worker API: sends MIME to /deliver
- Worker API → MIME parsing and rewrite: parses and rewrites
- MIME parsing and rewrite → Cloudflare Email Sending: sends message
- Worker API → Mail log: updates delivery status
- Git repository → Config sync workflow: triggers on commit
- Config sync workflow → Config push script: runs
- Config push script → Cloudflare Tunnel: posts signed config
- Cloudflare Tunnel → Config webhook: forwards request
- Config webhook → OLD allowlist: writes config
- Config webhook → MAR rules: writes config
- Git repository → DB sync workflow: triggers on commit
- DB sync workflow → DB sync script: runs
- DB sync script → Routing CSVs: reads and posts
- DB sync script → Worker API: requests /db/sync
- Worker API → D1 database: applies table state
- Worker API → Routing CSVs: returns post-apply state