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
env:
- name: url
value: https://blog.domain.com
- name: mail__transport
value: SMTP
- name: mail__options__host
value: 99.99.99.99
- name: mail__options__port
value: '25'
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:
environment:
- 'mail__transport:SMTP'
- 'mail__options__host:mail.domain.com'
- 'mail__options__port:25'
- 'url=https://test.domain.com'
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.