Gmail SMTP with Ghost docker (alpine)

I’ve read everything I can find on this forum (and other places) regarding this topic, but I still can’t for the life of me figure out why I can’t send a simple invite to add people as contributors/authors.

Below is the error messages I got from the container’s log via portainer:

Error sending email: Failed to send email. Reason: queryA ETIMEOUT smtp.gmail.com. Please check your email settings and resend the invitation.
Error: queryA ETIMEOUT smtp.gmail.com

at createMailError (/var/lib/ghost/versions/4.41.3/core/server/services/mail/GhostMailer.js:67:12)

at QueryReqWrap.onresolve [as oncomplete] (dns.js:210:19)

I’m running Ghost on the latest alpine docker image, behind a traefik reverse proxy (I doubt traefik is the reason for the error). I don’t use a config.production.json file, so everything is coded into my docker-compose.yml as below:

version: '3.1'
services:
  ghost:
    container_name: ghost
    image: ghost:4-alpine
    restart: always
    security_opt:
      - no-new-privileges:true
    ports:
      - 1234:1234
    environment:
      url: https://photos.DOMAIN.COM
      mail__transport: SMTP
      mail__from: name@gmail.com <name@gmail.com>
      #mail__options__service: 'gmail' (I've tried with this line active as well)
      mail__options__host: 'smtp.gmail.com'
      mail__options__port: 465 #SSL
      mail__options__secure: 'true'
      mail__options__auth__user: 'name@gmail.com'
      mail__options__auth__pass: 'app_password' # Google's app password for "less secure apps"
    volumes:
      - /share/FOLDER/ghost/blog:/var/lib/ghost/content # bind mount for persistent volume
    labels:
      # Traefik rules
      - "traefik.enable=true"
      - "traefik.http.routers.ghost.entrypoints=http"
      - "traefik.http.routers.ghost.rule=Host(`photos.DOMAIN.COM`)"
      - "traefik.http.middlewares.ghost-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.ghost.middlewares=ghost-https-redirect"
      - "traefik.http.routers.ghost-secure.entrypoints=https"
      - "traefik.http.routers.ghost-secure.rule=Host(`photos.DOMAIN.COM`)"
      - "traefik.http.routers.ghost-secure.tls=true"
      - "traefik.http.routers.ghost-secure.service=ghost"
      - "traefik.http.services.ghost.loadbalancer.server.port=1234"

Any pointers as to what I might be doing wrong?

Can you drop inside the container and make sure you have network connectivity.

Installing telnet or such and ensure you can connect to the port works be helpful for diagnostics.

I’ll see if I can get Telnet installed via Homebrew on my Mac (and just FYI my Ghost docker is running on a QNAP NAS). But I’m quite sure the connection to my Ghost docker is fine though, since I can access Ghost simply via photos.DOMAIN.COM (I have the domain pointed to my NAS’s IP) as referred to in my docker-compose.yml in my original post. In fact everything works pretty much as expected other than the email issue.

I just tried using telnet to connect to photos.DOMAIN.COM, but it appears telnet times out. I checked the IP it pointed to – it was a Cloudflare IP, and rightly so, as my domain has been proxied behind Cloudflare. Not sure why it would time-out over telnet though, as I can connect to my Ghost blog without any issues simply by pointing my browser towards photos.DOMAIN.COM. Any pointers?