При разработке приложений часто возникает задача проверки отправки emails. Для этого можно использовать MailHog совместно с Docker, что позволит с легкостью тестировать это локально. Достаточно будет один раз настроить эту конфигурацию и забыть о любой настройки SMTP отправки через ваше приложение.
Давайте рассмотрим это подробнее.
Основые определения
Для начала познакомимся с основными определениями, чтобы было легче разобраться.
SMTP (Simple Mail Transfer Protocol)
SMTP (Simple Mail Transfer Protocol) — является стандартным протоколом для отправки электронных писем по Интернету и обычно работает на порту 25, 587 или 465 (для зашифрованного соединения).
SMTP сервер
SMTP сервер — это сервер который работает по протоколу SMTP и используется для отправки, приема и ретрансляции электронной почты между отправителями и получателями.
SMTP клиент
SMTP клиент — это приложение которое отправляет электронную почту на SMTP сервер. Оно действует как инициатор соединения с SMTP сервером для передачи сообщений.
Sendmail приложение
Sendmail — это одино из самых старых и известных приложений для маршрутизации и доставки электронной почты на Unix-подобных операционных системах.
Оно функционирует как почтовый транспортный агент (MTA — Mail Transport Agent), который может обрабатывать отправку, прием, фильтрацию на спам, ретрансляцию электронной почты. Может использоваться как SMTP сервер так и SMTP клиент.
С годами sendmail стал менее популярным из-за сложности настройки и управления, но он по-прежнему используется во многих средах, особенно в устаревших системах.
Msmtp приложение
Msmtp — это легковесный SMTP клиент, который отправляет электронную почту от пользователя к SMTP серверу. Простой, удобный в использовании, с достаточно полной совместимостью с sendmail.
Далее msmtp мы будем использовать для отправки почты вместо sendmail.
MailHog
MailHog — это инструмент для тестирования отправки электронной почты в процессе разработки приложений. Он эмулирует SMTP сервер, перехватывает сообщения и позволяет просматривать исходящие (от приложений) электронные сообщения.
MailHog предоставляет так-же удобный UI интерфейс, где можно ознакомиться с полученными emails:
MailHog довольно удобен при локальной разработке из-под Docker из-за простоты установки и легковестности.
Существует так-же альтернатива MailHog — MailPit, который имеет улучшенный интерфейс, более отзывчивый и постоянно обновляется.
Настройка отправки почты в Docker
Теперь приступим к настройке msmtp клиента, Dockerfile и docker-compose.yml.
Создадим msmtp конфиг
Создадим msmtp конфиг и положим его в директорию проекта по адресу /dev/docker/php-fpm/msmtprc
defaults
port 1025
tls off
logfile /proc/self/fd/2
account default
auth off
host mailhog
from default-mail@docker-lamp.example
add_missing_date_header on
#user on
#password on
Отправлять почту msmtp будет на 1025 порт, на котором будет висеть MailHog.
Больше настроек msmtp доступно в официальной документации.
Создадим Docker файл приложения
На этой стадии необходимо настроить Dockerfile с нашим приложением и установить msmtp пакет.
Мы используем в примере PHP image, но вы можете использовать любой другой image под ваш язык: nodejs, go, python, т.к. потому что инструкции по установке почтового клиента будут одинаковые.
Создадим Dockerfile по адресу /dev/docker/php-fpm/Dockerfile
FROM php:8.2-fpm
# .. другие Docker инструкции
# Устанаваливаем пакеты
RUN set -xe; \
apt-get update; \
apt-get -y install \
msmtp \
msmtp-mta
WORKDIR /var/www/html/
# Копируем msmtprc конфиг
COPY msmtprc /etc/msmtprc
msmtp-mta
— используется как алиаса sendmail
для msmtp. Это позволяет не возиться с настройками php.ini , т.к. в php.ini sendmail_path
по дефолту будет /usr/sbin/sendmail -t -i
.
Но если очень хочется, можно прописать вручную в php.ini путь до msmtp:
[mail function]
sendmail_path = "/usr/bin/msmtp -t -i"
Создадим docker-compose файл
Как правило ни одна локальная разработка не происходит без docker-compose.yml файла, т.к. контейнеры по одному поднимать дольно сложно.
Положим файл в корень проекта ./docker-compose.yml
version: "3"
services:
php:
build:
context: ./dev/docker/php-fpm
container_name: "wp-yoda_php"
depends_on:
- mailhog
volumes:
- ./:/var/www/html
networks:
- lamp-network
mailhog:
image: mailhog/mailhog
container_name: "wp-yoda_mailhog"
ports:
- "1025"
- "8025:8025"
networks:
- lamp-network
networks:
lamp-network:
driver: bridge
В docker-compose файле мы добавляем 2 сервиса:
- MailHog service, который доступен как SMTP сервер во внутренней сети на 1025 порту, и UI который будет доступен на 8025.
- PHP сервис связанный с MailHog одной сетью. Так-же примонтирован volume — текущая директория.
Запустим наш проект выполнив в корне команду
docker-compose up -d
Не забудьте добавить в hosts dns запись 127.0.0.1 localhost
Проверим что MailHog доступен по http://localhost:8025/
Подключимся в PHP контейнер и протестируем отправку сообщения через shell:
docker-compose exec php bash
# send mail
echo -e "Subject: Test Email\n\nThis is the body of the email." | sendmail -i user@example.com
Если все ок, вы увидитите сообщение об успехе в console и зайдя в MailHog, у вас так-же появится новое сообщение.
Проверим отправку через PHP
Создадим php скрипт test-mail.php
с отправкой письма в корне проекта:
<?php
// Define recipient, subject, message, and headers
$to = 'recipient@example.com';
$subject = 'Test Mail';
$message = 'Hello, this is a test mail from PHP script.';
$headers = 'From: sender@example.com' . "\r\n" .
'Reply-To: sender@example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
// Send the email
if(mail($to, $subject, $message, $headers)) {
echo "Mail sent successfully!";
} else {
echo "Failed to send mail.";
}
Подключимся к контейнеру и выполним скрипт
docker-compose exec php bash
php test-mail.php
Если все прошло успешно перейдя по адресу http://localhost:8025/
в MailHog, мы увидим новое сообщение:
Полный код
Аналогичный код можно посмотреть в Docker-LAMP, но он будет сложнее чем пример из статьи, т.к. там используется полноценный LAMP с шаблонизатором в конфигах.
Заключение
При разработке приложений часто возникает необходимость проверить функционал отправки электронных писем. Использование MailHog в сочетании с Docker значительно упрощает эту задачу, позволяя проводить тестирование локально. Для удобства настройки отправки писем можно воспользоваться msmtp, который легко утанавливается и настраивается в Docker.