Environment variables
Every setting for the Node mail server and for KumoMTA, with defaults.
Settings are read from .env files. Copy the example file and edit it:
| Component | Copy | To |
|---|---|---|
| Node mail server | server/.env.example | server/.env |
| KumoMTA | outbound/.env.example | outbound/.env |
| KumoMTA relay | relay/.env.example | relay/.env |
All .env files are in .gitignore. server/.env.example is always the most current list. Only server/src/config/env.ts reads environment variables, and an invalid number or choice stops the server at startup with a message naming the variable.
Node mail server (server/.env)
Server
| Variable | Default | Description |
|---|---|---|
INCOMING_MAIL_HOST | the machine's hostname | Hostname of the receiving server, for example mx.example.com. Also used for the MX record. |
OUTGOING_MAIL_HOST | INCOMING_MAIL_HOST | Hostname of the sending server, for example mail.example.com. |
MAIL_SERVER_IP | none | The server's public IP address. Used to build the SPF record. |
MAX_EMAILS_PER_MINUTE | 5 | Rate limit for the submission port and the JSON API, unless outgoing.rateLimit.maxConnectionsPerMinute is set in mail.config.json. |
DOMAIN_NAME | none | The domain to generate DNS records for. Only used by the generator (start.ts), which the setup script sets. |
TLS
| Variable | Description |
|---|---|
TLS_PRIVATE_KEY_PATH | Path to the private key, for example /etc/letsencrypt/live/mail.example.com/privkey.pem. |
TLS_CERTFICATE_PATH | Path to the certificate chain. The name is spelled this way in the code. |
See TLS certificates.
DKIM
| Variable | Default | Description |
|---|---|---|
DKIM_PRIVATE_KEY | none | Private key used to sign outgoing mail. Write line breaks as \n. |
DKIM_SELECTOR | default | The selector in your DKIM DNS record. |
PGP
| Variable | Description |
|---|---|
PGP_PRIVATE_KEY | Armored private key. |
PGP_PUBLIC_KEY | Armored public key. |
PGP_REVOCATION_CERTIFICATE | Armored revocation certificate. |
PGP_PASSPHRASE | Passphrase for the private key. |
See PGP encryption.
Files
| Variable | Default | Description |
|---|---|---|
MAIL_SPOOL_DIR | ./spool | Where queued mail, the bounce tracking records and the suppression list are stored. |
MAIL_DATA_DIR | ./data | The server's SQLite database, server.db, with one table per feature (ip_blocks: the blocked IPs). /app/data on the inbound-data volume in Docker. |
MAIL_CONFIG_PATH | ./config/mail.config.json | Behaviour: checks, limits, queue and bounces. |
SMTP_MESSAGES_PATH | ./config/smtp-messages.json | The text and code of each SMTP reply. |
The queue settings that used to be variables (MAX_CONCURRENT_DELIVERIES, MAIL_QUEUE_MAX_AGE_HOURS) and the port 25 rate limit (INCOMING_MAX_MESSAGES_PER_MINUTE) are now in mail.config.json. See Configuration files.
Outbound driver
| Variable | Default | Description |
|---|---|---|
OUTBOUND_DRIVER | relay if OUTBOUND_RELAY_HOST is set, otherwise direct | direct (or node), go, relay or kumo-http. Any other value stops the server at startup. |
See Outbound drivers.
Relay driver
Used when OUTBOUND_DRIVER is relay. Setting OUTBOUND_RELAY_HOST alone also selects it.
| Variable | Default | Description |
|---|---|---|
OUTBOUND_RELAY_HOST | empty | Relay hostname. |
OUTBOUND_RELAY_PORT | 587 | Relay port. |
OUTBOUND_RELAY_USER | empty | Relay username. |
OUTBOUND_RELAY_PASS | empty | Relay password. |
OUTBOUND_RELAY_CA_PATH | empty | Certificate authority file, if the relay uses your own CA. |
OUTBOUND_RELAY_TLS | verify, or insecure for a loopback host | verify requires a valid certificate. insecure accepts a self-signed one. none sends in plain text. |
OUTBOUND_RELAY_MAX_CONNECTIONS | 5 | Connections kept open to the relay. |
KumoMTA HTTP driver
Used when OUTBOUND_DRIVER is kumo-http.
| Variable | Default | Description |
|---|---|---|
KUMO_HTTP_URL | http://127.0.0.1:8000 | KumoMTA's HTTP listener. |
KUMO_HTTP_USER | empty | Basic authentication user. |
KUMO_HTTP_PASS | empty | Basic authentication password. |
KUMO_HTTP_TIMEOUT_MS | 30000 | Timeout for each request. |
KUMO_HTTP_STATIC_CONTENT | true | Sends template_dialect: "Static" so KumoMTA does not template the message. Needs KumoMTA 2025.12.02 or newer. Set to false for older versions. |
Go MTA driver
Used when OUTBOUND_DRIVER is go.
| Variable | Default | Description |
|---|---|---|
GO_MTA_URL | http://127.0.0.1:2580 | The Go MTA service. |
GO_MTA_TOKEN | empty | Bearer token for the service. |
GO_MTA_TIMEOUT_MS | 300000 | Timeout for each delivery request. |
Bounces
| Variable | Default | Description |
|---|---|---|
BOUNCE_DOMAIN | empty | Domain for return addresses, for example bounces.example.com. Messages keep the sender's own return address until it is set. |
BOUNCE_SMTP_HOST | 0.0.0.0 | Address of the bounce SMTP server. |
BOUNCE_SMTP_PORT | 2525 | Port of the bounce SMTP server. 0 turns it off. |
BOUNCE_HTTP_HOST | 0.0.0.0 | Address of the bounce HTTP server. |
BOUNCE_HTTP_PORT | 8025 | Port of the bounce HTTP server. 0 turns it off. |
BOUNCE_WEBHOOK_TOKEN | empty | Bearer token for the bounce HTTP server. The HTTP server does not start without it. |
BOUNCE_EVENTS_WEBHOOK_URL | empty | Every bounce event is posted here as JSON. |
BOUNCE_EVENTS_WEBHOOK_TOKEN | empty | Sent as a Bearer token with each event. |
See Bounces.
JSON send API
| Variable | Default | Description |
|---|---|---|
MAIL_API_HOST | 0.0.0.0 | Address to listen on. |
MAIL_API_PORT | 8080 | Port to listen on. |
MAIL_API_TOKEN | empty | Bearer token. The API does not start without it. |
See JSON send API.
Worker threads
| Variable | Default | Description |
|---|---|---|
MAIL_WORKERS | CPU cores minus 1, at most 4 | Number of threads. 0 uses the main thread. |
MAIL_WORKER_CONCURRENCY | 4 | Tasks one worker runs at the same time. |
MAIL_WORKER_MAX_QUEUE | 1000 | Tasks allowed to wait. When full, clients get 451 4.3.2. |
MAIL_WORKER_TIMEOUT_MS | 120000 | Longest a single task may run. |
See Background workers.
IMAP storage (optional)
| Variable | Default | Description |
|---|---|---|
IMAP_LMTP_HOST | unset | IMAP server to store incoming mail in, over LMTP. In Docker: imap. Unset: mail is checked but not stored. |
IMAP_LMTP_PORT | 24 | The IMAP server's LMTP port. |
IMAP_LMTP_TIMEOUT_MS | 60000 | Longest wait for the IMAP server. After that the sender is told to retry. |
See IMAP.
ARC (optional)
| Variable | Default | Description |
|---|---|---|
ARC_PRIVATE_KEY_PATH | empty | Path to the ARC signing key. |
ARC_SIGNING_DOMAIN | empty | Domain that signs the ARC headers. |
ARC_SELECTOR | default | ARC selector. |
ARC sealing is on only when both the key path and the signing domain are set.
KumoMTA (outbound/.env)
| Variable | Default | Description |
|---|---|---|
KUMOMTA_HOSTNAME | mail.enjoys.in | Hostname for the SMTP banner and EHLO. It must match the server's PTR record. |
KUMOMTA_SOURCE_IPS | unset | Comma-separated outbound IPs. Leave unset to use the default route. |
USE_RELAY | true when unset | true checks the sender's domain against domains.lua and DKIM-signs. false skips both. |
DKIM_BACKEND | file | Where DKIM keys come from: file, http or redis. |
DKIM_SELECTOR | default | DKIM selector. |
DKIM_HTTP_URL | none | Key service URL when the backend is http. |
DKIM_API_KEY | none | Sent as the X-API-Key header to the key service. |
REDIS_HOST | 127.0.0.1 | Redis host when the backend is redis. |
REDIS_PORT | 6379 | Redis port. |
WEBHOOK_URL | unset | Delivery events are posted here as JSON. Leave unset to turn webhooks off. |
WEBHOOK_SECRET | 2025 | Read by the policy, but not sent with webhook requests yet. |
KumoMTA relay (relay/.env)
Accounts, their domains and their webhooks are not set here. They live in relay/policy/users.lua. See Relay.
| Variable | Default | Description |
|---|---|---|
KUMOMTA_HOSTNAME | relay.example.com | Hostname for the SMTP banner and EHLO. It must match the sending IP's PTR record. |
KUMOMTA_SOURCE_IPS | unset | Comma-separated outbound IPs. Leave unset to use the default route. |
RELAY_LISTEN | 0.0.0.0:2587 | Listener address inside the container. |
RELAY_TLS_CERT | unset | Certificate for STARTTLS. Without it, KumoMTA uses a self-signed one. |
RELAY_TLS_KEY | unset | Private key for RELAY_TLS_CERT. |
RELAY_SMARTHOST | unset | Send everything to this host instead of each recipient's MX. |
RELAY_SMARTHOST_PORT | 587 | Smarthost port. |
RELAY_SMARTHOST_USER | unset | Smarthost login. Leave unset for no login. |
RELAY_SMARTHOST_PASS | empty | Smarthost password. |
RELAY_SMARTHOST_TLS | Required | Required, RequiredInsecure, Opportunistic, OpportunisticInsecure or Disabled. |
RELAY_SMARTHOST_CONNECTIONS | 10 | Maximum connections to the smarthost. |
RELAY_RETRY_INTERVAL | 1m | First retry delay for mail. |
RELAY_MAX_RETRY_INTERVAL | 4h | Longest delay between retries. |
RELAY_MAX_AGE | 24h | How long mail is retried before it bounces. |
DKIM_BACKEND | file | Where DKIM keys come from: file, http, redis or none. |
DKIM_SELECTOR | default | DKIM selector. |
DKIM_HTTP_URL | none | Key service URL when the backend is http. |
DKIM_API_KEY | none | Sent as the X-API-Key header to the key service. |
REDIS_HOST | 127.0.0.1 | Redis host when the backend is redis. |
REDIS_PORT | 6379 | Redis port. |
WEBHOOK_MAX_AGE | 3d | How long an event keeps being retried before it is dropped. |
WEBHOOK_TIMEOUT | 10s | Timeout for each webhook request. |