Настройка sendmail внутри контейнера докеров
У меня есть контейнер docker, на котором запущены php и apache. Хост находится в экземпляре AWS, в котором запущен экземпляр докера. Я не могу отправить электронное письмо с терминала докера. Есть ли способ отправить сообщение электронной почты из экземпляра docker с помощью sendmail, который использует конфигурацию хоста docker?
Следующая команда отправляет электронную почту с хоста, но не отправляет электронное письмо из экземпляра docker. Ошибка также не указана.
echo "Subject: Testing Email" | cat - text | /usr/lib/sendmail -F [email protected] -t [email protected]
Ответы
Ответ 1
Что я делаю, так это настроить хост MTA для прослушивания на docker0
и установить ssmtp в контейнере, чтобы переманить sendmail в контейнере с помощью MTA хоста. Причиной запуска MTA на хосте является то, что системные (критические) ошибки могут быть отправлены в почтовый ящик администратора. Причиной не запускать MTA в контейнере является то, что это дублированный процесс, поскольку хост-система уже запускает MTA.
На хосте я использовал postfix. Все, что нам нужно сделать, это настроить постфикс для прослушивания на docker0
и принять исходящие письма из контейнеров Docker. Отредактируйте файл /etc/postfix/main.cf
и добавьте IP-адрес docker0
в inet_interfaces
, чтобы он принимал подключения из контейнеров Docker. Кроме того, добавьте сетевые адреса контейнеров Docker в mynetworks
, чтобы контейнеры Docker были законными для отправки писем через постфиксный сервер на хосте. (ссылка и более подробная информация)
Чтобы использовать sendmail в контейнерах, установите ssmtp и установите FromLineOverride
, чтобы разрешить, и mailhub
на IP-адрес хоста в /etc/ssmtp/ssmtp.conf
. Вы можете установить mailhub
как символ, например smtp-server
, а затем запустить контейнер с опцией --add-host
, как показано в этом Dockerfile (запустите его с --add-host smtp-server:your-docker0-address
). Это позволит настроить полезный sendmail в контейнерах, которые фактически будут использовать MTA хоста для отправки писем.
Ответ 2
В вашем Dockerfile нигде не установлен sendmail (или любой другой почтовый агент). Хост, однако, по-видимому, имеет sendmail в наличии. "Лучшее" или наиболее похожее на Docker решение состоит в том, чтобы раскрутить другой контейнер, на котором выполняется MTA (например, postfix или exim), и сконфигурировать ваше приложение для его использования.
Ответ 3
построение на предыдущих ответах,
создать config/sendmail_config.sh с помощью:
#!/bin/sh
# set host in hosts
line=$(head -n 1 /etc/hosts)
line2=$(echo $line | awk '{print $2}')
echo "$line $line2.localdomain" >> /etc/hosts
yum install -y sendmail sendmail-cf m4 \
&& hostname >> /etc/mail/relay-domains \
&& m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
#remove localhost limit
sed -i -e "s/Port=smtp,Addr=127.0.0.1, Name=MTA/Port=smtp, Name=MTA/g" \
/etc/mail/sendmail.mc
sendmail -bd
изменить yum для apt-get на контейнерах на основе debian
затем в файле Dockerfile добавьте:
RUN sed -i -e "s#;sendmail_path =#sendmail_path = /usr/sbin/sendmail -t -i#g" \
/your_path_to/php.ini
COPY ./config/sendmail_config.sh .
Я хочу, чтобы sendmail с моим php util, чтобы я мог вставлять его в любом месте, не имея необходимости ссылаться на другой контейнер MTA или хост для выполнения задачи.
Я запустил sh sendmail_config.sh, а затем запустил мой php util.
Ответ 4
Предполагая, что на хосте установлен и настроен почтовый сервер!
Изображения на докере на альпийском языке должны иметь исполняемый файл sendmail
.
Простым решением является запуск контейнера в сети хоста:
docker run --rm --net="host" php:fpm-alpine sh -c 'echo "Subject: test" | sendmail -v [email protected]'
Чтобы запустить контейнер с сетевым мостом по умолчанию,
настроить почтовый сервер для прослушивания интерфейса докерера 172.17.0.1,
и разрешить передачу сообщений электронной почты из док-станции 172.17.0.0/16.
Параметры exim, затронутые в:/etc/exim4/update-exim4.conf.conf
dc_local_interfaces='127.0.0.1 ; ::1 ; 172.17.0.1'
dc_relay_nets='172.17.0.0/16'
Перезапустите почтовый сервер и запустите контейнерный файл:)
docker run --rm --hostname="your-domain.com" php:fpm-alpine sh -c 'echo "Subject: test" | sendmail -v [email protected] -S 172.17.0.1'
Ответ 5
Добавление полного имени домена к имени хоста Docker в /etc/hosts делает трюк для меня:
{YourDockerIP} {YouDockerHostName}.localdomain {YouDockerHostName}
Мне это выглядит так:
172.17.0.25 77f5a7ae8606.localdomain 77f5a7ae8606
Вы также можете использовать этот bash script для автоматического обновления этой строки:
#!/bin/bash
line=$(head -n 1 /etc/hosts | awk '{printf "%s %s.localdomain %s", $1, $2, $2}')
sed -e "1 s/^.*$/${line}/g" /etc/hosts > hosts
# with sed -i, it actually performs a rename of /etc/hosts, but docker does not
# allow that, so we have to use a temp file and copy it to overwrite /etc/hosts
cp hosts /etc/hosts
rm hosts
Ссылка: http://hjk41.azurewebsites.net/2015/09/25/using-sendmail-inside-docker/
Ответ 6
Я понял путь сам, хотя и не самый изящный вариант. Я настроил sendmail внутри моего докера, чтобы передать запрос через host ip. Добавьте в файл следующую строку:/etc/mail/access
Connect:<host_ip_here> RELAY
Кроме того, в хосте, а также в докере, запишите следующую строку в файле "/etc/mail/sendmail.mc", предварительно добавив "dnl #" и суффикс с "dnl".
DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')
Я передал host ip как переменную среды в контейнер докера, так что он настраивается. Теперь докер-sendmail будет передавать запрос sendmail smtp через хост-машину.
Ответ 7
EDIT: см. ответ xuhdev для получения дополнительной информации и настройки почтового отправителя. Мой ответ можно использовать для настройки sendmail вместо postfix на хосте.
EDIT # 2: добавьте правило брандмауэра, чтобы разрешить трафик smtp с docker
Я сделал подобную настройку в качестве татун-миттала следующим образом:
- В приложении docker я установил его для использования SMTP-сервера с интерфейсом ip docker0 (172.17.42.1)
-
в докере-хосте, изменен /etc/mail/sendmail.mc, чтобы включить прослушивание интерфейса docker0 (в отличие от всех интерфейсов в ответе на таун - полужирная добавлена строка)
DAEMON_OPTIONS (`Family = inet, Name = MTA-v4, Port = smtp, Addr = 127.0.0.1 ') dnl
DAEMON_OPTIONS (`Family = inet, Name = MTA-v4, Port = smtp, Addr = 172.17.42.1 ') dnl
-
Разрешить доступ из контейнеров докеров к интерфейсу докеров в брандмауэре
iptables -I INPUT -s 172.17.0.0/24 -d 172.17.42.1 -dport 25 -j ACCEPT
-
в/etc/mail/access, который я добавил в конце, чтобы разрешить всем экземплярам докеры отправлять электронные письма и makemap hash/etc/mail/access </etc/mail/access для компиляции базы данных
///ИЗМЕНИТЬ - ИСПОЛЬЗУЙТЕ НИЖЕ, КАК DOCKER ПОСЕТИТ 172.17.1.X после многих перестроек
///OLD - Connect: 172.17.0 RELAY
Подключение: 172.17 RELAY
-
Наконец перезапустите sendmail - перезапустите службу sendmail
Ответ 8
Я тоже боролся с этой проблемой. Из моего кода python, запущенного внутри контейнера докеров, мне нужно было временно отправить электронные письма с помощью постфикса (smtp-сервера), запущенного на главной машине. После того, как вы пробовали целую кучу вещей, то, что оказалось простым решением, было командой docker run с --net = "host". Внимание. Это не может быть хорошим решением во всех случаях, так как такой контейнер будет совместно использовать сетевой стек с хостом докера и с точки зрения контейнера, localhost (или 127.0.0.1) будет ссылаться на хост докера.
Вот что я сделал на узле ubuntu:
docker run -it --net = "host" ubuntu/bin/bash
Это дало мне контейнерную оболочку.
Затем я установил python в этот контейнер:
apt-get update && & apt-get -y install supervisor python-pip
Затем я запустил интерпретатор python и произвел следующие строки кода:
import smtplib
from email.mime.text import MIMEText
fromaddr = 'testemail.yourdomain.com'
toaddr = 'youremail.yourdomain.com'
msg = MIMEText('Sample email from python/docker container')
msg['from'] = fromaddr
msg['subject'] = 'Subject of python email'
msg['to'] = toaddr
server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddr, msg.as_string())
server.quit
Я также нашел [это] [1] полезное чтение.
Ответ 9
Вы должны указать inet_interfaces на мост докеров (docker0) в конфигурации post fix, расположенной по адресу set/etc/postfix/main.cf
inet_interfaces =
Больше внутренней рабочей детали в отправка электронной почты из докера через постфикс, установленный на хосте
Примечание: используйте команду ifconfig, чтобы получить адрес моста докерера
Ответ 10
Для меня просто добавление флага --network = host в мою команду запуска docker сработало. Он должен использовать хост для отправки электронной почты.
Ответ 11
В соответствии с в руководстве Sendmail мы можем использовать команду sendmail -bd
для запуска службы. Но он существует с нулевым статусом. Так что...
# In your Dockerfile
RUN yum install -y sendmail
# Run mail listener
RUN sendmail -bd
CMD sleep infinity
# or run your command
Также вы можете использовать supervisord.
Я использую эту конфигурацию:
[program:sendmail]
command=/usr/sbin/sendmail -bd
autostart=true
autorestart=false
numprocs=1
startretries=0
И протестируйте его:
$ echo test123 | sendmail [email protected]
Не забудьте проверить папку "Спам".