Docker Email Marketing Stack: Tools and Architecture
How to design a Docker-based email marketing stack: which services to containerize, why to separate sending from lists, an example Compose architecture, and the data you must persist.
Overview
Running your email marketing stack in Docker gives you reproducible, portable infrastructure you can stand up anywhere — a VPS, a PaaS, or your laptop. The key design decisions are which services to containerize, how to separate concerns, and what state you must persist. Get those right and the stack is easy to move and upgrade; get them wrong and you'll lose data or couple things that should be independent.
The services and how to split them
A typical email stack in Docker runs a few containers: the sending app (useSend) with its Postgres and Redis; optionally a list manager (Listmonk has an official image and needs Postgres; Mautic needs PHP + MySQL); and your own app. Keep sending separate from list management as distinct services so you can scale, upgrade, or replace one without touching the other — the same separation that keeps any self-hosted stack maintainable.
Delivery still goes out through Amazon SES or an SMTP provider — you don't containerize a mail server (MTA) for production sending, because IP reputation isn't something a container fixes. The containers run the apps; SES runs the delivery.
- useSend container + Postgres + Redis
- Optional Listmonk (Postgres) or Mautic (PHP/MySQL)
- Keep sending and list management as separate services
- Delivery via SES/SMTP — don't containerize an MTA
Compose architecture and persisting data
A Docker Compose file wires the services with a private network, environment variables for secrets (or a secrets manager), and named volumes for anything stateful. The non-negotiable: persist your databases (Postgres/MySQL) and any uploaded assets to named volumes or external managed databases — a container is ephemeral, and losing the database means losing your subscriber list and send history.
Managed PaaS like Coolify and Railway wrap this Compose/Docker model with one-click services and managed databases, which is why they're popular for this. Whatever the host, deliverability (SPF/DKIM/DMARC, warmup, suppression) is still yours, and a workflow layer like Mailbase can point at the useSend container you run.
- Compose: private network, env-var/secret config, named volumes
- Persist databases + assets — containers are ephemeral
- Coolify/Railway wrap this with managed databases
- Deliverability and a workflow layer still sit on top
Common Mistakes
- Assuming “self-hosted” means plug-and-play — DNS and SES work remain.
- Forgetting the SES sandbox exit and SNS bounce/complaint wiring.
- Self-hosting the app but expecting it to fix IP reputation for you.
- Skipping the workflow layer and stitching five tools together by hand.
Sources & Further Reading
Official docs for current setup details, pricing, and API behavior — verify specifics there, since they change.
Related guides
More on docker email marketing stack and the surrounding self-hosted email workflow:
FAQ
How do I build an email marketing stack with Docker?
Containerize the apps — a sending app like useSend with its Postgres and Redis, optionally a list manager like Listmonk — wire them with Docker Compose on a private network, persist databases to named volumes, and relay delivery through Amazon SES. Don't containerize a mail server for production sending.
Should I run my own mail server in Docker?
Not for production marketing/transactional sending — IP reputation is a full-time job a container won't solve. Run your sending app (useSend) in Docker and relay through Amazon SES or an SMTP provider that owns the IP reputation.
What data must I persist in a Dockerized email stack?
Your databases (Postgres/MySQL holding subscribers, campaigns, and send history) and any uploaded assets, via named volumes or external managed databases. Containers are ephemeral, so anything not on a volume is lost on recreate — including your entire subscriber list.