NodeMailServer
Reference

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:

ComponentCopyTo
Node mail serverserver/.env.exampleserver/.env
KumoMTAoutbound/.env.exampleoutbound/.env
KumoMTA relayrelay/.env.examplerelay/.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

VariableDefaultDescription
INCOMING_MAIL_HOSTthe machine's hostnameHostname of the receiving server, for example mx.example.com. Also used for the MX record.
OUTGOING_MAIL_HOSTINCOMING_MAIL_HOSTHostname of the sending server, for example mail.example.com.
MAIL_SERVER_IPnoneThe server's public IP address. Used to build the SPF record.
MAX_EMAILS_PER_MINUTE5Rate limit for the submission port and the JSON API, unless outgoing.rateLimit.maxConnectionsPerMinute is set in mail.config.json.
DOMAIN_NAMEnoneThe domain to generate DNS records for. Only used by the generator (start.ts), which the setup script sets.

TLS

VariableDescription
TLS_PRIVATE_KEY_PATHPath to the private key, for example /etc/letsencrypt/live/mail.example.com/privkey.pem.
TLS_CERTFICATE_PATHPath to the certificate chain. The name is spelled this way in the code.

See TLS certificates.

DKIM

VariableDefaultDescription
DKIM_PRIVATE_KEYnonePrivate key used to sign outgoing mail. Write line breaks as \n.
DKIM_SELECTORdefaultThe selector in your DKIM DNS record.

PGP

VariableDescription
PGP_PRIVATE_KEYArmored private key.
PGP_PUBLIC_KEYArmored public key.
PGP_REVOCATION_CERTIFICATEArmored revocation certificate.
PGP_PASSPHRASEPassphrase for the private key.

See PGP encryption.

Files

VariableDefaultDescription
MAIL_SPOOL_DIR./spoolWhere queued mail, the bounce tracking records and the suppression list are stored.
MAIL_DATA_DIR./dataThe 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.jsonBehaviour: checks, limits, queue and bounces.
SMTP_MESSAGES_PATH./config/smtp-messages.jsonThe 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

VariableDefaultDescription
OUTBOUND_DRIVERrelay if OUTBOUND_RELAY_HOST is set, otherwise directdirect (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.

VariableDefaultDescription
OUTBOUND_RELAY_HOSTemptyRelay hostname.
OUTBOUND_RELAY_PORT587Relay port.
OUTBOUND_RELAY_USERemptyRelay username.
OUTBOUND_RELAY_PASSemptyRelay password.
OUTBOUND_RELAY_CA_PATHemptyCertificate authority file, if the relay uses your own CA.
OUTBOUND_RELAY_TLSverify, or insecure for a loopback hostverify requires a valid certificate. insecure accepts a self-signed one. none sends in plain text.
OUTBOUND_RELAY_MAX_CONNECTIONS5Connections kept open to the relay.

KumoMTA HTTP driver

Used when OUTBOUND_DRIVER is kumo-http.

VariableDefaultDescription
KUMO_HTTP_URLhttp://127.0.0.1:8000KumoMTA's HTTP listener.
KUMO_HTTP_USERemptyBasic authentication user.
KUMO_HTTP_PASSemptyBasic authentication password.
KUMO_HTTP_TIMEOUT_MS30000Timeout for each request.
KUMO_HTTP_STATIC_CONTENTtrueSends 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.

VariableDefaultDescription
GO_MTA_URLhttp://127.0.0.1:2580The Go MTA service.
GO_MTA_TOKENemptyBearer token for the service.
GO_MTA_TIMEOUT_MS300000Timeout for each delivery request.

Bounces

VariableDefaultDescription
BOUNCE_DOMAINemptyDomain for return addresses, for example bounces.example.com. Messages keep the sender's own return address until it is set.
BOUNCE_SMTP_HOST0.0.0.0Address of the bounce SMTP server.
BOUNCE_SMTP_PORT2525Port of the bounce SMTP server. 0 turns it off.
BOUNCE_HTTP_HOST0.0.0.0Address of the bounce HTTP server.
BOUNCE_HTTP_PORT8025Port of the bounce HTTP server. 0 turns it off.
BOUNCE_WEBHOOK_TOKENemptyBearer token for the bounce HTTP server. The HTTP server does not start without it.
BOUNCE_EVENTS_WEBHOOK_URLemptyEvery bounce event is posted here as JSON.
BOUNCE_EVENTS_WEBHOOK_TOKENemptySent as a Bearer token with each event.

See Bounces.

JSON send API

VariableDefaultDescription
MAIL_API_HOST0.0.0.0Address to listen on.
MAIL_API_PORT8080Port to listen on.
MAIL_API_TOKENemptyBearer token. The API does not start without it.

See JSON send API.

Worker threads

VariableDefaultDescription
MAIL_WORKERSCPU cores minus 1, at most 4Number of threads. 0 uses the main thread.
MAIL_WORKER_CONCURRENCY4Tasks one worker runs at the same time.
MAIL_WORKER_MAX_QUEUE1000Tasks allowed to wait. When full, clients get 451 4.3.2.
MAIL_WORKER_TIMEOUT_MS120000Longest a single task may run.

See Background workers.

IMAP storage (optional)

VariableDefaultDescription
IMAP_LMTP_HOSTunsetIMAP server to store incoming mail in, over LMTP. In Docker: imap. Unset: mail is checked but not stored.
IMAP_LMTP_PORT24The IMAP server's LMTP port.
IMAP_LMTP_TIMEOUT_MS60000Longest wait for the IMAP server. After that the sender is told to retry.

See IMAP.

ARC (optional)

VariableDefaultDescription
ARC_PRIVATE_KEY_PATHemptyPath to the ARC signing key.
ARC_SIGNING_DOMAINemptyDomain that signs the ARC headers.
ARC_SELECTORdefaultARC selector.

ARC sealing is on only when both the key path and the signing domain are set.

KumoMTA (outbound/.env)

VariableDefaultDescription
KUMOMTA_HOSTNAMEmail.enjoys.inHostname for the SMTP banner and EHLO. It must match the server's PTR record.
KUMOMTA_SOURCE_IPSunsetComma-separated outbound IPs. Leave unset to use the default route.
USE_RELAYtrue when unsettrue checks the sender's domain against domains.lua and DKIM-signs. false skips both.
DKIM_BACKENDfileWhere DKIM keys come from: file, http or redis.
DKIM_SELECTORdefaultDKIM selector.
DKIM_HTTP_URLnoneKey service URL when the backend is http.
DKIM_API_KEYnoneSent as the X-API-Key header to the key service.
REDIS_HOST127.0.0.1Redis host when the backend is redis.
REDIS_PORT6379Redis port.
WEBHOOK_URLunsetDelivery events are posted here as JSON. Leave unset to turn webhooks off.
WEBHOOK_SECRET2025Read by the policy, but not sent with webhook requests yet.

See KumoMTA configuration.

KumoMTA relay (relay/.env)

Accounts, their domains and their webhooks are not set here. They live in relay/policy/users.lua. See Relay.

VariableDefaultDescription
KUMOMTA_HOSTNAMErelay.example.comHostname for the SMTP banner and EHLO. It must match the sending IP's PTR record.
KUMOMTA_SOURCE_IPSunsetComma-separated outbound IPs. Leave unset to use the default route.
RELAY_LISTEN0.0.0.0:2587Listener address inside the container.
RELAY_TLS_CERTunsetCertificate for STARTTLS. Without it, KumoMTA uses a self-signed one.
RELAY_TLS_KEYunsetPrivate key for RELAY_TLS_CERT.
RELAY_SMARTHOSTunsetSend everything to this host instead of each recipient's MX.
RELAY_SMARTHOST_PORT587Smarthost port.
RELAY_SMARTHOST_USERunsetSmarthost login. Leave unset for no login.
RELAY_SMARTHOST_PASSemptySmarthost password.
RELAY_SMARTHOST_TLSRequiredRequired, RequiredInsecure, Opportunistic, OpportunisticInsecure or Disabled.
RELAY_SMARTHOST_CONNECTIONS10Maximum connections to the smarthost.
RELAY_RETRY_INTERVAL1mFirst retry delay for mail.
RELAY_MAX_RETRY_INTERVAL4hLongest delay between retries.
RELAY_MAX_AGE24hHow long mail is retried before it bounces.
DKIM_BACKENDfileWhere DKIM keys come from: file, http, redis or none.
DKIM_SELECTORdefaultDKIM selector.
DKIM_HTTP_URLnoneKey service URL when the backend is http.
DKIM_API_KEYnoneSent as the X-API-Key header to the key service.
REDIS_HOST127.0.0.1Redis host when the backend is redis.
REDIS_PORT6379Redis port.
WEBHOOK_MAX_AGE3dHow long an event keeps being retried before it is dropped.
WEBHOOK_TIMEOUT10sTimeout for each webhook request.

On this page