How to Configure Docker Containers to Use Host’s Postfix Mail Server for SMTP Relay


2 views

When attempting to send mail from Docker containers through the host's Postfix installation, we encounter several authentication and header issues. From the maillog, we can see three critical problems:

  • Missing Date header (MISSING_DATE)
  • Missing From header (MISSING_FROM)
  • Missing Message-ID (MISSING_MID)

There are two primary approaches to solve this:

# Solution 1: Direct sendmail binary mounting
docker run -v /usr/sbin/sendmail:/usr/sbin/sendmail:ro your-container

# Solution 2: Proper SMTP configuration
docker run -e SMTP_HOST=host.docker.internal your-container

The first approach is simpler but has security implications. The second approach is more robust but requires proper Postfix configuration.

Edit your Postfix configuration (/etc/postfix/main.cf):

# Allow Docker subnet
mynetworks = 127.0.0.0/8 [::1]/128 172.17.0.0/16

# Force proper headers
smtpd_helo_required = yes
smtpd_sender_restrictions = reject_unknown_sender_domain
smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination

For applications that don't set proper headers, create a wrapper script:

#!/bin/sh
{
    echo "From: youruser@yourdomain.com"
    echo "Date: $(date -R)"
    echo "Message-ID: <$(date +%s).$(openssl rand -hex 8)@yourdomain.com>"
    echo "Content-Type: text/plain; charset=UTF-8"
    echo ""
    cat -
} | /usr/sbin/sendmail -t "$@"

Ensure your OpenDKIM configuration includes:

AutoRestart         Yes
AutoRestartRate     10/1h
UMask               002
Syslog              Yes
SyslogSuccess       Yes
LogWhy              Yes
Canonicalization    relaxed/simple
Mode                sv
SubDomains          no

Create a test container with:

docker run --rm -it alpine sh -c "echo 'Test message' | sendmail -f valid@yourdomain.com recipient@example.com"

Check your mail logs to verify proper header injection and DKIM signing.

For containers that can't use the host's sendmail:

# Dockerfile snippet
RUN apt-get update && apt-get install -y ssmtp
COPY ssmtp.conf /etc/ssmtp/ssmtp.conf

# ssmtp.conf contents
mailhub=host.docker.internal:25
hostname=yourdomain.com
FromLineOverride=YES
UseTLS=NO
UseSTARTTLS=NO

When running applications in Docker containers that need email functionality, we often want to leverage the host's existing Postfix configuration rather than setting up separate mail services inside each container. The challenge lies in maintaining proper email headers (Message-ID, Date, DKIM signatures) while avoiding spam filters.

The original approach of connecting to Postfix via port 25 from the container results in missing headers because:

Sep 28 23:35:52 dantooine spamd[3175]: spamd: result: . 2 - MISSING_DATE,MISSING_FROM,MISSING_MID

Postfix treats these connections differently than local submissions, often stripping important authentication markers.

The most reliable solution is to mount the host's sendmail binary inside the container:

docker run -v /usr/sbin/sendmail:/usr/sbin/sendmail:ro your-container

This gives containers direct access to the host's mail system while preserving all header processing.

Configure Postfix to accept authenticated submissions on port 587:

# /etc/postfix/master.cf
submission inet n - - - - smtpd
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject

Then configure your container to use SASL authentication when connecting.

For better integration, consider these Docker network options:

# Use host network directly
docker run --network host your-container

# Or create a dedicated network
docker network create mail_network

Here's how to send mail from a Python container using mounted sendmail:

import subprocess

def send_email(to, subject, body):
    message = f"""To: {to}
Subject: {subject}

{body}"""
    process = subprocess.Popen(["/usr/sbin/sendmail", "-t"], stdin=subprocess.PIPE)
    process.communicate(message.encode())

send_email("recipient@example.com", "Test", "This is a test email")

After configuration, verify your DKIM signatures are properly added:

cat /var/log/mail.log | grep DKIM

You should see entries like:

opendkim[1234]: ABC123: DKIM-Signature field added

If emails still get marked as spam:

  1. Check SPF records include your Docker subnet
  2. Verify reverse DNS matches your sending domain
  3. Ensure proper FROM headers in your application