在Docker容器中使用本地SMTP服务器发送Python邮件

8
我希望能够使用Python的smtp库发送电子邮件。我知道这个库使用本地SMTP服务,端口号为25。我有以下代码,这些代码在我的本地环境中运行没有问题,并且可以成功发送邮件。但是当我将它们移动到Docker容器中时,电子邮件无法发送,也不会出现任何错误。
我的代码:
from_mail = 'noreply@testmail.com'
to_mail = 'to@testmail.com'

s = smtplib.SMTP('localhost')
subject = 'Test Subject'
content = 'content test'

message = f"""\
      Subject: {subject}
      To: {to_mail}
      From: {from_mail}
      {content}"""
result = s.sendmail(from_mail, to_mail, message)
s.quit()

在运行这些代码之后,我得到了一个空的字典({})作为result的值。在sendmail方法的描述中有这样一句话:

...该消息被接受并发送到了其中三个地址,其中一个地址因为错误代码550而被拒绝。如果所有地址都被接受,则该方法将返回一个空字典。

这是否涉及网络配置?我需要配置任何网络设置吗?

你的容器基于哪个镜像?如何运行容器?这可能有助于解决你的问题。 - Pierre B.
我的容器基于 python:3.6-slim-buster. - kamilyrb
请问您能分享一下 Dockerfile 吗? - rok
你的操作系统是什么? - rok
3个回答

6
您分享的代码是SMTP客户端应用程序。假设使用SMTP客户端标准库smtplib并且SMTP服务器正在本地主机上运行,则在以下情况下,该代码将在Docker容器中工作:
  • 您使用--net=host启动容器,则不需要进行更改。调用smtplib.SMTP('localhost')将连接到在主机上运行的SMTP服务器。
  • 如果您使用Windows或MacOS,则无需使用localhost连接,而需要连接到host.docker.internal。如果您使用Linux,则可能需要使用另一种技巧。基本上,该代码仍然连接到在主机上运行的SMTP服务器。
  • 您将SMTP服务器和Python stmp客户端应用程序(您分享的代码)打包在同一个Docker镜像中。这是不好的实践,应该避免。但是,您可以按照文档进行操作。

请分享以下内容以更好地理解问题:

更具体地说:

  • 您使用的操作系统。 Docker for desktop在Mac和Windows上的网络功能方面表现不同,特别是

  • 您使用的Dockerfile。否则,无法运行镜像并复制您遇到的问题,并理解您所说的sendmail service is running in my container.

  • 完全工作的Python代码(包括导入等...)。否则,不清楚您使用的smtplib是什么。

  • 文档链接。如果使用标准库smtplib,则其文档中没有这样的描述:

sendmail方法描述如下:

...该消息已被三个地址接受以进行投递,而一个地址由于错误代码550而被拒绝。如果所有地址都被接受,则该方法将返回一个空字典。


1
"--net=host" 对我没有用(可能是因为我使用的是 "0.0.0.0" 而不是 "localhost"),但 "host.docker.internal" 完美地解决了问题!谢谢。 - GG.

0

默认情况下,Docker容器在单独的网络堆栈中运行,因此localhost在Docker容器内部的含义与代码直接在计算机上运行时不同。

根据您的SMTP服务器设置方式,它可能还配置为拒绝发送除来自计算机之外的任何电子邮件,而Docker容器可能被视为不应通过它发送电子邮件的外部人员。

我想最简单的解决方案是使用--net=host运行Docker容器。这样,Docker容器的网络堆栈将与计算机的堆栈相同,一切都应该像代码直接在Docker之外运行一样工作。


我在Docker容器上连接SMTP服务没有任何问题。但是,当我更改连接信息,例如端口号或主机名时,就会出现连接错误。 - kamilyrb

0
如果在主机上运行正常,请尝试使用主机IP而不是localhost
s = smtplib.SMTP(HOST_IP)

或者像Arthur建议的那样,您可以使用--net=host在主机网络中运行容器,然后继续使用localhost


感谢您的回答,sendmail服务正在我的容器中运行。我想从容器中发送邮件而不使用主机。 - kamilyrb
你确定吗?你需要在问题中添加更多细节。例如,你的容器的Dockerfile,以及如何在容器中安装SMTP服务等。 - Shashank V

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接