Email: Inbound (MTA-in)¶
Incoming email flows through the MTA-in Postfix container, which delivers messages to the Django backend via a custom milter.
Flow¶
External SMTP server
│
▼ (port 25)
MTA-in (Postfix)
│
▼ (milter)
Django MDA (backend:8000)
│
▼
Messages inbox (PostgreSQL)
Requirements¶
- MX record pointing to
mx.<domain> - Port 25 open inbound (firewall + VPS provider)
- MTA-in container running as
root(milter socket permissions)
Milter Permission Fix¶
Without user: root, the milter socket at /var/spool/postfix/milter/delivery.sock has incorrect permissions, causing:
warning: connect to Milter service unix:/var/spool/postfix/milter/delivery.sock: Permission denied
451 4.7.1 Service unavailable - try again later
The fix in compose.yml:
Verification¶
Send a test email:
python3 -c "
import smtplib, email.mime.text
msg = email.mime.text.MIMEText('Test inbound')
msg['From'] = 'test@example.com'
msg['To'] = '<user>@<domain>'
msg['Subject'] = 'Test inbound delivery'
s = smtplib.SMTP('localhost', 25, timeout=10)
s.sendmail('test@example.com', ['<user>@<domain>'], msg.as_string())
s.quit()
print('Sent')
"
Then check the backend logs:
Firewall¶
- Hetzner Cloud: Add incoming TCP/25 rule explicitly (not open by default)
- Other providers: Check if port 25 is blocked by default