Sign inSign up

garfieldwtf/mail-relay

By garfieldwtf

•Updated about 21 hours ago

Image
0

717

garfieldwtf/mail-relay repository overview

⁠MailMule

MailMule is a Dockerized SMTP relay gateway with a domain routing UI, authenticated mail submission, a persistent delivery queue, and mail activity logs. Its layout follows the mail proxy model used by Proxmox Mail Gateway⁠: relay domains, transport destinations, trusted sender networks, TLS, and outbound smarthost settings. Spam and virus filtering are not included.

This is a mail gateway, not a mailbox server. Destination servers store recipients' mail.

⁠Deploy with Docker Compose

Create a directory and save this as compose.yaml:

services:
  relay:
    image: garfieldwtf/mail-relay:latest
    container_name: mail-relay
    restart: unless-stopped
    ports:
      - "0.0.0.0:25:25"
      - "0.0.0.0:465:465"
      - "0.0.0.0:587:587"
      # Admin UI stays local. Put it behind HTTPS or use a VPN/SSH tunnel.
      - "127.0.0.1:8080:8080"
    environment:
      ADMIN_USER: admin
      ADMIN_PASSWORD: change-this-to-a-long-random-secret
      PUBLIC_HOSTNAME: relay.example.com
      TRUSTED_NETWORKS: 127.0.0.0/8
      DATABASE_PATH: /data/relay.sqlite3
      # Optional: all outbound traffic not matched by a relay-domain route goes here.
      OUTBOUND_SMARTHOST: ""
      OUTBOUND_SMARTHOST_USERNAME: ""
      OUTBOUND_SMARTHOST_PASSWORD: ""
    volumes:
      - ./relay-data:/data
      - ./certs:/certs:ro
      - ./relay-queue:/var/spool/postfix
      - ./relay-logs:/var/log/postfix

Set a unique admin password and PUBLIC_HOSTNAME, then start the gateway:

docker compose up -d

The first run creates a persistent self-signed certificate so all SMTP listeners can start. Before using it with real mail clients, mount a valid certificate chain and private key as ./certs/fullchain.pem and ./certs/privkey.pem, then recreate the container. The key and certificate must match PUBLIC_HOSTNAME.

The admin UI uses a sign-in page with expiring sessions and is bound to localhost at port 8080. It has a Log out button; change the admin username or password in Gateway Settings. Password changes end all active sessions. Access it through an HTTPS reverse proxy, VPN, or SSH tunnel, and keep the admin interface restricted.

⁠SMTP listeners

PortProtocolUse
25SMTP with optional STARTTLSInternet inbound mail for configured relay domains; trusted networks may submit outbound mail
465SMTP over implicit TLSAuthenticated client submission
587SMTP with mandatory STARTTLSAuthenticated client submission

Create SMTP accounts in SMTP Accounts. Use login@PUBLIC_HOSTNAME as the SMTP username and the account password you set. Submission on ports 465 and 587 requires authentication; unauthenticated clients cannot relay outbound mail.

⁠Configure inbound domain routing

  1. Open the admin UI and add a relay domain under Mail Routing.
  2. Choose Use destination domain MX and enter a domain, or choose Direct to host and enter a host or IPv4 address such as 10.0.0.25:25.
  3. Point that domain's MX record to PUBLIC_HOSTNAME and allow inbound TCP port 25 through your firewall.
  4. Configure the destination server to accept mail from this gateway.

Unknown recipient domains are rejected. MX delivery resolves the configured destination domain's MX records. Direct delivery sends all recipients in that configured relay domain to the selected server. Existing routes are retained as direct-host routes when upgrading. Trusted networks can be managed in Trusted Networks; those networks may relay externally through port 25, so only add networks you control.

⁠Outbound delivery

By default, submitted messages are delivered directly to recipient MX servers. Configure a default outbound smarthost in Gateway Settings using bracket syntax, for example [smtp.provider.example]:587. TLS is required when an outbound smarthost is set. If it requires SMTP authentication, enter both the username and password. The values are stored in the protected persistent database; the environment variables remain available as first-run defaults.

If the mail log reports mail for <domain> loops back to myself, make sure the route points to the backend mail server, not the gateway. For a backend on the same Docker host, use its private IPv4 address and SMTP port.

The gateway listens and sends mail over IPv4 only. Messages deferred by a destination remain in the persistent Postfix queue. Inspect and retry queued delivery in Mail Queue. Recent SMTP and delivery events appear in Mail Log. The mounted relay-data directory stores route and SMTP account data, DKIM private keys, generated maps, and the TLS bootstrap certificate; relay-queue stores queued messages; relay-logs stores SMTP activity logs. Back up these directories and keep relay-data private.

⁠SPF, DKIM, and DMARC

Use Email Authentication in the dashboard to create DNS records for each domain that sends mail through MailMule. SPF and DMARC are DNS TXT records; MailMule generates their values for you. DKIM is signed by MailMule for authenticated submissions on ports 465/587 and messages relayed from Trusted Networks. Public inbound mail forwarded to a destination server is not signed as if it originated from your domain.

Enter the public IPv4 address that recipient mail servers see. If you send through an outbound smarthost, use the provider's published SPF include domain or its actual sending IP. Copy the generated TXT records into the DNS control panel for the domain, often available from the domain registrar:

RecordDNS namePurpose
SPF@Lists the authorized outbound sending IP and optional provider includes
DKIM<selector>._domainkeyPublishes the public key corresponding to MailMule's private signing key
DMARC_dmarcStarts with monitoring policy and can optionally send aggregate reports

If your domain already has an SPF record, merge MailMule's IP/include into that record instead of creating a second SPF TXT record. If a DMARC record already exists, update it rather than adding another. Use ~all and p=none while checking that all legitimate senders are covered; move to -all, quarantine, or reject only after reviewing your mail sources. Create the DMARC report mailbox before enabling rua reports.

MailMule keeps DKIM signing disabled until its Verify DKIM DNS and enable signing action finds the exact generated public key in DNS. Once enabled, MailMule signs outbound messages for that domain. Keep the persistent data directory protected because it contains the DKIM private key. SPF authorizes the final outbound sending IP; DMARC evaluates alignment of SPF or DKIM with the visible From domain. MailMule generates these records but does not perform inbound spam filtering or DMARC enforcement.

⁠Security and filtering

The gateway uses Postfix for IPv4-only SMTP transport, domain acceptance, routing, TLS, SASL authentication, DKIM signing, and queueing. Spam scoring, blocklists, antivirus, quarantine, and content filtering are intentionally not part of this image. Configure SPF and DMARC DNS records for your sending domains and protect the admin UI with HTTPS and network access controls.

⁠Supported architectures and publishing

The published multi-platform image supports linux/amd64 and linux/arm64. Docker selects the matching image automatically.

docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t garfieldwtf/mail-relay:latest \
  --push .

Tag summary

Content type

Image

Digest

sha256:bfd924159…

Size

97.6 MB

Last updated

about 21 hours ago

docker pull garfieldwtf/mail-relay