In 2019, it’s the default config for postfix on RHEL/CentOS. Postfix binds only to the loopback interface and drops all smtp requests that don’t originate from 127.0.0.0/8
. No auth required. I’m not sure about debian, but I’d imagine exim
has a similar default config.
A couple relevant topics on these forums from other users who hit this issue:
- How to set SMTP config to use localhost?
- https://meta.discourse.org/t/smtp-without-user-or-password/88879
There doesn’t appear to be a topic for how to set this up on RHEL/Cent OS with the necessary changes to both Discourse and postfix, so I’m documenting this here.
This does not appear to be possible with the discourse-setup
script, but I did get this to work.
First, I had to figure out the IP address of the docker host as the docker container sees it. Using 127.0.0.1
won’t work because the docker container will see 127.0.0.1
as itself. Rather, we need to specify the IP address or hostname of the docker host that is running the postfix SMTP server, and one that is addressible by the docker container (so not your docker host’s Internet-facing IP address if you want your SMTP server to not be Internet-accessible, for example).
I extracted the relevant IP address of the docker host (172.17.0.1
) from the docker0
interface by executing this on the docker host:
[maltfield@osestaging1 ~]$ ip address show docker0
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 02:42:80:35:65:a1 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:80ff:fe35:65a1/64 scope link
valid_lft forever preferred_lft forever
[maltfield@osestaging1 ~]$
Then I edited my Discourse app’s yaml file, setting the “DISCOURSE_SMTP_ADDRESS” to 172.17.0.1
from above.
[maltfield@osestaging1 ~]$ cd /var/discourse/
[maltfield@osestaging1 discourse]$ grep SMTP containers/app.yml
DISCOURSE_SMTP_ADDRESS: 172.17.0.1
DISCOURSE_SMTP_PORT: 25
DISCOURSE_SMTP_AUTHENTICATION: none
DISCOURSE_SMTP_OPENSSL_VERIFY_MODE: none
DISCOURSE_SMTP_ENABLE_START_TLS: false
[maltfield@osestaging1 discourse]$
Note that I first tried to use the internal docker hostname host.docker.internal
for this, but apparently this hostname isn’t available to linux docker users
Because the default postfix configuration in RHEL/Cent OS binds only to 127.0.0.1 (which is good), you’ll need to change /etc/postfix/main.cf
so it also binds to the docker0
interface and add that subnet to the mynetworks
group so that SMTP traffic coming from docker containers will be accepted by postfix.
[maltfield@osestaging1 postfix]$ grep -ir '172.17' /etc/postfix/*
/etc/postfix/main.cf:inet_interfaces = 127.0.0.1, 172.17.0.1
/etc/postfix/main.cf:mynetworks = 127.0.0.0/8, 172.17.0.0/16
[maltfield@osestaging1 postfix]$
After those changes, rebuild Discourse and it should now be able to send emails out through your docker host’s postfix.
/var/discourse/launcher rebuild app
While this works, I have a few questions:
- Is there some other environment variable or hostname that already points to the docker host (
172.17.0.1
in this case)?
I noticed that there is a DISCOURSE_HOST_IP environment variable “injected” by launcher
. Is it possible to set this DISCOURSE_SMTP_ADDRESS
yaml key to the same value as the other’s yaml key with something like this?
DISCOURSE_SMTP_ADDRESS: $DISCOURSE_HOST_IP
- In general, how durable is the
172.17.0.1
IP of the docker host? Is it always this IP on RHEL/Cent OS systems? Will it ever change on me?