可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a docker container running php and apache. The host is in an AWS instance which has the docker instance running. I am unable to send an email from the docker terminal. Is there any way to send an email from docker instance using sendmail which uses the docker's host's configuration?
The following command sends an email from host but doesn't send an email from docker instance. No error is given either.
echo "Subject: Testing Email" | cat - text | /usr/lib/sendmail -F abc.pqr@domain.com -t abc.pqr@domain.com
回答1:
What I do is to configure the host MTA to listen on docker0
and install ssmtp in the container to bridge sendmail in the container with the host MTA. The reason to run an MTA on the host is that system (critical) errors can be sent to the admin's mailbox. The reason to not run MTA in the container is that it is a duplicated process as the host system already runs an MTA.
On the host, I used postfix. All we need to do is to configure postfix to listen on docker0
and accept outgoing mails from Docker containers. Edit the file /etc/postfix/main.cf
and add the docker0
IP address to inet_interfaces
so it accepts connections from Docker containers. Also, add the network addresses of Docker containers to mynetworks
so that Docker containers are legal to send mails via the postfix server on the host. (reference and more details)
To use sendmail in containers, install ssmtp and set FromLineOverride
to be permitted and and mailhub
to the IP address of the host in /etc/ssmtp/ssmtp.conf
. You can set mailhub
to be a symbol such as smtp-server
and then run the container with --add-host
option, as shown in this Dockerfile (run it with --add-host smtp-server:your-docker0-address
). This would configure a usable sendmail in containers which would actually use the host MTA to send mails.
回答2:
Nowhere in your Dockerfile is sendmail (or any other mail agent) installed. The host, however, apparently does have sendmail available. The "best" or most Docker-like solution is to spin up another container that runs an MTA (like postfix or exim), and configure your application to use that.
回答3:
building on previous answers,
create config/sendmail_config.sh with:
#!/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
change yum for apt-get on debian based containers
then in Dockerfile add:
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 .
I want sendmail with my php util so I can stick it anywhere with out having to link to another MTA container or host to complete the task.
I run sh sendmail_config.sh, and then run my php util.
回答4:
Adding a fully qualified domain name to the Docker host name in /etc/hosts does the trick for me:
{YourDockerIP} {YouDockerHostName}.localdomain {YouDockerHostName}
To me it looks like this:
172.17.0.25 77f5a7ae8606.localdomain 77f5a7ae8606
You can also use this bash script to automatically update this line:
#!/bin/bash
line=$(head -n 1 /etc/hosts | awk '{printf "%s %s.localdomain %s", $1, $2, $2}')
sed -e "1 s/^.*$/${line}/g" /etc/hosts > hosts
# with sed -i, it actually performs a rename of /etc/hosts, but docker does not
# allow that, so we have to use a temp file and copy it to overwrite /etc/hosts
cp hosts /etc/hosts
rm hosts
Reference: http://hjk41.azurewebsites.net/2015/09/25/using-sendmail-inside-docker/
回答5:
I figured out a way myself, although not the most elegant solution. I configured the sendmail inside my docker so as to Relay the request via host's ip. Add the following line to the file "/etc/mail/access
Connect:<host_ip_here> RELAY
Also, in the host as well as docker, comment out the following line in the file "/etc/mail/sendmail.mc" by prefixing it with "dnl #" and suffixing with "dnl".
DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')
I passed the host ip as an environment variable to the docker container, so that it is configurable. Now the docker's sendmail will relay it's sendmail's smtp request via host machine.
回答6:
Assuming there is a mail server installed and configured on host!
Alpine based docker images should have sendmail
executable.
The simple solution is to run the container on host' network:
docker run --rm --net="host" php:fpm-alpine sh -c 'echo "Subject: test" | sendmail -v your@mail.com'
To run the container with default network bridge,
configure mail server to listen on docker interface 172.17.0.1,
and allow to relay emails from docker subnet 172.17.0.0/16.
Exim options affected in: /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'
Restart mail server and run the container 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'
回答7:
EDIT: Please see xuhdev answer for more info and how to set up mail forwarder. My answer can be used to setup sendmail instead of postfix on host.
EDIT #2: Add firewall rule to allow smtp traffic from docker
I have made a similiar setup as the tarun mittal as following:
- in docker app I have set it up to use the smtp server with the ip of docker0 interface (172.17.42.1)
in docker host, modified the /etc/mail/sendmail.mc to include listening on the docker0 interface (in contrast to all interfaces in tarun's answer - bold is added line)
DAEMON_OPTIONS(`Family=inet, Name=MTA-v4, Port=smtp, Addr=127.0.0.1')dnl
DAEMON_OPTIONS(`Family=inet, Name=MTA-v4, Port=smtp, Addr=172.17.42.1')dnl
Allow the access from the docker containers to docker interface in firewall
iptables -I INPUT -s 172.17.0.0/24 -d 172.17.42.1 -dport 25 -j ACCEPT
in /etc/mail/access I have added at the end to allow all docker instances to send emails and makemap hash /etc/mail/access < /etc/mail/access to compile database
/// EDITED - USE BELOW AS DOCKER WILL GO TO 172.17.1.X after many rebuilds
/// OLD - Connect:172.17.0 RELAY
Connect:172.17 RELAY
Finally restart sendmail - service sendmail restart
回答8:
I struggled with this issue as well. From my python code running inside a docker container, I needed to temporarily send emails using postfix (smtp server) running on the host machine. After trying whole bunch of things, what turned out to be a simple solution was docker run command with --net="host". Caution: This may not be a good solution in all cases as such a container will share the network stack with the docker host and from the container point of view, localhost(or 127.0.0.1) will refer to the docker host.
Here's what I did on an ubuntu host:
docker run -it --net="host" ubuntu /bin/bash
This gave me the container shell.
I then installed python in this container:
apt-get update && apt-get -y install supervisor python-pip
Then I launched the python interpreter and fired the following lines of code:
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
I also found [this][1] a useful read.
回答9:
You have to point inet_interfaces to docker bridge (docker0) in post fix config located at set /etc/postfix/main.cf
inet_interfaces =
More internal working detail at sending email from docker via postfix installed on host
Note: use ifconfig command to get the docker bridge address
回答10:
According to the Sendmail manual we may use sendmail -bd
command to run a service. But it exists with zero status. So...
# In your Dockerfile
RUN yum install -y sendmail
# Run mail listener
RUN sendmail -bd
CMD sleep infinity
# or run your command
Also you may use supervisord.
I use this config:
[program:sendmail]
command=/usr/sbin/sendmail -bd
autostart=true
autorestart=false
numprocs=1
startretries=0
And test it:
$ echo test123 | sendmail your@mail.com
Don't forget to check Spam folder.