我有一个运行php和apache的docker container。主机位于运行docker实例的AWS实例中。我无法从docker终端发送电子邮件。有没有办法使用sendmail使用docker的主机配置从docker实例发送电子邮件?
以下命令从主机发送电子邮件但不从docker实例发送电子邮件。也没有错误。
echo "Subject: Testing Email" | cat - text | /usr/lib/sendmail -F abc.pqr@domain.com -t abc.pqr@domain.com
答案 0 :(得分:20)
我所做的是将主机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发送邮件。
答案 1 :(得分:5)
您的Dockerfile中没有安装sendmail(或任何其他邮件代理)。但是,主机显然确实有sendmail可用。 “最佳”或类似Docker的解决方案是启动运行MTA的另一个容器(如postfix或exim),并配置您的应用程序以使用它。
答案 2 :(得分:5)
以前的答案为基础,
使用以下命令创建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
在基于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 .
我希望sendmail使用我的php util,所以我可以将它粘贴到任何地方,而不必链接到另一个MTA容器或主机来完成任务。
我运行sh sendmail_config.sh,然后运行我的php util。
答案 3 :(得分:4)
假设在主机上安装并配置了邮件服务器!
基于Alpine 的泊坞窗图片应该有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'
重新启动邮件服务器并运行容器verbose:)
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'
答案 4 :(得分:3)
在/ etc / hosts中为Docker主机名添加一个完全限定的域名对我来说很有用:
String input="monkey";
char[] inparr=input.toCharArray();
int len=input.length;
for(int i=0;i<len/2;i++) //iterate till half length that will work
{
if(i%2==0)
{
//character is even
//swap i and len-i index
int temp=inparr[i];
inparr[i]=inparr[len-i];
inparr[i]=temp;
}
else
{
}
}
对我看起来像这样:
{YourDockerIP} {YouDockerHostName}.localdomain {YouDockerHostName}
您也可以使用此bash脚本自动更新此行:
172.17.0.25 77f5a7ae8606.localdomain 77f5a7ae8606
参考:http://hjk41.azurewebsites.net/2015/09/25/using-sendmail-inside-docker/
答案 5 :(得分:2)
我自己想办法,虽然不是最优雅的解决方案。我在docker中配置了sendmail,以便通过主机的ip中继请求。将以下行添加到文件&#34; / etc / mail / access
Connect:<host_ip_here> RELAY
此外,在主机和泊坞窗中,注释掉文件中的以下行&#34; /etc/mail/sendmail.mc"用前缀加上&#34; dnl#&#34;和&#34; dnl&#34;后缀。
DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')
我将主机ip作为环境变量传递给docker容器,因此它是可配置的。现在,docker的sendmail将通过主机转发它的sendmail的smtp请求。
答案 6 :(得分:1)
编辑:请参阅xuhdev答案了解更多信息以及如何设置邮件转发器。我的回答可以用来在主机上设置sendmail而不是postfix。
编辑#2:添加防火墙规则以允许来自docker的smtp流量
我做了类似tarun mittal的设置如下:
,修改了/etc/mail/sendmail.mc以包含在docker0接口上的监听(与tarun的所有接口相反 - 粗体添加了行)
DAEMON_OPTIONS(`Family = inet,Name = MTA-v4,Port = smtp,Addr = 127.0.0.1&#39;)dnl
DAEMON_OPTIONS(`Family = inet,Name = MTA-v4,Port = smtp,Addr = 172.17.42.1&#39;)dnl
允许从docker容器访问防火墙中的docker接口 iptables -I INPUT -s 172.17.0.0/24 -d 172.17.42.1 -dport 25 -j ACCEPT
我在最后添加了允许所有docker实例发送电子邮件和 makemap hash / etc / mail / access&lt; / etc / mail / access 来编译数据库
///已编辑 - 使用以下作为DOCKER将在经过多次重建后转至172.17.1.X
/// OLD - Connect:172.17.0 RELAY
连接:172.17 RELAY
最后重启sendmail - service sendmail restart
答案 7 :(得分:1)
我也在努力解决这个问题。从我在docker容器中运行的python代码,我需要使用在主机上运行的postfix(smtp服务器)临时发送电子邮件。在尝试了很多东西后,原来是一个简单的解决方案是docker run命令--net =“host”。警告:在所有情况下这可能不是一个好的解决方案,因为这样的容器将与docker主机共享网络堆栈,从容器的角度来看,localhost(或127.0.0.1)将引用docker主机。 这是我在ubuntu主机上做的事情: docker run -it --net =“host”ubuntu / bin / bash 这给了我容器壳。 然后我在这个容器中安装了python: apt-get update&amp;&amp; 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
我还发现[this] [1]是一本有用的读物。
答案 8 :(得分:0)
你必须将inet_interfaces指向位于set /etc/postfix/main.cf的post fix config中的docker bridge(docker0)
inet_interfaces =
sending email from docker via postfix installed on host
的更多内部工作细节注意:使用ifconfig命令获取docker bridge address
答案 9 :(得分:0)
对我来说,仅在docker run命令上添加--network = host标志即可。它应该使用主机发送电子邮件。
答案 10 :(得分:-1)
根据the Sendmail manual,我们可以使用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 your@mail.com
不要忘记查看垃圾邮件文件夹。