Python send mail inside docker container with local SMTP server
Asked Answered
T

3

9

I want to send mail with smtp lib on python. I understand that it uses local smtp service on port number 25. I have below codes. 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.

My codes:

from_mail = '[email protected]'
to_mail = '[email protected]'

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. In the sendmail method description has this:

... 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.

Is it about network configuration? Should I configure any network settings?

Tonita answered 15/6, 2020 at 9:22 Comment(4)
What image is tour container based on? And how do you run the container? This may help solve your issueSalisbury
My container based on python:3.6-slim-busterTonita
can you share the dockerfile, please?Peppers
what is your operating system?Peppers
P
6

The code you shared is SMTP client application. 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:

  • You start the container with --net=host, then no changes is needed. calling smtplib.SMTP('localhost') will connect to SMTP server running on the host.
  • You don't start the container with --net=host. Then you need to connect to host.docker.internal instead of localhost if you use Windows or MacOS. If you use Linux, may need to use another trick. Essentially, the code is still connecting to SMTP server running on the host.
  • You package SMTP server and the python stmp client application (code you shared) in the same Docker image. 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.

  • Dockerfile you use. 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.

  • Fully working python code (including imports, etc...) Otherwise, it's not clear what smtplib you use.

  • Links to documentation. If you use standard library smtplib, then its docs doesn't have such description:

sendmail method description has this:

... 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.

Peppers answered 23/6, 2020 at 20:50 Comment(1)
--net=host didn't work for me (perhaps because I was using 0.0.0.0 instead of localhost) but host.docker.internal worked perfectly! Thanks.Md
I
0

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.

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. 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.

Internship answered 17/6, 2020 at 9:43 Comment(1)
I have not any problems about connect to smtp service on docker container. When I change the connection informations - for example another port number or host name - I get connection error.Tonita
T
0

If it works on host machine, try using the host IP instead of 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.

Tobytobye answered 18/6, 2020 at 20:32 Comment(2)
Thanks for answer, sendmail service is running in my container. I want to send mail from container not using host.Tonita
Are you sure about that? You need to add more details to your question then. The dockerfile of your container, how you installed smtp service in the container etcTobytobye

© 2022 - 2024 — McMap. All rights reserved.