Set up the Cloudflare Email gateway
Deploy a Cloudflare Worker that receives, stores and sends mail for one of your domains.
The Cloudflare Email gateway is a Cloudflare Worker. It receives mail through Email Routing, stores messages in D1 with raw mail and attachments in R2, and sends through Cloudflare Email Sending. You deploy one Worker per domain.
Before you start
- The domain is a zone on your Cloudflare account. Email Routing needs Cloudflare DNS.
- Your Cloudflare account is on the Workers Paid plan, which Email Sending needs to send to any recipient.
- You have a Cloudflare API token with Zone, Email Routing: Edit and Zone, DNS: Edit, and you can deploy Workers with wrangler.
- You have Bun and a copy of the Metis Suite source code:
git clone https://github.com/trymetis/metis.git
cd metis
bun install
cd apps/gateway-cloudflare
Deploy the Worker
Create the database
bun run db:createIt prints a D1 database id. Paste it into wrangler.jsonc as
database_id, and set MAIL_DOMAIN there to your domain.
Create the storage bucket
bun run r2:createCreate the tables
bun run db:applySet the admin token
Generate a long random value, for example with openssl rand -hex 32,
then store it as the Worker’s admin token:
bun run secretKeep this value: you need it to create mailbox tokens.
Deploy
bun run deployIt prints the Worker’s workers.dev address. You need it below.
Connect your domain
Run the setup with your API token, your zone id and the addresses you want to receive mail for:
CLOUDFLARE_API_TOKEN=... CLOUDFLARE_ZONE_ID=... \
MAIL_ADDRESSES=alice@example.com,bob@example.com \
bun run setupThe setup turns on Email Routing for the zone, creates a routing rule for
each address, sets the domain up for Email Sending, and adds the DNS
records sending needs (SPF, DKIM, DMARC and a bounce record). It is safe
to run again: run it with more addresses whenever you add one. Set
WORKER_NAME if you named the Worker differently.
Without MAIL_ADDRESSES, the setup sends every address on the domain to
the Worker instead (a catch-all). Aliases then work with no setup, but
the domain accepts more spam. Mail for an address with no token is kept,
and it appears once you create a token for that address.
Register it in Metis Suite
Open Dashboard, System, Cloudflare Email under Providers. Click Add server and fill in:
- Name: what users see in the connect dialog.
- Domain: your domain, such as
example.com, withouthttps://. - Worker endpoint: the Worker’s
https://address.
Click Save changes and enter your authenticator code.
You can also set the starting list before the first start:
METIS_CLOUDFLARE_SERVERS=[{"name":"Example Mail","domain":"example.com","endpoint":"https://metis-cf-mail.you.workers.dev"}]Create mailbox tokens
Create a token for each address and give it to its owner. See Mailbox tokens.
Cloudflare limits
- A D1 row holds at most 2 MB, so message bodies are cut at 1 MB. Raw mail and attachments are kept in R2 in full.
- Email Sending includes 3,000 emails a month on Workers Paid, then is billed per 1,000. A message can have at most 50 recipients. Email Sending is in beta.
- Email Routing allows at most 200 routing rules per zone. Beyond that, use catch-all mode.