Ghost blog mail configuration in Docker and Kubernetes
This post documents my experiments on configuring something as simple as SMTP mail for the ghost blogging platform using a non cloud email server.
I believed this would be a trivial thing to do, and ultimately it was. However, as always there were very fine details that needed to be configured very precisely for all of this to work.
Context
I have a public blog running ghost that uses a public email service which was working fine. Information about doing this is a simple google search away as this is the most common use case.
I wanted to implement this same functionality in a private network that uses MS Exchange. This was running in a Kubernetes pod via a deployment so I believed it was a simple matter of taking the environment variable configuration from docker-compose and translate it into the correct format for supplying environment variables to the container in kubernetes.
Key takeaways
The following is the configuration that finally worked
However these were the key points you should be very aware of:
- The configuration option name must be specificed exactly. For the longest time I had missed the
mail_transport
option entirely whilemail__options_host
andmail__options_port
and varioues othermail__options_*
were configured. When I did realize themail_transport
option was missing I has initially made the mistake of naming itmail_options_transport
. - Kubernetes may not have a way to resolve DNS names you will specific for the
mail_options_host
parameter and that's why I ended up configuring the IP. This will probably break if the mail service hosted on a different IP in the future.
Debug process I went through
At first I couldn't get this to work in Kubernetes and instead of inspecting the ghost config options and logs within Kubernetes which I haven't done before, I decided to debug the mail configuation from within an ephemeral docker container that I ran using docker run --rm -p 5000:2368 --name ghost ghost
. I docker exec -ti ghost bash
into the container and attempted to use the ghost
shell command under the var/lib/ghost
folder. However, I got feedback that I can't run ghost
using the root user. I created a new user with elevated privileges as was pointed out through a link in the error message. However, this led to challenges with permissions on the config.production.json
file. Then I attempted to mount a host volume to the ephemeral container via docker run --rm -v $(pwd):/var/lib/ghost -p 5000:2368 --name ghost ghost
, but the container would always exit. I didn't figure out why. Finally, I just created a docker-compose file and experimented with providing the relevant environment variabe parameters. The configuration looked like this:
After multiple configuration changes and attempts to send test mails via the Ghost > Labs > Send Test Mail functionality, I noticed that the url
parameter had an =
between the key and the value. I then did the same for mail parameter like so:
environment:
- 'mail__transport=SMTP'
- 'mail__options__host=mail.domain.com'
- 'mail__options__port=25'
- 'url=https://test.domain.com'
And suddenly the mail started going through. So it was just a matter of using =
rather than :
. Funny enough, the configuration with :
works fine when using a public mail service but not for when using a private email service in a private network.
Conclusion
The intent of this post was to help others who might experience the same issue and also to give an insight in to the debug process that I followed. Hopefully this can lead to improvements in how I debug such problems in future this saving time.