简体   繁体   English

Python 在带有本地 SMTP 服务器的 docker 容器内发送邮件

[英]Python send mail inside docker container with local SMTP server

I want to send mail with smtp lib on python.我想用 python 上的smtp lib 发送邮件。 I understand that it uses local smtp service on port number 25. I have below codes.我知道它在端口号 25 上使用本地 smtp 服务。我有以下代码。 These codes run on my local without any problem and mail sends successfully.这些代码在我的本地运行没有任何问题,邮件发送成功。 But when I move them to docker container, mail is not sent and it doesn't give any error.但是当我将它们移动到 docker 容器时,邮件不会发送,也不会出现任何错误。

My codes:我的代码:

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()

After running these codes, I get empty dict ({}) as result value.运行这些代码后,我得到空 dict ({}) 作为result值。 In the sendmail method description has this:在 sendmail 方法描述中有这样的:

... the message was accepted for delivery to three of the four addresses, and one was rejected, with the error code 550. If all addresses are accepted, then the method will return an empty dictionary. ...消息被接受以传递到四个地址中的三个,一个被拒绝,错误代码为 550。如果所有地址都被接受,则该方法将返回一个空字典。

Is it about network configuration?和网络配置有关吗? Should I configure any network settings?我应该配置任何网络设置吗?

The code you shared is SMTP client application.您共享的代码是 SMTP 客户端应用程序。 Assuming SMTP client standard library smtplib is used and SMTP server is running on localhost, the code will work in Docker container in the following conditions:假设使用 SMTP 客户端标准库smtplib并且 SMTP 服务器在 localhost 上运行,代码将在 Docker 容器中运行,条件如下:

  • You start the container with --net=host , then no changes is needed.您使用--net=host启动容器,然后不需要更改。 calling smtplib.SMTP('localhost') will connect to SMTP server running on the host.调用smtplib.SMTP('localhost')将连接到主机上运行的 SMTP 服务器。
  • You don't start the container with --net=host .您不要使用--net=host启动容器。 Then you need to connect to host.docker.internal instead of localhost if you use Windows or MacOS.然后,如果您使用 Windows 或 MacOS,则需要连接到host.docker.internal而不是localhost If you use Linux, may need to use another trick .如果你使用 Linux,可能需要使用另一个技巧 Essentially, the code is still connecting to SMTP server running on the host.本质上,代码仍然连接到主机上运行的 SMTP 服务器。
  • You package SMTP server and the python stmp client application (code you shared) in the same Docker image.您的 package SMTP 服务器和 python stmp 客户端应用程序(您共享的代码)在同一个 ZC5FD214CDD0D2B3B42Z2 图像中。 It's bad practice and should be avoided.这是不好的做法,应该避免。 But you can follow the docs to achieve it.但是您可以按照文档来实现它。

Please, do share the following to better understand the question:请分享以下内容以更好地理解问题:

More specifically:进一步来说:

  • OS you are use.您正在使用的操作系统。 Docker for desktop behaves differently for Mac and Windows, especially in terms of networking features.桌面版 Docker 对于 Mac 和 Windows 的行为不同, 尤其是在网络功能方面。

  • Dockerfile you use. Dockerfile你用。 Otherwise it's impossible to run the image and replicate the issue you are facing and understand what you mean by sendmail service is running in my container.否则,无法运行映像并复制您面临的问题并理解sendmail service is running in my container.

  • Fully working python code (including imports, etc...) Otherwise, it's not clear what smtplib you use.完全工作的 python 代码(包括导入等)否则,不清楚您使用什么smtplib

  • Links to documentation.文档链接。 If you use standard library smtplib , then its docs doesn't have such description:如果您使用标准库smtplib ,那么它的文档没有这样的描述:

sendmail method description has this: sendmail 方法描述有这样的:

... the message was accepted for delivery to three of the four addresses, and one was rejected, with the error code 550. If all addresses are accepted, then the method will return an empty dictionary. ...消息被接受以传递到四个地址中的三个,一个被拒绝,错误代码为 550。如果所有地址都被接受,则该方法将返回一个空字典。

By default, the docker containers run in a separate network stack, so localhost does not mean the same thing inside a docker container as it does when your code runs directly on your computer.默认情况下,docker 容器在单独的网络堆栈中运行,因此localhost在 docker 容器中的含义与代码直接在计算机上运行时的含义不同。

Depending on how your SMTP server is set up, it might also be configured to refuse sending any email but those coming directly from your computer, and a docker container might be treated as an outsider that should not be sending an email through it. Depending on how your SMTP server is set up, it might also be configured to refuse sending any email but those coming directly from your computer, and a docker container might be treated as an outsider that should not be sending an email through it.

I guess the simplest solution would be to run your docker container with --net=host .我想最简单的解决方案是使用--net=host运行您的 docker 容器。 With this the network stack of the docker container will be the same as the stack of your computer and everything should work as if the code was running directly outside docker.有了这个,docker 容器的网络堆栈将与您的计算机的堆栈相同,并且一切都应该像代码直接在 docker 外部运行一样工作。

If it works on host machine, try using the host IP instead of localhost .如果它适用于主机,请尝试使用主机 IP 而不是localhost

s = smtplib.SMTP(HOST_IP)

Or as Arthur suggested, you can run the container in host network with --net=host and then continue using localhost .或者正如 Arthur 建议的那样,您可以使用--net=host在主机网络中运行容器,然后继续使用localhost

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python使用本地smtp服务器向用户发送邮件 - Python send a mail to the user using local smtp server 通过 python 使用 SMTP 服务器发送邮件 - send mail via python with SMTP server 如何设置邮件服务器并使用 python SMTP 发送电子邮件 - how to set up a mail server and send emails using python SMTP 如何将 python 文件发送到 docker 容器(使用 python 映像)并获取 Z78E6221F6393D1356681 到本地的 DB398DZF - how to send python file to docker container(using python image) and get the output back to local 如何删除 docker 容器内 python 中的文件? - How to delete file in python inside docker container? 我如何在 Docker 容器内的 python 脚本中连接到 redis 服务器 - how do i connect to redis server in python script inside a Docker container 如何直接从服务器使用python发送电子邮件而不使用smtp - how to send email with python directly from server and without smtp 使用boto3从docker容器内部连接到DynamoDB Local - Connect to DynamoDB Local from inside docker container with boto3 SMTP 服务器与python3 - SMTP server with python3 kafka-python生产者在docker容器中运行时无法发送 - kafka-python producer not able to send when run in a docker container
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM