Ghost inside docker — unable to reach Mailgun HTTPS API

Hi all. I’m having the darndest time trying to get newsletter bulk sending working. I’m running ghost in docker alongside MariaDB (since Maria uses the same engine as MySQL, this works seamlessly with ghost, as far as I can tell—that’s not my issue). Everything is running behind nginx as a reverse proxy, configured outside of docker, which is listening to port 443 and using proxy_pass to forward requests to http://localhost:5555.

My docker compose file looks like this:

services:

  ghost:
    image: ghost:latest
    depends_on:
      - ghostdb
    restart: always
    ports:
      - 5555:2368
    environment:
      database__client: mysql
      database__connection__host: ghostdb
      database__connection__user: ghostusr
      database__connection__password: ***
      database__connection__database: ghostdatabase
      database__connection__port: 3306
      mail__transport: "SMTP"
      mail__from: "***"
      mail__options__service: "Mailgun"
      mail__options__secure: true
      mail__options__host: "smtp.mailgun.org"
      mail__options__port: 465
      mail__options__auth__user: "***"
      mail__options__auth__pass: "***"
      url: myurl
      NODE_ENV: production
    volumes:
      - ghost:/var/lib/ghost/content

  ghostdb:
    container_name: ghostdb
    image: mariadb
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=***
      - MYSQL_DATABASE=ghostdatabase
      - MYSQL_USER=ghostusr
      - MYSQL_PASSWORD=***
    volumes:
      - /mnt/ghostdb:/var/lib/mysql

volumes:
  ghost:
  ghostdb:

The error I am getting is that when I try to publish a post and send a newsletter, it’s unable to reach Mailgun’s API.

At first, I thought it might be because it’s running in docker and can’t access the host network. But transactional emails over SMTP work fine—it’s only the HTTPS request that does not work.

I’ve tried all sorts of things. I’ve tried opening the docker container to the host network, but then I couldn’t connect to my database. I’ve tried explicitly mapping 443 in the ghost container, but that’s not working. I’ve opened port 443 on my web host for both ingress and egress. I’m at a loss here.

Why can’t ghost make an API call out to the internet from inside the docker container?

Have you had a look at the logs produced by Ghost?

docker compose logs should show what’s going on :slight_smile:

1 Like

Yes, they throw an ECONNABORTED error after timing out while trying to call the Mailgun API

ghost-1  | [2024-11-10 17:50:32] ERROR ECONNABORTED
ghost-1  | [2024-11-10 17:50:32] ERROR [BULK_EMAIL_DB_RETRY] Sending email batch 6730f22cdc1ebf0001f51bd5  - Failed (1st try)
ghost-1  | 
ghost-1  | [BULK_EMAIL_DB_RETRY] Sending email batch 6730f22cdc1ebf0001f51bd5  - Failed (1st try)
ghost-1  | 
ghost-1  | "Mailgun Error 400: timeout of 60000ms exceeded"
ghost-1  | "https://ghost.org/docs/newsletters/#bulk-email-configuration"
ghost-1  | 
ghost-1  | Error ID:
ghost-1  |     48469dc0-9f8c-11ef-acf8-a99ee5298814
ghost-1  | 
ghost-1  | Error Code: 
ghost-1  |     BULK_EMAIL_DB_RETRY

looks like we may have a similiar issue - please view this one here scroll to the end of the thread - Failed to send magic link email Error when trying to sign up - #35 by Mediatech

From what you’ve described, it seems like there might be an issue with the container’s network settings, especially if it’s able to send SMTP but not access Mailgun’s HTTPS API.

One thing to try is setting the network mode to host in your Docker Compose file for the Ghost container. It might look something like this:
network_mode: host