Mailsetup in Docker only working with environment variables

Hey fellow ghosts,

I am checking out selfhosting ghost employing docker. Having it run for a while to do some testing I just realized today that the mail setup via the config.production.json I have been using, doesnt work anymore.

However, when I set the mail config via the environment variables in my docker compose file it works flawlessly. For this I removed the bind mount to a config file I had saved on the host. The automically generated config-production.json file inside the container shows for the mail config just the transport : Direct parameter and nothing else.

I wonder, if the config is stored in a different place now? Did I miss some changes regarding the config via docker? I checked github, the forum and google, but couldn’t find anything giving me a clue on what I am doing wrong.

Any help or advice is much appreciated!


EDIT: Currently running ghost 5.82.2 in a proxmox lxc running docker with debian 11.

You should be able bind-mount your own config.production.json into the container.

You can test if it’s working by running the bash shell in the container and looking around. From memory, the command would be like:

docker exec -ti my_container_name bash

You could share the config you tried that didn’t work.

@markstos, thanks for taking the time. See the following excerpt of the config file with the mail config. It worked before the way it is, but doesnt now. I cannot really tell when it actually stopped working. I just realized yesterday when checking the logs in portainer.

  "mail": {
    "transport": "SMTP",
    "from": "'blog'  <XXX@domain.tld>",
    "logger": true,
    "options": {
        "service": "XXX",
        "host": "srv.maildomain.tld",
        "secure": true,
        "port": 465,
        "auth": {
            "user": "mail address as username",
            "pass": "password"

Also, I entered the console in portainer and checked, that the bind mount works and has the config file I mount. I can confirm, that it is the corrrect file.

When using the config file I get the follow error in the logs

ARN Error sending email: Failed to send email. Reason: Missing credentials for "PLAIN". Please check your email settings and resend the invitation.
[2024-04-22 16:38:12] ERROR "POST /ghost/api/admin/invites/" 500 231ms
Error sending email: Failed to send email. Reason: Missing credentials for "PLAIN". Please check your email settings and resend the invitation.

which leaves the impression I am not sending any credentials to the mailserver of my provider when wanting to send the email. Apparently, my provider doesnt block external requests since it is working with other apps I host and also works when configuring email via the environmental variables in the compose file.

If you have more advice I really appreciate it.

Best regards,

When you say you entered the container and found the file as expected, was it mounted to /var/lig/ghost/config.production.json inside the container?

It could be that something changed on your email provider’s side. Research how to test the SMTP connection directly or with another tool and confirm your SMTP settings work outside of Ghost.

Thanks again @markstos for answering my post.

Yes, the file is mounted to /var/lib/ghost/config.production.json (assuming you meant /lib and not /lig ) and shows the same content as the file on the docker host. That is way I assumed it, was mounted correctly.

That I dont get. What would need to change at the provider side, so the setup via the environment variables in docker would work but the setup directly via the mounted config.production.json would doesnt?

Also, I am using the same settings on a couple of other services run in docker and none of them have the same issue. However, in all of them I must set the mail config via environment variables.

Did a check, my mail provider does not report any technical issues, the service is not down and they also do not block external requests. As I said, if that were the case, setting the mail config via docker environment variables shouldnt work.

Referring to the error log it seems the request to the smtp service does not send the required credentials to log in, hence it doesnt work. Maybe there is an additional config parameter, I need to set, to make it work.


Both environment variables and the config file are directly supported by Ghost, which in turn uses nconf to handle configuration. That’s documented here:

I see three possibilities:

  1. Although the env and file based configurations are assumed to be the same. They are not. You could post them both for comparison.
  2. Precedence. Perhaps one is overriding the other. The official Ghost config docs (Configuration - Adapt your publication to suit your needs) Don’t specific the precedence order, but I presume ENV vars override the config file.
  3. Permissions. The config file is correctly mounted into the container, but can’t be read by the Node process inside the container. I can’t explain that would have worked before and then stopped, though.