Files
docker-postfix/README.md
T
Ketan Patel 2a9a7c6baa
Build and Push Docker Image / build (push) Successful in 1m52s
Merge newer Postfix implementation into Gitea and update Alpine
2026-10-02 23:51:09 -04:00

9.4 KiB

Docker Postfix SMTP Relay

A lightweight Postfix SMTP relay container supporting multiple email service providers including Maileroo, Mailtrap, SendGrid, and any generic SMTP server.

The image uses Alpine 3.24 (musl libc) and is published as k2patel/postfix:latest. Builds run on Gitea for pushes to main, monthly, or by manual dispatch.

Features

  • 🚀 Multi-provider support (Maileroo, Mailtrap, SendGrid, Gmail, Office365, any SMTP)
  • 🔒 TLS/SSL encryption
  • 🌐 Auto-detects /16 subnet for relay
  • 📝 All logs to stderr (docker logs)
  • 🏥 Built-in health checks
  • 🔧 Simple Makefile-based operations

Quick Start

1. Clone and Configure

git clone https://git.k2patel.in/k2patel/docker-postfix.git
cd docker-postfix
cp env.sample .env
nano .env  # Edit with your SMTP provider details

2. Build and Start

cd test
make build
make up

3. Test

cd test
make test TO=your@email.com

Configuration

Environment Variables

Variable Required Default Description
SMTP_SERVER Yes - SMTP server hostname
SMTP_PORT Yes 587 SMTP server port
SMTP_USERNAME Yes - SMTP username
SMTP_PASSWORD Yes - SMTP password
DOMAIN Yes - Domain for outgoing mail
SERVER_HOSTNAME No Auto Server FQDN
TIMEZONE No America/New_York Timezone
SMTP_NETWORKS No Auto /16 Additional networks (comma-separated CIDR)
SMTP_LISTEN_PORT No 25 Port to expose on host
LOCAL_NETWORK No Auto-detected Override local network CIDR (e.g., 192.168.0.0/16)
DEBUG No no Enable debug logging

Provider Examples

Maileroo

SMTP_SERVER=smtp.maileroo.com
SMTP_PORT=587
SMTP_USERNAME=noreply@example.com
SMTP_PASSWORD=your_password
DOMAIN=example.com

Mailtrap

SMTP_SERVER=live.smtp.mailtrap.io
SMTP_PORT=587
SMTP_USERNAME=your_username
SMTP_PASSWORD=your_password
DOMAIN=example.com

SendGrid

SMTP_SERVER=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USERNAME=apikey
SMTP_PASSWORD=your_api_key
DOMAIN=example.com

Note: For SendGrid, username must be apikey (literal string).

Gmail

SMTP_SERVER=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your_email@gmail.com
SMTP_PASSWORD=your_app_password
DOMAIN=gmail.com

Makefile Commands

All operations are handled through the Makefile in the test/ directory.

Setup Commands

cd test

make build       # Build the Docker image
make up          # Start the container
make down        # Stop the container
make restart     # Restart the container

Monitoring Commands

make logs        # View logs (follow mode)
make logs-tail   # View last 100 lines
make status      # Show container and Postfix status
make queue       # View mail queue
make health      # Check container health

Maintenance Commands

make shell       # Open shell in container
make config      # Show Postfix configuration
make test        # Send test email (auto-detects container)
make flush       # Flush mail queue
make check       # Validate Postfix configuration

Cleanup Commands

make clean       # Remove container and volumes
make clean-all   # Remove everything including images

Advanced Commands

make debug       # Start with debug mode enabled
make validate    # Validate .env file
make queue-delete # Delete all messages in queue
make stats       # Show real-time container stats

Full Command List

Run make help or just make to see all available commands:

cd test
make

Network Configuration

The container automatically allows relay from:

  • Localhost (127.0.0.0/8)
  • Auto-detected /16 subnet

To add custom networks:

SMTP_NETWORKS=192.168.1.0/24,10.0.0.0/8

Using with Applications

Configure your application to use the relay:

services:
  your-app:
    environment:
      MAIL_HOST: postfix-relay
      MAIL_PORT: 25
    depends_on:
      - postfix

Connection details:

  • Host: postfix-relay
  • Port: 25
  • Authentication: Not required for local network

Testing

The easiest way to test your Postfix relay:

cd test
make test TO=recipient@example.com

That's it! No configuration needed.

What Gets Auto-Detected?

The test script automatically finds and configures:

Feature What Happens Override Option
Container Name Finds containers using docker-postfix-postfix image Specify as first arg
FROM Address Uses noreply@DOMAIN from container env FROM=email@domain.com
SMTP Port Detects mapped port (e.g., 25 or custom) N/A (always detected)
Host IP Converts 0.0.0.0 → 127.0.0.1 for local testing N/A (always detected)
Subject Defaults to "Test Email from Postfix Relay" SUBJECT="Your Subject"

No manual configuration required - just provide the recipient email!

Advanced Testing Options

With custom FROM address:

make test TO=user@example.com FROM=noreply@mydomain.com

With custom subject:

make test TO=user@example.com FROM=sender@domain.com SUBJECT="My Test Email"

Using the test script directly:

./test-email.sh user@example.com
./test-email.sh user@example.com sender@mydomain.com
./test-email.sh user@example.com sender@mydomain.com "Custom Subject"

Manual container specification (if auto-detection fails):

./test-email.sh my-container user@example.com sender@domain.com

Test Script Features

The test-email.sh script automatically:

  • Finds containers using docker-postfix-postfix image
  • Detects port mapping and converts 0.0.0.0 to 127.0.0.1
  • Uses proper SMTP protocol via sendmail
  • Falls back to mail command if needed
  • Shows queue status after sending
  • Provides colored output for easy reading

Validation Tests

cd test
make check       # Validate Postfix configuration
make validate    # Validate .env file
make queue       # View mail queue
make config      # Show current Postfix config

Troubleshooting

Email Not Received

1. Check container logs:

cd test
make logs-tail   # Last 100 lines
make logs        # Follow in real-time

2. Check mail queue:

make queue       # View queued messages
make flush       # Force processing

3. Verify configuration:

make config      # Show Postfix config
make check       # Validate config
make validate    # Validate .env file

SMTP Protocol Errors

If you see "improper command pipelining" errors:

Use the test script (handles protocol correctly):

./test-email.sh user@example.com sender@domain.com

Verify FROM domain matches DOMAIN setting:

# In .env file
DOMAIN=mydomain.com

# Use matching FROM address
make test TO=user@example.com FROM=noreply@mydomain.com

Check mynetworks configuration:

docker exec postfix-relay postconf mynetworks

Container Not Auto-Detected

1. Verify container is running:

docker ps | grep postfix

2. Start the container:

cd test
make up

3. Manually specify container:

./test-email.sh my-container-name user@example.com

Enable Debug Mode

For detailed SMTP transaction logs:

cd test
make debug

Emails Stuck in Queue

cd test
make queue          # View queue
make flush          # Force processing
make queue-delete   # Delete all (with confirmation)

Network Configuration Issues

Override auto-detected network:

# In .env file
LOCAL_NETWORK=192.168.1.0/24

Add additional networks:

SMTP_NETWORKS=10.0.0.0/8,172.16.0.0/12

Container Health Issues

cd test
make status      # Check status
make health      # Check health status
make restart     # Restart container
make down        # Stop container
make up          # Start fresh

Examples

Testing Examples

Simple test with Gmail:

cd test
make test TO=youraddress@gmail.com
# FROM will auto-detect from DOMAIN in .env

Test with custom FROM and subject:

make test TO=client@example.com FROM=support@mycompany.com SUBJECT="Production Test"

Test from command line:

./test-email.sh user@example.com noreply@mydomain.com "Hello World"

Verify email was sent:

make queue       # Should show empty queue if sent
make logs-tail   # Check for "status=sent"

Basic Workflow

# Initial setup
cd docker-postfix
cp env.sample .env
nano .env

# Build and start
cd test
make build
make up

# Check status
make status
make logs

# Test email delivery
make test TO=your@email.com

# Stop
make down

Development Workflow

cd test

# Start with debug
make debug

# Check logs in another terminal
make logs

# Restart after changes
make restart

# Clean up
make clean

Monitoring Workflow

cd test

# Check everything
make status
make health
make queue
make logs-tail

# Continuous monitoring
make logs

Security

  • Store credentials in .env (never commit to git)
  • Limit relay to trusted networks only
  • TLS automatically enabled for known providers
  • Use app-specific passwords for Gmail

License

MIT License - See LICENSE file for details.

Support

For issues and questions, please open an issue on Gitea.