Docker Integration

Docker Email Testing with SendPit

Configure Docker Compose to use SendPit for email testing. No extra containers needed — just point your SMTP config at SendPit.

Introduction

Modern development teams run their applications inside Docker containers. Whether you are building a monolith, a collection of microservices, or a simple staging environment, email testing remains a pain point. The traditional approach is to spin up a local mail catcher such as MailHog or Mailpit as yet another container in your docker-compose.yml. That works on one developer's laptop, but the moment a second developer clones the repo, a CI pipeline runs, or a staging server is provisioned, every environment needs its own mail catcher configured from scratch.

SendPit eliminates that overhead. Because SendPit is a cloud-hosted SMTP sandbox, you do not need an extra container. Every environment -- local Docker, CI runner, staging cluster -- points at the same smtp.sendpit.com endpoint. Emails land in a shared, web-based inbox that the whole team can access. No container to maintain, no ports to expose, no volumes to persist.

This guide walks you through configuring Docker Compose services to use SendPit for email testing, with framework-specific examples, Docker secrets for credential security, multi-service patterns, and CI/CD tips.

Prerequisites

Before you start, make sure you have:

  • Docker Engine 20.10 or later and Docker Compose v2.
  • A SendPit account with at least one mailbox created. You can sign up at sendpit.com.
  • Your SMTP credentials from the SendPit dashboard: host, port, username, and password.

Your SendPit SMTP settings will look like this:

Setting Value
Host smtp.sendpit.com
Port 587
Encryption TLS
Username mb_a1b2c3d4e5f6g7h8
Password Your mailbox password

Setting SMTP Environment Variables

The cleanest way to pass SMTP credentials to a Docker container is through environment variables. Docker Compose offers two approaches: inline environment keys and external env_file references.

Inline environment keys

services:
  web:
    image: myapp:latest
    environment:
      SMTP_HOST: smtp.sendpit.com
      SMTP_PORT: "587"
      SMTP_USERNAME: mb_a1b2c3d4e5f6g7h8
      SMTP_PASSWORD: your-mailbox-password
      SMTP_ENCRYPTION: tls

Using an env_file

Create a .env.sendpit file (and add it to .gitignore):

SMTP_HOST=smtp.sendpit.com
SMTP_PORT=587
SMTP_USERNAME=mb_a1b2c3d4e5f6g7h8
SMTP_PASSWORD=your-mailbox-password
SMTP_ENCRYPTION=tls

Then reference it in your compose file:

services:
  web:
    image: myapp:latest
    env_file:
      - .env.sendpit

The env_file approach keeps credentials out of your docker-compose.yml, making it safer to commit the compose file to version control.

Example docker-compose.yml

Here is a complete, minimal compose file for a web application that sends email through SendPit:

version: "3.8"

services:
  web:
    build: .
    ports:
      - "8000:8000"
    env_file:
      - .env.sendpit
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: myapp
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

Notice there is no mail catcher service. Your application connects to smtp.sendpit.com over the internet, so you only need the services your application actually requires.

Framework-Specific Docker Examples

Laravel with Docker

Laravel reads mail settings from its .env file. You can either mount the .env file into the container or pass environment variables that override Laravel's config.

Option A: Pass environment variables directly

services:
  php:
    build: .
    environment:
      MAIL_MAILER: smtp
      MAIL_HOST: smtp.sendpit.com
      MAIL_PORT: "587"
      MAIL_USERNAME: mb_a1b2c3d4e5f6g7h8
      MAIL_PASSWORD: your-mailbox-password
      MAIL_ENCRYPTION: tls
      MAIL_FROM_ADDRESS: dev@yourapp.com
      MAIL_FROM_NAME: "My App"

Option B: Mount a .env file

services:
  php:
    build: .
    volumes:
      - ./.env:/var/www/html/.env:ro

With either approach, Laravel's config/mail.php will pick up the SendPit credentials automatically. No code changes needed.

Django with Docker

Django reads SMTP settings from settings.py. Configure it to pull from environment variables:

# settings.py
import os

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = os.environ.get('SMTP_HOST', 'smtp.sendpit.com')
EMAIL_PORT = int(os.environ.get('SMTP_PORT', 587))
EMAIL_USE_TLS = True
EMAIL_HOST_USER = os.environ.get('SMTP_USERNAME', '')
EMAIL_HOST_PASSWORD = os.environ.get('SMTP_PASSWORD', '')

Then pass the variables in your compose file:

services:
  django:
    build: .
    env_file:
      - .env.sendpit
    command: gunicorn myproject.wsgi:application --bind 0.0.0.0:8000

Node.js with Docker

Using Nodemailer, configure the transport from environment variables:

const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
  host: process.env.SMTP_HOST || 'smtp.sendpit.com',
  port: parseInt(process.env.SMTP_PORT, 10) || 587,
  secure: false,
  auth: {
    user: process.env.SMTP_USERNAME,
    pass: process.env.SMTP_PASSWORD,
  },
});

And the compose service:

services:
  node:
    build: .
    env_file:
      - .env.sendpit
    ports:
      - "3000:3000"

Docker Secrets for SMTP Credentials

For production-like Docker Swarm deployments or any environment where you want stronger credential isolation, Docker secrets are a better choice than plain environment variables. Secrets are mounted as files inside the container rather than being visible in docker inspect output.

Create the secrets:

echo "mb_a1b2c3d4e5f6g7h8" | docker secret create smtp_username -
echo "your-mailbox-password" | docker secret create smtp_password -

Reference them in your compose file:

version: "3.8"

services:
  web:
    image: myapp:latest
    environment:
      SMTP_HOST: smtp.sendpit.com
      SMTP_PORT: "587"
      SMTP_ENCRYPTION: tls
    secrets:
      - smtp_username
      - smtp_password

secrets:
  smtp_username:
    external: true
  smtp_password:
    external: true

Inside your application, read /run/secrets/smtp_username and /run/secrets/smtp_password as files:

# The secrets are available at these paths inside the container:
/run/secrets/smtp_username
/run/secrets/smtp_password

For local development without Swarm, you can use file-based secrets:

secrets:
  smtp_username:
    file: ./secrets/smtp_username.txt
  smtp_password:
    file: ./secrets/smtp_password.txt

Multi-Service Setups

Real-world applications often have multiple services that send email: a web server for transactional emails, a background worker for queued notifications, and a cron service for scheduled reports. All of them need the same SMTP configuration.

Use YAML anchors or an env_file shared across services:

services:
  web:
    build: .
    env_file:
      - .env.sendpit
    ports:
      - "8000:8000"

  worker:
    build: .
    env_file:
      - .env.sendpit
    command: php artisan queue:work

  cron:
    build: .
    env_file:
      - .env.sendpit
    command: supercronic /etc/crontab

Every service reads the same .env.sendpit file, so credentials are defined once and shared everywhere. When you rotate your SendPit mailbox password, update the single file and restart the containers.

Docker Networking

Unlike local mail catchers that require a shared Docker network between your application container and the mail catcher container, SendPit requires no special networking configuration. Your containers reach smtp.sendpit.com over the public internet, just like they reach any other external service.

This means:

  • No custom Docker networks for email.
  • No links or depends_on entries for a mail service.
  • No internal DNS aliases to manage.
  • Works identically in Docker Compose, Docker Swarm, and Kubernetes.

The only requirement is that your container has outbound internet access on port 587, which is the default for most Docker setups.

CI/CD with Docker

SendPit shines in CI/CD pipelines where spinning up a mail catcher adds complexity and build time. Instead, pass SendPit credentials as CI secrets and let your Dockerized tests send email to the real sandbox.

GitHub Actions

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run tests
        env:
          SMTP_HOST: smtp.sendpit.com
          SMTP_PORT: 587
          SMTP_USERNAME: ${{ secrets.SENDPIT_USERNAME }}
          SMTP_PASSWORD: ${{ secrets.SENDPIT_PASSWORD }}
        run: docker compose -f docker-compose.test.yml up --abort-on-container-exit

GitLab CI

test:
  stage: test
  image: docker:24
  services:
    - docker:24-dind
  variables:
    SMTP_HOST: smtp.sendpit.com
    SMTP_PORT: "587"
    SMTP_USERNAME: $SENDPIT_USERNAME
    SMTP_PASSWORD: $SENDPIT_PASSWORD
  script:
    - docker compose -f docker-compose.test.yml up --abort-on-container-exit

No need to add a mailhog or mailpit service to your CI pipeline. Every test run uses the same shared SendPit inbox, so you can inspect test emails from any browser.

Kubernetes

If your team has moved beyond Docker Compose to Kubernetes, the same principle applies. Store SendPit credentials in a Kubernetes Secret and reference them in your pod spec:

apiVersion: v1
kind: Secret
metadata:
  name: sendpit-smtp
type: Opaque
stringData:
  SMTP_HOST: smtp.sendpit.com
  SMTP_PORT: "587"
  SMTP_USERNAME: mb_a1b2c3d4e5f6g7h8
  SMTP_PASSWORD: your-mailbox-password
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  template:
    spec:
      containers:
        - name: web
          image: myapp:latest
          envFrom:
            - secretRef:
                name: sendpit-smtp

ConfigMaps work for non-sensitive values like SMTP_HOST and SMTP_PORT, while Secrets handle the username and password.

Troubleshooting

DNS resolution failures

If your container cannot resolve smtp.sendpit.com, check that it has a working DNS configuration. By default, Docker uses the host's DNS. You can verify with:

docker compose exec web nslookup smtp.sendpit.com

If resolution fails, try adding a public DNS server to your compose file:

services:
  web:
    dns:
      - 8.8.8.8
      - 1.1.1.1

Firewall and port issues

Some corporate networks or cloud providers block outbound traffic on port 587. Test connectivity from inside your container:

docker compose exec web nc -zv smtp.sendpit.com 587

If the connection times out, check your firewall rules or ask your network administrator to allow outbound TCP on port 587.

Connection timeouts

If connections hang, it is usually a DNS or firewall issue. Increase the SMTP timeout in your application to rule out slow networks:

  • Laravel: Set MAIL_TIMEOUT=30 in your environment.
  • Django: Add EMAIL_TIMEOUT = 30 in settings.py.
  • Node.js: Pass connectionTimeout: 30000 to Nodemailer's createTransport.

Authentication errors

Double-check that your SMTP_USERNAME starts with mb_ and matches a mailbox in your SendPit dashboard. Ensure the password has no trailing whitespace, which can happen when copying from a web interface.

SendPit vs Local Mail Catchers

Tools like MailHog and Mailpit are popular for local email testing, but they come with friction in Docker workflows:

Concern Local Mail Catcher SendPit
Extra container needed Yes No
Shared across team No (each dev runs their own) Yes (shared cloud inbox)
Works in CI/CD Requires service setup Just set environment variables
Persistent between restarts Only with volumes Always persistent
Web UI access localhost only Accessible from anywhere
Docker network config Required (internal networking) Not required (external service)
Setup time Configure per environment One-time mailbox creation

For teams that want a single, consistent email testing experience across every environment, SendPit is the simpler choice. You remove a container from your stack, eliminate per-developer setup, and gain a shared inbox that works everywhere -- from docker compose up on a laptop to a Kubernetes staging cluster.

Next Steps

  • Create a mailbox in the SendPit dashboard if you have not already.
  • Update your docker-compose.yml with the env_file approach shown above.
  • Send a test email from your Dockerized application and verify it appears in the SendPit inbox.
  • Read the SMTP Integration Guide for framework-specific examples beyond Docker.
  • Invite your team so everyone can view captured emails in the shared inbox.

Looking for general SMTP setup? See the full integration guide, or read the developer documentation and explore SMTP Sandbox features.

Questions? Contact [email protected]