Getting started
Deploy to Cloudflare
One click provisions the Worker, database, storage, queues and AI bindings on your account.
The Deploy button
Clicking it will:
- Fork the repository into your GitHub or GitLab account.
- Create every resource declared in
wrangler.jsoncon your Cloudflare account:
| Binding | Resource | Purpose |
|---|---|---|
DB | D1 database | Users, inboxes, emails, labels, webhooks |
BUCKET | R2 bucket | Raw MIME, large bodies, attachments |
OAUTH_KV | KV namespace | OAuth grants and tokens for MCP clients |
JOBS | Queue (+ DLQ) | Labeling and webhook delivery |
INBOX_HUB | Durable Object | Realtime fan-out, wait long-polls |
COUNTERS | Durable Object | Rate limits, flood protection, budgets |
AI | Workers AI | Smart labels with Clef |
- Ask for the secrets from
.dev.vars.example:BETTER_AUTH_SECRET(generate one withopenssl rand -base64 32) and the AWS keys for Amazon SES (see below). - Build the app, apply D1 migrations and deploy. Workers Builds keeps redeploying on every push to your fork.
Amazon SES
All mail is received and sent through Amazon SES in your own AWS account — reliable deliverability, any DNS provider, and about $0.10 per 1,000 emails.
- Pick a region that supports SES receiving (e.g.
eu-west-1,us-east-1,us-west-2) and set it asAWS_REGION. - Create an IAM user with this policy and put its access key into
AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ses:*",
"sns:*",
"s3:CreateBucket",
"s3:PutBucketPolicy",
"s3:GetObject",
"s3:DeleteObject",
"sts:GetCallerIdentity"
],
"Resource": "*"
}
]
} - New SES accounts start in the sandbox (sending only to verified addresses). Request production access before sending to real recipients — receiving works right away.
After the deploy
- Open the Worker URL and attach a custom domain such as
mail.example.com— Amazon SNS only delivers to HTTPS URLs. SetAPP_URLto it. - Create the first account — it owns the instance. Everyone with the owner or admin role can change instance settings; a self-hosted instance belongs to one team.
- The setup wizard checks bindings, sets up SES receiving with one click (S3 bucket, SNS topic, receipt rule), adds your domain with its DNS records and waits for a test mail.
Set
APP_URLto your public URL once you attach a custom domain. It is used for OAuth metadata, links in emails and attachment URLs.
Recommended variables
| Variable | Example | Why |
|---|---|---|
APP_URL | https://mail.example.com | Stable public URL |
MAIL_FROM | Squadmail <noreply@example.com> | Sender for invites and resets |
AWS_REGION | eu-west-1 | Amazon SES region |
SIGNUP_MODE | invite | open, invite or closed |
See the full configuration reference.
Updating
Pull upstream changes into your fork. Workers Builds rebuilds, applies new migrations (wrangler d1 migrations apply DB --remote is part of the deploy script) and deploys.