MailCheap on Unbroker
Newsletters where you pay for the emails you send, not for dormant subscribers
Plan requirements
Template container services, databases and persistent volumes require Pro. Resource usage is billed separately. Review the configuration and pricing before deploying. View pricing
Deployment inputs
ADMIN_EMAILRequired- Your email. You sign in to MailCheap with a code sent here, and it can open /admin.
ALLOWED_EMAILSOptional- Who else can sign in, comma-separated addresses and whole domains, e.g. jane@example.com, @example.org.
EMAIL_FROMRequired- From address of sign-in codes and alerts, e.g. MailCheap <login@mail.example.com>. Its domain must be verified at Resend or Amazon SES.
RESEND_API_KEYOptional- Resend API key for sign-in codes and alerts. Without it, they go through Amazon SES.
SES_REGIONRequired- AWS region of your Amazon SES account.
SES_ACCESS_KEY_IDOptional- Access key of the IAM user MailCheap sends through Amazon SES with.
SES_SECRET_ACCESS_KEYOptional- Secret of that access key.
SES_AWS_ACCOUNT_IDOptional- The 12-digit ID of that AWS account.
SES_SNS_TOPIC_ARNOptional- ARN of the SNS topic that receives bounces, complaints and deliveries, subscribed to https://<your-app>/api/webhooks/ses.
QSTASH_TOKENOptional- Upstash QStash token. QStash runs background sending and scheduling.
QSTASH_CURRENT_SIGNING_KEYOptional- QStash current signing key.
QSTASH_NEXT_SIGNING_KEYOptional- QStash next signing key.
SENDING_ENABLEDRequired- "true" lets emails reach readers. Leave "false" until your domain and email provider are set up.
A newsletter app where you pay your email provider for the emails you send, not a platform for every subscriber on your list. Write an issue, send it to your list and publish it on the web, from the dashboard or from an AI agent through its MCP server and REST API. Imports beehiiv, Substack, Mailchimp, Kit and other CSV exports as they are.
What gets deployed
| Service | Image | Notes |
|---|---|---|
| MailCheap | ghcr.io/unbroker-app/mailcheap-container | Public. The upstream app, built from a pinned commit by mailcheap-container |
| db | MongoDB 7 | Internal. Accounts, contacts, campaigns and stats |
The session secret and the key of the never-email list are generated for you. Don’t change them later: the first signs everyone out and breaks the links in emails already sent, the second empties the list.
Before you deploy
MailCheap signs you in with a code it emails, so it needs a way to send email from the first minute. Pick one:
- Resend (quickest): verify the domain of
EMAIL_FROMat Resend and fill inRESEND_API_KEY. - Amazon SES: fill in the
SES_*fields and verify the domain ofEMAIL_FROMin that AWS account (Identities, Easy DKIM).
Without either, the app runs but nobody can sign in.
After deploy
- Open the app’s URL and sign in with
ADMIN_EMAIL. Only that address and the ones inALLOWED_EMAILScan sign in. - To send to readers, follow upstream’s
self-hosting guide,
steps 4 to 6, with your app’s URL in place of the Vercel one:
- Amazon SES: production access, an SNS topic subscribed to
https://<your-app>/api/webhooks/ses, and an IAM user with the policy the guide lists. Fill in theSES_*variables. - Upstash QStash: fill in
QSTASH_TOKENand the two signing keys. QStash calls your app back over the internet to send each batch. - Add your sending domain under Domains, create a newsletter, then set
SENDING_ENABLEDtotrue.
- Amazon SES: production access, an SNS topic subscribed to
Until SENDING_ENABLED is true, nothing reaches readers. Sign-in codes and
alerts go out either way.
Caveats
- Amazon SES only. The template sets
EMAIL_PROVIDER=ses. For PostShiba (invite only), change it topostshibaand add thePOSTSHIBA_*variables from upstream’s.env.example. - Image uploads are off until you add an S3 bucket behind CloudFront
(
IMAGES_S3_*,IMAGES_CDN_URL) or a Vercel Blob token. Campaigns can still use images hosted anywhere. - Rate limits are per container. Upstash Redis (
UPSTASH_REDIS_REST_*) shares them, but it only matters with more than one instance. - Built-in pages show a placeholder URL. The docs pages,
robots.txt,sitemap.xmlandllms.txtare rendered when the image is built, before your URL exists, so they showhttp://localhost:3000. Email links, sign-in, the API and MCP use your real URL. - Google sign-in, Telegram alerts and the other optional settings in upstream’s
.env.examplecan be added as variables on the service.
Service configuration
- db: mongodb. Private service. 1 GiB persistent storage.
- MailCheap: ghcr.io/unbroker-app/mailcheap-container:sha-6225f69e3c98b42745fab34d827f7b5ed4d3c63c. Public URL.
Project links
More templates
Configuration and instructions from the public template repository. Check the application's license and complete the setup steps before using it in production.