Recipients from anywhere
Type them in, paste a block (Jane Doe
Typed in, pasted, uploaded as CSV, or pulled straight from LDAP / Active Directory. Self-hosted, and it runs offline.
docker run -d -p 8000:8000 \
-e SECRET_KEY=$(openssl rand -base64 36) \
-e ADMIN_PASSWORD=choose-one \
-v mailer-data:/data \
ghcr.io/timothestoifl24/bulk-mailer:latestOpen http://127.0.0.1:8000 and sign in as admin. The full walkthrough, including a Compose stack with PostgreSQL, is in Setup.
Built with FastAPI, Jinja2 and SQLAlchemy, a Tabler (Bootstrap 5) interface vendored locally rather than pulled from a CDN, and either SQLite or PostgreSQL. No JavaScript build step — server-rendered pages you can run on a workstation, a small VPS, or fully offline on an isolated network.
This tool will happily send to every address a directory returns. It has no opinion about whether it should.
Sending responsibly
Check the throttle against your mail server's rate limit. Do a dry run. Send a test to yourself. Make sure the recipients actually expect the message.
The unsubscribe link is in the default template for a reason — keep it.
| Guide | A first campaign, start to finish |
| Screenshots | Every screen, before you install anything |
| Setup | Docker, Compose, or from source |
| Advanced config | PostgreSQL, LDAP sign-in, list sync, deployment |
| Upgrading | Versioning, schema changes, what to check |
| FAQ | The questions that come up |
| Contributing | Development setup, tests, releases |
Bug reports and questions go to Issues and Discussions. Security problems go privately, never to a public issue.