my road to docker smtp

My Road to Docker: Sorting Out SMTP

This post may contain affiliate links. Please see the disclaimer for more information.

This post is part of a series on this project. Here is the series so far:

Having said in my last ‘Road to Docker’ post that I didn’t have any current plans for another post, something came up which warrants a write up here. I managed to solve the problem in question in a Dockerised fashion and I’m quite pleased with the solution. Let’s get into it….

The Backstory

After converting my web stack over to Docker recently, I had installed the WP Mail SMTP plugin in WordPress to handle mail from the site. This was required since WordPress could no longer send via a local mail setup. I configured the plugin to send via my existing mail server. This worked well for a while – then I encountered a speed bump on my road to Docker!

For some reason (I think due to an update of the WordPress container), I just stopped receiving email from the site. Upon investigation it seemed that the TLS connection was unable to be started correctly. I got the following debug log when testing mail via WordPress:

SMTP Debug:

2019-07-30 08:38:11	Connection: opening to, timeout=300, options=array (
2019-07-30 08:38:11	Connection: opened
2019-07-30 08:38:11	SERVER -> CLIENT: 220 ESMTP Postfix
2019-07-30 08:38:11	CLIENT -> SERVER: EHLO
2019-07-30 08:38:11	SERVER -> CLIENT:
                   	                  250-SIZE 30720000
                   	                  250 DSN
2019-07-30 08:38:11	CLIENT -> SERVER: STARTTLS
2019-07-30 08:38:11	SERVER -> CLIENT: 220 2.0.0 Ready to start TLS
2019-07-30 08:38:12	SMTP Error: Could not connect to SMTP host.
2019-07-30 08:38:12	CLIENT -> SERVER: QUIT
2019-07-30 08:38:12	SERVER -> CLIENT: 
2019-07-30 08:38:12	SMTP ERROR: QUIT command failed: 
2019-07-30 08:38:12	Connection: closed
2019-07-30 08:38:12	SMTP Error: Could not connect to SMTP host.

Looking into the logs on the mail server, I found the following corresponding error:

warning: TLS library problem: 27261:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1275:SSL alert number 40:

I tried googling the error, but after trying a few of the suggested fixes, I gave up and decided to solve the problem a different way.

Fixing it, Take 1

My first attempt involved installing Postfix on the host in a smarthost configuration to my main server. This is the same setup as I use on most of my servers for system mail from cron, etc (via a custom Ansible role).

After getting the mail system running and able to send mail from the host, I tried to configure it in WordPress. However, I was unable to connect to the host machine from the container on the Docker host IP address. I investigated this and found that because I was using a private network the IP address was different than the standard Docker interface address.

Trying this address didn’t work either. Perhaps this is a security feature in Docker, or perhaps I was doing it wrong. Either way it pushed me on to a better solution.

Fixing it, Take 2

My next plan involved putting Postfix into a container. This would be put on the same private network as the WordPress container to allow access. I needed to keep the smarthost configuration to talk to the main mailserver. A quick search turned up a suitable image in the form of boky/postfix. This image is intended exactly for this purpose and I was able to set it up without too much trouble.

To spin this up I added the following to my previous docker-compose.yml file:

    image: boky/postfix
      - ""
      RELAYHOST_TLS_LEVEL: "verify"
      - /home/rob/docker-data/postfix/spool:/var/spool/postfix
      - internal
    restart: always

Pretty simple! As per the previous post I put all the secrets into an file to keep them separate from the stack.

The mail forwarder is available both on the internal Docker network and on the host system to replace the native mail forwarding setup. Setting this up with WordPress ended up being trivial (see screenshot below). However, I required some further configuration to make the mail on the host system work.

my road to docker smtp
We just use the container name as the hostname and 587 as the port! Authentication and SMTP aren’t required for the local connection.


In order to redirect the system mail from the host via the Dockerised mail forwarder, I had to set up MSMTP. This is pretty effectively documented elsewhere, so I won’t go into details. The only differences in this setup are that we don’t require authentication or TLS to the mail forwarder because it’s only available locally. The mail forwarder itself is already handling authentication and TLS to the main mail server.

For reference, here is the msmtprc file I ended up with:

# Set default values for all following accounts.
auth           off
tls            off
logfile        /var/log/msmtp/msmtp.log

# Local mailserver
account        local
host           localhost
port           587

# Set a default account
account default : local

aliases         /etc/aliases


Here we’ve seen how to quickly deploy a mail forwarding server for your Dockerised applications. We’ve also configured our host system to also use it, so we don’t need to run two forwarders.

I feel that this is the best solution to this problem (although I still don’t quite know what the original problem was!). It feels like a nicer solution than my original solution of running the mail forwarder locally. It has also resulted in one more Dockerised application!

I’m intending to convert my other Docker servers over to this approach in the near future. For the system mail part, I still need to create an Ansible role to push out the MSMTP configuration. Actually, the whole question of Ansible/host configuration and how it fits with Dockerised services is still something I need to work out. If anyone has any ideas feel free to share in the comments.

As I said in the last post, I don’t have any more ‘Road to Docker’ posts planned in the immediate future. However, the migration is ongoing so there will be more at some point!

If you liked this post and want to see more, please consider subscribing to the mailing list (below) or the RSS feed. You can also follow me on Twitter. If you want to show your appreciation, feel free to buy me a coffee.


Why email will never be Free…

Hello! This blog is not dead and neither am I. It’s been a long while since I’ve written anything here and the site is starting to look a bit abandoned. I’ve been seriously busy with what I refer to as ‘life stuff’ over the last few months and my ‘tech-time’ has been a bit squeezed, so I haven’t had much to write about. I’m now getting back into the swing of things and starting to think of stuff to write about.

Email. We all use it. It works, right? Well for the most part. It’s probably one of the most used and simplest forms of digital communication available today. Shame it’s so horribly complicated then.

My major task over the last couple of weeks has been getting my new server set up so that it hosts my own email and provides accounts for members of my family. I’ve actually been doing this on and off pretty much since I got the server, but with the release of CentOS 6 I decided to cut my losses and upgrade sooner rather than later.

So I set out installing Postfix and Dovecot, following the instructions on the CentOS wiki pages. I managed to get through all the configuration of Amavisd, ClamAV and Spamassasin and I installed Roundcube for webmail access. Then I started thinking about adding users for my family and came to the decision that I didn’t want to add shell users for every email account, so I would modify my set up to incorporate virtual users and domains. After following a dead end of setting this up using plain text files (which turns out to be more fiddly to administer than shell accounts) I settled on using Postfix.admin with a database based system. Then there were my adventures with sieve, managesieve and Roundcube, which turned into a whole afternoon of getting nowhere.

Now my gripe here isn’t with the software. Far from it, all the previously mentioned software is excellent. Nor is it even with the documentation, although that is lacking in some areas, usually a quick web search will find you a useful forum post. No, my problem here is that I had to do all this in the first place in order to set up a Autonomous Free Software based mail system.

Given that I did this partly for the fun of it (yes I appear to like the pain of making tea), this isn’t really a problem for me. When I changed over my DNS everything pretty much worked, but I’m not your average user. Now, I know there are things like iRedMail, which can automate all this stuff and if I hadn’t wanted to learn how a mail system works I probably would have tried it. However, I’m skeptical as to the reliability of such a system.

This brings us to the crux of the problem. Email is too complicated! Think about all those disparate components I listed above, each of which is developed separately and has to interact seamlessly in order for the system to keep going. If one breaks, you’re screwed. I think this is probably worse in a iRedMail based system as the administrator would have no expertise in the inner workings of the system.

This leads me to my actual point (finally!). This is why people use Gmail, Hotmail, etc. It’s not because they would otherwise have to provide their own hosting, it’s because these services make it easy. I think what I’m basically asking for is “WordPress for email”. Something I can just unpack point it at a database and go, without having to know an what an RBL is. Yes, this wouldn’t be as easy as Gmail, but Blogger or Tumblr are easier than self-hosted WordPress and there are still tons of WordPress blogs out there. It would put Free Software based email within the reach of the ordinary computer literate person.

My fear is that the Free Software community treats email as a largely solved problem. We have loads of great software, which works for those of us with beards. However, until we make it easy to use, simple, cohesive and pretty, email is destined to languish in the land of the non-Free.