在docker容器中配置sendmail

时间:2014-10-06 11:12:26

标签: ubuntu amazon-web-services sendmail docker

我有一个运行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

11 个答案:

答案 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的另一个容器(如postfixexim),并配置您的应用程序以使用它。

答案 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的设置如下:

  • 在docker app中我已将其设置为使用带有docker0接口的ipt的smtp服务器(172.17.42.1)
  • 在docker主机中
  • ,修改了/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

  • 在/ etc / mail / access中的
  • 我在最后添加了允许所有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

不要忘记查看垃圾邮件文件夹。