问题描述
我有一个运行php和apache的docker container。主机位于运行docker实例的AWS实例中。我无法从docker终端发送电子邮件。有没有办法使用sendmail使用docker’s host’s配置从docker实例发送电子邮件?
以下命令从主机发送电子邮件,但不从docker实例发送电子邮件。也没有错误。
echo "Subject: Testing Email" | cat - text | /usr/lib/sendmail -F abc.pqr@domain.com -t abc.pqr@domain.com
最佳解决思路
我所做的是配置主机MTA以侦听docker0
并在容器中安装ssmtp以使用主机MTA桥接容器中的sendmail。在主机上运行MTA的原因是系统(严重)错误可以发送到管理员的邮箱。不在容器中运行MTA的原因是它是一个重复的进程,因为主机系统已经运行了MTA。
在主机上,我使用了postfix。我们需要做的就是配置postfix以侦听docker0
并接受来自Docker容器的传出邮件。编辑文件/etc/postfix/main.cf
并将docker0
IP地址添加到inet_interfaces
,以便它接受来自Docker容器的连接。此外,将Docker容器的网络地址添加到mynetworks
,以便Docker容器合法通过主机上的后缀服务器发送邮件。 (reference and more details)
要在容器中使用sendmail,请安装ssmtp并将FromLineOverride
设置为允许,并将mailhub
设置为/etc/ssmtp/ssmtp.conf
中主机的IP地址。您可以将mailhub
设置为smtp-server
等符号,然后使用--add-host
选项运行容器,如此Dockerfile(使用--add-host smtp-server:your-docker0-address
运行)中所示。这将在容器中配置可用的sendmail,它实际上将使用主机MTA发送邮件。
次佳解决思路
您的Dockerfile中没有任何地方安装了sendmail(或任何其他邮件代理)。但是,主机显然确实有sendmail可用。 “best”或大多数Docker-like解决方案是启动另一个运行MTA的容器(如postfix或exim),并配置您的应用程序使用它。
第三种解决思路
在之前的答案基础上,创建配置/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
在基于debian的容器上更改yum for apt-get
然后在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 .
我想用我的php util发送sendmail所以我可以把它粘在任何地方而不必链接到另一个MTA容器或主机来完成任务。我运行sh sendmail_config.sh,然后运行我的php util。
第四种思路
假设在主机上安装并配置了邮件服务器!
基于Alpine的docker镜像应具有sendmail
可执行文件。
简单的解决方案是在主机网络上运行容器:
docker run --rm --net="host" php:fpm-alpine sh -c 'echo "Subject: test" | sendmail -v your@mail.com'
要使用默认网桥运行容器,请将邮件服务器配置为在docker接口172.17.0.1上侦听,并允许从docker子网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 your@mail.com -S 172.17.0.1'
第五种思路
将完全限定的域名添加到/etc /hosts中的Docker主机名对我来说是个窍门:
{YourDockerIP} {YouDockerHostName}.localdomain {YouDockerHostName}
对我来说,它看起来像这样:
172.17.0.25 77f5a7ae8606.localdomain 77f5a7ae8606
您还可以使用此bash脚本自动更新此行:
#!/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/
第六种思路
我自己想办法,虽然不是最优雅的解决方案。我在docker中配置了sendmail,以便通过主机的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')
我将主机ip作为环境变量传递给docker容器,因此它是可配置的。现在,docker的sendmail将通过主机中继it’s sendmail’s smtp请求。