A Django app and smtp relay service for working with 3rd party email services (well, just Postmark initially. Also supports delivery to an MH email box on the same machine (for use with asimap hosted on the same machine).
- Linux host running docker with at least 2gb of RAM to run all of the services. More if you have a lot of email servers at postmark that this is handling email for.
The docker-compose.yml file in this repo has all that is necessary to run the system services. Most configuration for dealing with postmark and users is handled directly within the django-admin. For setting up the service itself you will need a .env file with the necessary values filled in.
Here is a minimal set of env. vars you will need to set in the .env for your services:
# This project uses a .env file for basic configuration and passing secrets to
# the AS Email Service.
#
# Naturally due to the sensitive nature of this file access to it must be
# carefully controlled.
#
# This is a get-the-thing-off-the-ground setup.
#
# The following env. vars are required for the service to function.
#
DJANGO_SECRET_KEY=<your sites secret key here>
EMAIL_BACKEND=<backend to use>
ANYMAIL="key1=value1,key2=value2"
SITE_NAME=your_email_server.your.domain
DEFAULT_FROM_EMAIL = "you@example.com"
SERVER_EMAIL = "your-server@example.com"
# JSON mapping of provider name to its API keys. Each provider has an
# "account_api_key" plus per-domain sending keys.
# Must be compact single-line JSON (docker-compose does not support multiline
# .env values). Tip: keep a readable JSON file and generate this with:
# jq -c '.' email_server_tokens.json >> .env
#
EMAIL_SERVER_TOKENS={"forwardemail":{"account_api_key":"<forwardemail-account-api-key>","example.com":"<forwardemail-account-api-key>"},"postmark":{"account_api_key":"<postmark-account-api-token>","example.com":"<postmark-server-api-token>","example.org":"<postmark-server-api-token>"}}
# The container-internal paths where volumes are mounted. These rarely
# need to change.
#
DATABASE_URL=sqlite:////mnt/db/as_email_service.db
EMAIL_SPOOL_DIR=/mnt/spool
MAIL_DIRS=/mnt/mail_dirs
# External (host) directories mounted into the containers. Set these to
# wherever you want data stored on the host.
#
HOST_SPOOL_ROOT=/home/mailapps/spool
HOST_MAIL_ROOT=/home/mailapps/mail_dirs
HOST_DB_DIR=/home/mailapps/dbs
HOST_SPAMA_DIR=/home/mailapps/spama
# as_email expects to find ssl_crt.pem and ssl_key.pem in this directory.
#
HOST_SSL_DIR=/home/mailapps/ssl
# Email addresses users forward misclassified messages to for SpamAssassin
# training. Both must be set to enable user-driven training. See
# docs/sa-training.md for setup instructions.
#
# SPAM_TRAINING_ADDRESS=spam@mail.example.com
# NOT_SPAM_TRAINING_ADDRESS=not-spam@mail.example.com
# What docker tag to pull and run
#
RELEASE_VERSION=latestThe REST API is documented via OpenAPI 3.0. The full reference is available in docs/api.md and the machine-readable spec in docs/openapi.yaml.
When the development server is running you can also browse the interactive docs:
- Swagger UI:
/as_email/api/schema/swagger-ui/ - ReDoc:
/as_email/api/schema/redoc/
To regenerate the docs after making API changes:
make api-docsThe service supports both initial corpus training (running sa-learn directly
against a spam/ham directory) and ongoing user-driven training (users forward
misclassified messages to dedicated addresses, which a management command
processes and stages for sa-learn).
See docs/sa-training.md for full setup and operational instructions.
The SMTP daemon writes structured security log lines that fail2ban can monitor to automatically ban IPs performing brute-force attacks, flooding connections, or using nonexistent accounts. Six jails cover different attack patterns with configurable thresholds and ban durations.
See docs/fail2ban-integration.md for setup instructions and configuration details.
NOTE: This project uses mkcert to generate and use SSL certificates for
development. See https://github.com/FiloSottile/mkcert for details. The Makefile and supporting scripts assume that you have already run mkcert -install to setup the local trusted CA for development.
The canonical Python version is defined in .python-version at the project root.
uv and make build read it automatically.
To bump the Python version:
- Update
requires-pythoninpyproject.tomlto the newx.y.zversion - Update the
image:field in.drone.ymltopython:<x.y.z> - Run
make uv-syncto rebuild the local venv
Even if you are not going to download new python and node modules you need at least these packages installed for local development:
- python (3.13 or greater)
- npm
- docker
[./LICENSE](BSD 3-Clause License)
This favicon was generated using the following graphics from Twitter Twemoji:
- Graphics Title: 1f4e8.svg
- Graphics Author: Copyright 2020 Twitter, Inc and other contributors (https://github.com/twitter/twemoji)
- Graphics Source: https://github.com/twitter/twemoji/blob/master/assets/svg/1f4e8.svg
- Graphics License: CC-BY 4.0 (https://creativecommons.org/licenses/by/4.0/)