papercut-smtp
Papercut SMTP Service -- https://github.com/ChangemakerStudios/Papercut-SMTP
50K+

The Simple Desktop Email Helper
If you ever send emails from an application or website during development, you're familiar with the fear of an email being released into the wild. Are you positive none of the 'test' emails are addressed to colleagues or worse, customers? Of course, you can set up and maintain a test email server for development -- but that's a chore. Plus, the delay when waiting to view new test emails can radically slow your development cycle.
Papercut SMTP is a 2-in-1 quick email viewer AND built-in SMTP server (designed to receive messages only). Papercut SMTP doesn't enforce any restrictions on how you prepare your email, but it allows you to view the whole email: body, HTML, headers, and attachments. This Docker image runs the Papercut SMTP Service with an embedded web UI for viewing emails.
# Pull the latest image
docker pull changemakerstudiosus/papercut-smtp:latest
# Run with default configuration
docker run -d \
--name papercut \
-p 37408:8080 \
-p 2525:2525 \
changemakerstudiosus/papercut-smtp:latest
Access the web UI at: http://localhost:37408
Send test emails to: localhost:2525
The Docker image uses non-privileged ports by default, allowing the container to run securely without root privileges:
| Service | Container Port | Suggested Host Port | Traditional Port |
|---|---|---|---|
| HTTP Web UI | 8080 | 37408 | 80 |
| SMTP Server | 2525 | 2525 | 25 |
Ports below 1024 (like 25 and 80) require special permissions in Linux. By using ports 2525 and 8080, Papercut runs securely without needing:
--sysctl flagsIf you want the service available on traditional ports on your host, you can map them:
# Map to traditional ports on the host
docker run -d \
--name papercut \
-p 80:8080 \
-p 25:2525 \
changemakerstudiosus/papercut-smtp:latest
Access: http://localhost (port 80) | SMTP: localhost:25
Override default configuration using environment variables:
docker run -d \
--name papercut \
-e SmtpServer__IP=0.0.0.0 \
-e SmtpServer__Port=2525 \
-e Urls=http://0.0.0.0:8080 \
-p 8080:8080 \
-p 2525:2525 \
changemakerstudiosus/papercut-smtp:latest
Available Environment Variables:
SmtpServer__IP - SMTP listening address (default: "Any" = 0.0.0.0)SmtpServer__Port - SMTP listening port (default: 2525, use 587 for STARTTLS)SmtpServer__MessagePath - Path where emails are stored (default: /app/Incoming)SmtpServer__LoggingPath - Path for log files (default: /app/logs)SmtpServer__AllowedIps - IP allowlist for SMTP connections (default: "*" = all IPs allowed)Urls - HTTP server URLs (default: http://0.0.0.0:8080)Security - SMTP IP Allowlist Configuration:
SmtpServer__AllowedIps - Comma-separated list of allowed IP addresses or CIDR ranges for SMTP connections
* - Allow all IPs (default, backward compatible)192.168.1.0/24 - Allow single CIDR range192.168.1.0/24,10.0.0.0/8 - Allow multiple CIDR ranges192.168.1.100 - Allow single IP192.168.1.100,192.168.1.101 - Allow multiple specific IPsTLS/STARTTLS Configuration (Optional):
SmtpServer__CertificateFindType - Certificate search method (default: "FindBySubjectName")SmtpServer__CertificateFindValue - Certificate identifier (empty = TLS disabled)SmtpServer__CertificateStoreLocation - Store location: "LocalMachine" or "CurrentUser" (default: "LocalMachine")SmtpServer__CertificateStoreName - Store name: "My", "Root", etc. (default: "My")Mount your own appsettings.Production.json:
docker run -d \
--name papercut \
-v /path/to/your/appsettings.Production.json:/app/appsettings.Production.json:ro \
-p 8080:8080 \
-p 2525:2525 \
changemakerstudiosus/papercut-smtp:latest
Example appsettings.Production.json:
{
"Urls": "http://0.0.0.0:8080",
"SmtpServer": {
"IP": "Any",
"Port": 2525,
"MessagePath": "/app/Incoming",
"LoggingPath": "/app/logs"
}
}
By default, emails are stored inside the container and will be lost when the container is removed. To persist emails, mount a volume:
docker run -d \
--name papercut \
-p 37408:8080 \
-p 2525:2525 \
-v papercut-messages:/app/Incoming \
changemakerstudiosus/papercut-smtp:latest
docker run -d \
--name papercut \
-p 37408:8080 \
-p 2525:2525 \
-v /path/on/host/messages:/app/Incoming \
changemakerstudiosus/papercut-smtp:latest
Create a docker-compose.yml:
version: '3.8'
services:
papercut:
image: changemakerstudiosus/papercut-smtp:latest
container_name: papercut-smtp
ports:
- "37408:8080" # Web UI
- "2525:2525" # SMTP
volumes:
- papercut-messages:/app/Incoming
- papercut-logs:/app/logs
environment:
- SmtpServer__IP=0.0.0.0
- SmtpServer__Port=2525
- Urls=http://0.0.0.0:8080
restart: unless-stopped
volumes:
papercut-messages:
papercut-logs:
Run with:
docker compose up -d
Papercut SMTP supports optional TLS/STARTTLS encryption and SMTP authentication for secure email testing.
Enable STARTTLS using environment variables:
docker run -d \
--name papercut-tls \
-p 8080:8080 \
-p 587:587 \
-e SmtpServer__Port=587 \
-e SmtpServer__CertificateFindType=FindBySubjectName \
-e SmtpServer__CertificateFindValue=localhost \
changemakerstudiosus/papercut-smtp:latest
TLS/STARTTLS requires an X.509 certificate. The certificate must be installed in the Windows certificate store (LocalMachine or CurrentUser).
Create a self-signed certificate for testing (on Windows host):
# Create certificate
$cert = New-SelfSignedCertificate `
-Subject "CN=localhost" `
-DnsName "localhost" `
-CertStoreLocation "cert:\LocalMachine\My" `
-NotAfter (Get-Date).AddYears(2)
# Get thumbprint for configuration
$cert.Thumbprint
Then use the thumbprint in your Docker configuration:
docker run -d \
--name papercut-tls \
-p 8080:8080 \
-p 587:587 \
-e SmtpServer__Port=587 \
-e SmtpServer__CertificateFindType=FindByThumbprint \
-e SmtpServer__CertificateFindValue=YOUR_THUMBPRINT_HERE \
changemakerstudiosus/papercut-smtp:latest
version: '3.8'
services:
papercut-tls:
image: changemakerstudiosus/papercut-smtp:latest
container_name: papercut-smtp-tls
ports:
- "8080:8080"
- "587:587" # STARTTLS port
volumes:
- papercut-messages:/app/Incoming
- papercut-logs:/app/logs
environment:
# Basic configuration
- SmtpServer__IP=0.0.0.0
- SmtpServer__Port=587
- Urls=http://0.0.0.0:8080
# TLS configuration
- SmtpServer__CertificateFindType=FindByThumbprint
- SmtpServer__CertificateFindValue=YOUR_CERT_THUMBPRINT
- SmtpServer__CertificateStoreLocation=LocalMachine
- SmtpServer__CertificateStoreName=My
restart: unless-stopped
volumes:
papercut-messages:
papercut-logs:
Alternatively, configure TLS in a custom appsettings.Production.json:
{
"Urls": "http://0.0.0.0:8080",
"SmtpServer": {
"IP": "Any",
"Port": 587,
"MessagePath": "/app/Incoming",
"LoggingPath": "/app/logs",
"CertificateFindType": "FindByThumbprint",
"CertificateFindValue": "YOUR_CERT_THUMBPRINT_HERE",
"CertificateStoreLocation": "LocalMachine",
"CertificateStoreName": "My"
}
}
| Port | Mode | Description |
|---|---|---|
| 25 | Plain SMTP | No encryption (default) |
| 587 | STARTTLS | Start plain, upgrade to TLS (recommended) |
| 465 | SMTPS | Immediate TLS encryption |
| 2525 | Plain SMTP | Non-privileged alternative to port 25 |
| FindType | Example | Use Case | Ease of Use |
|---|---|---|---|
FindBySubjectName | localhost | Find by common name | ⭐⭐⭐ Recommended - Easiest |
FindByThumbprint | ABC123DEF456... | Most specific | ⭐⭐ More secure but harder to configure |
FindBySubjectDistinguishedName | CN=localhost, O=Company | Full distinguished name | ⭐ Most specific |
SMTP AUTH is automatically available when using TLS/STARTTLS. By default, Papercut accepts all credentials for development/testing purposes.
Test with authentication:
# Using openssl
openssl s_client -connect localhost:587 -starttls smtp
# Should see in EHLO response:
# 250-STARTTLS
# 250-AUTH PLAIN LOGIN
Send email with MailKit (C#):
using var client = new SmtpClient();
client.Connect("localhost", 587, SecureSocketOptions.StartTls);
client.Authenticate("anyuser", "anypass"); // Accepts any credentials
client.Send(message);
client.Disconnect(true);
# Test STARTTLS connection
openssl s_client -connect localhost:587 -starttls smtp
# Expected output should include:
# - STARTTLS in EHLO response
# - Certificate details
# - "Verify return code: 0 (ok)" or self-signed warning
Certificate Not Found:
Error: No certificate found matching FindByThumbprint='...'
Multiple Certificates Found:
Error: Multiple certificates (3) found matching...
Connection Refused on Port 587:
-p 587:587docker logs papercut-tls | grep TLSRestrict SMTP connections to specific IP addresses or networks using the SmtpServer__AllowedIps environment variable:
Allow specific network:
docker run -d \
--name papercut \
-e SmtpServer__AllowedIps=192.168.1.0/24 \
-p 8080:8080 \
-p 2525:2525 \
changemakerstudiosus/papercut-smtp:latest
Allow multiple networks:
docker run -d \
--name papercut \
-e SmtpServer__AllowedIps=192.168.1.0/24,10.0.0.0/8,172.16.0.0/12 \
-p 8080:8080 \
-p 2525:2525 \
changemakerstudiosus/papercut-smtp:latest
Allow specific IPs only:
docker run -d \
--name papercut \
-e SmtpServer__AllowedIps=192.168.1.100,192.168.1.101 \
-p 8080:8080 \
-p 2525:2525 \
changemakerstudiosus/papercut-smtp:latest
Docker Compose with IP filtering:
services:
papercut:
image: changemakerstudiosus/papercut-smtp:latest
ports:
- "8080:8080"
- "2525:2525"
environment:
- SmtpServer__AllowedIps=192.168.1.0/24,10.0.0.0/8
restart: unless-stopped
Notes:
SmtpServer__AllowedIps=* to allow all IPs (default behavior)To listen on IPv6:
docker run -d \
--name papercut \
-e SmtpServer__IP=::0 \
-e Urls=http://[::]:8080 \
-p 8080:8080 \
-p 2525:2525 \
changemakerstudiosus/papercut-smtp:latest
To use completely custom ports:
docker run -d \
--name papercut \
-e SmtpServer__Port=3025 \
-e Urls=http://0.0.0.0:9080 \
-p 9080:9080 \
-p 3025:3025 \
changemakerstudiosus/papercut-smtp:latest
docker run -d \
--name papercut \
-p 37408:8080 \
-p 2525:2525 \
-v papercut-messages:/app/Incoming \
-v papercut-logs:/app/logs \
-v $(pwd)/appsettings.Production.json:/app/appsettings.Production.json:ro \
changemakerstudiosus/papercut-smtp:latest
Example Kubernetes deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: papercut-smtp
labels:
app: papercut-smtp
spec:
replicas: 1
selector:
matchLabels:
app: papercut-smtp
template:
metadata:
labels:
app: papercut-smtp
spec:
containers:
- name: papercut
image: changemakerstudiosus/papercut-smtp:latest
ports:
- containerPort: 8080
name: http
protocol: TCP
- containerPort: 2525
name: smtp
protocol: TCP
env:
- name: SmtpServer__Port
value: "2525"
- name: Urls
value: "http://0.0.0.0:8080"
volumeMounts:
- name: messages
mountPath: /app/Incoming
- name: logs
mountPath: /app/logs
volumes:
- name: messages
emptyDir: {}
- name: logs
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: papercut-smtp
labels:
app: papercut-smtp
spec:
type: ClusterIP
selector:
app: papercut-smtp
ports:
- name: http
port: 8080
targetPort: 8080
protocol: TCP
- name: smtp
port: 2525
targetPort: 2525
protocol: TCP
Apply with:
kubectl apply -f papercut-deployment.yaml
Access via port-forward for testing:
kubectl port-forward svc/papercut-smtp 37408:8080 2525:2525
Error: Permission denied when binding to ports
Solution: Use the default non-privileged ports (2525, 8080) or map ports at the host level:
# Correct - map at host level
docker run -d -p 25:2525 -p 80:8080 changemakerstudiosus/papercut-smtp:latest
# Avoid - requires special permissions
docker run -d --sysctl net.ipv4.ip_unprivileged_port_start=0 changemakerstudiosus/papercut-smtp:latest
Symptoms: Cannot connect to http://localhost:37408
Checks:
docker psdocker logs papercutdocker port papercutSymptoms: Emails not appearing in Papercut
Checks:
telnet localhost 2525docker port papercutdocker logs papercut | grep SMTPSymptoms: Environment variables or config changes ignored
Checks:
docker logs papercut | grep ASPNETCORE_ENVIRONMENT
docker logs papercut | grep "SMTP Server Configuration Initialized"
__)Symptoms: Container starts then immediately stops
Checks:
docker logs papercutLinux/Mac:
echo -e "Subject: Test Email\n\nThis is a test message." | nc localhost 2525
Windows PowerShell:
$smtp = New-Object Net.Mail.SmtpClient("localhost", 2525)
$smtp.Send("[email protected]", "[email protected]", "Test Subject", "Test body")
telnet localhost 2525
EHLO localhost
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
Subject: Test Email
This is a test message.
.
QUIT
Papercut SMTP is licensed under the Apache License, Version 2.0.
Content type
Image
Digest
sha256:be8e99e8d…
Size
100 MB
Last updated
about 1 month ago
docker pull changemakerstudiosus/papercut-smtp:7.7.3-alpha.7