Запустить Postfix в Docker и слать почту с VPS через внешний SMTP (Mailgun, корпоративный relay, провайдер) — нормальная схема, когда не хотите поднимать полноценный MTA «в мир» с PTR/DKIM-танцами на голом 25 порту. Ниже: Dockerfile, main.cf, sasl_passwd, сборка и проверка.
Идея схемы
Контейнер с Postfix принимает письма локально (или с приложений на хосте) и ретранслирует их на relayhost провайдера с SASL и TLS. Наружу с VPS часто уходит уже авторизованный SMTP на 587, а не «открытый» relay.
1. Dockerfile
FROM debian:buster-slim
RUN apt-get update && apt-get install -y postfix sasl2-bin \
&& rm -rf /var/lib/apt/lists/*
COPY main.cf /etc/postfix/main.cf
COPY sasl_passwd /etc/postfix/sasl_passwd
RUN postmap /etc/postfix/sasl_passwd \
&& chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
CMD ["postfix", "start-fg"]
- FROM — тонкий Debian как база под пакет postfix;
- COPY main.cf / sasl_passwd — конфиг и учётные данные relay;
- postmap — hash-карта паролей для
smtp_sasl_password_maps; - start-fg — Postfix на переднем плане, удобно для Docker.
На новых хостах имеет смысл взять более свежий Debian/Ubuntu-slim и актуальные пакеты; buster здесь как рабочий пример из исходной схемы.
2. main.cf
myhostname = yourdomain.com mydestination = yourdomain.com, localhost relayhost = [smtp.yourprovider.com]:587 smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd smtp_sasl_security_options = noanonymous smtp_use_tls = yes # при необходимости: # smtp_tls_security_level = encrypt
- myhostname — FQDN, от которого представляется Postfix;
- relayhost — SMTP провайдера (часто 587 submission);
- smtp_sasl_* — логин/пароль на relay;
- smtp_use_tls — шифрование до провайдера.
Подставьте реальный hostname, домен и host:port из панели SMTP-провайдера. Квадратные скобки вокруг хоста в relayhost отключают MX-lookup — обычно так и нужно для submission.
3. sasl_passwd
Файл рядом с Dockerfile (потом копируется в образ). Права на хосте держите жёсткими, в git не коммитьте.
[smtp.yourprovider.com]:587 username:password
После правок внутри контейнера/образа нужен postmap (в Dockerfile уже есть). Для runtime-секретов лучше volume или Docker secrets, а не пароль в слое образа навсегда.
4. Сборка и запуск
docker build -t postfix-smtp . docker run -d -p 25:25 --name smtp-server postfix-smtp
Порт 25 с хоста удобен, если приложения шлют на localhost:25. Если Postfix только для локальных контейнеров, можно не публиковать 25 наружу, а подключать через docker network и имя сервиса.
Логи:
docker logs -f smtp-server
5. Тестовая отправка
С хоста (нужен клиент mail/sendmail, либо отправка из другого контейнера в сеть):
echo "Test message" | mail -s "Test Subject" user@example.com
В приложении (WordPress, Laravel и т.д.) укажите SMTP host = IP/hostname контейнера или 127.0.0.1, порт 25 — либо сразу SMTP провайдера, минуя локальный Postfix, если relay из приложения проще.
Практические замечания
- TLS — для submission почти всегда обязателен; смотрите логи при reject;
- секреты — не кладите боевой sasl_passwd в публичный Dockerfile-контекст без .dockerignore;
- сеть — не открывайте 25 в интернет «на всех», если это только исходящий relay с localhost;
- SPF/DKIM/DMARC — настраиваются на стороне домена и провайдера, не «магией» контейнера;
- образ — для прода обновите base image и закрепите теги, buster-slim уже устаревает.
Кратко
Собираете образ с Postfix, прописываете relayhost и sasl_passwd, публикуете порт только тем, кому нужно слать почту, проверяете docker logs и тестовое письмо. Для продакшена вынесите секреты из слоя образа и согласуйте DNS-записи домена с SMTP-провайдером.


