Prerequisites
- Python 3.8 or later.
- A POSIX filesystem that supports
fcntl.flock()(Linux, macOS). opensslavailable onPATHfor automatic TLS certificate generation.- Root or
CAP_NET_BIND_SERVICEif binding to privileged ports (25, 143, 465, 587, 993). - No third-party Python packages required.
Installation from Source
git clone <repo> rmail
cd rmail
There is no build step. The server runs directly from the source tree.
Optional: Install as a Systemd Service
sudo python3 run.py install
This writes a systemd unit file at /etc/systemd/system/rmail.service,
enables the service, and starts it. The service restarts automatically on failure.
Use the Makefile targets for day-to-day management:
make start
make stop
make restart
make status
make logs
To remove the service:
sudo python3 run.py uninstall
Configuration
Generate a default config.json:
python run.py init
Open config.json and set at minimum:
hostname— the FQDN of your mail server (e.g.mail.example.com).domains— the list of accepted mail domains (e.g.["example.com"]).
{mail_root}/tls/. To use a CA-signed certificate, set
tls.cert_file and tls.key_file in config.json before starting.
Starting the Server
python run.py
On first run, if config.json does not exist, defaults are written automatically.
The server starts SMTP, IMAP, and the Exchange API listeners, then waits for connections.
sudo
or grant the Python binary CAP_NET_BIND_SERVICE.
Creating Users
make user
You will be prompted for an email address (e.g. alice@example.com) and a password.
The user directory and default mailboxes (INBOX, Sent, Drafts, Trash) are created immediately.
Additional user management commands:
make passwd # change a user's password
make deluser # delete a user
make listusers # list all users for a domain
Verifying the Installation
sudo python3 run.py diagnose
The diagnostic tool runs 8 phases covering configuration, user management, storage, SMTP, delivery, IMAP, the Exchange API, and cleanup. A passing run reports 0 failures and 0 warnings.
Migrating from a Previous Version
If upgrading from a version that stored messages using index.json and
msg-{uid}.eml files:
python run.py migrate
Each mailbox is converted to status.json plus shard directories with
flag-encoded filenames. The original index.json is preserved as
index.json.migrated.