Ghost installed via docker failed to send magic link for signup via SendGrid

I just setup ghost via Docker compose using this config:

  ghost:
    image: ghost:5-alpine
    container_name: ghost
    restart: always
    ports:
      - 8282:2368
    environment:
      database__client: mysql
      database__connection__host: ghostdb
      database__connection__user: root
      database__connection__password: XXXXXXXXX
      database__connection__database: ghost
      mail__options__service: Sendgrid
      mail__options__host: smtp.sendgrid.net
      mail__options__port: 587
      mail__options__secureConnection: true
      mail__from: system@blog.rooday.com
      mail__options__auth__user: apikey
      mail__options__auth__pass: XXXXXXXXX
      url: https://blog.rooday.com
    volumes:
      - /home/ghost:/var/lib/ghost/content
    labels:
      - traefik.enable=true
      - traefik.http.routers.ghost.rule=Host(`blog.rooday.com`)
      - traefik.http.services.ghost.loadbalancer.server.port=2368
      - traefik.http.routers.ghost.entrypoints=websecure
      - traefik.http.routers.ghost.tls.certresolver=cloudflare
  ghostdb:
    image: mysql:8.0
    container_name: ghostdb
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: XXXXXXXXX
    volumes:
      - /home/ghostdb:/var/lib/mysql

I tried navigating to my blog and signing up but I get this error in the logs:

[2024-02-05 21:10:25] ERROR "POST /members/api/send-magic-link/" 500 509ms

Failed to send email. Reason: Sending failed.

"Please see https://ghost.org/docs/config/#mail for instructions on configuring email."

Error ID:
    fb610100-c46a-11ee-836c-0119355d8e9e

----------------------------------------

Error: Sending failed
    at createMailError (/var/lib/ghost/versions/5.78.0/core/server/services/mail/GhostMailer.js:105:12)
    at DirectMailer.<anonymous> (/var/lib/ghost/versions/5.78.0/node_modules/nodemailer-direct-transport/lib/direct-transport.js:157:41)
    at DirectMailer.<anonymous> (/var/lib/ghost/versions/5.78.0/node_modules/nodemailer-direct-transport/lib/direct-transport.js:228:30)
    at /var/lib/ghost/versions/5.78.0/node_modules/nodemailer-direct-transport/lib/direct-transport.js:350:28
    at callback (/var/lib/ghost/versions/5.78.0/node_modules/smtp-connection/lib/smtp-connection.js:374:14)
    at SMTPConnection.<anonymous> (/var/lib/ghost/versions/5.78.0/node_modules/smtp-connection/lib/smtp-connection.js:385:20)
    at SMTPConnection._actionMAIL (/var/lib/ghost/versions/5.78.0/node_modules/smtp-connection/lib/smtp-connection.js:1252:16)
    at SMTPConnection.<anonymous> (/var/lib/ghost/versions/5.78.0/node_modules/smtp-connection/lib/smtp-connection.js:759:14)
    at SMTPConnection._processResponse (/var/lib/ghost/versions/5.78.0/node_modules/smtp-connection/lib/smtp-connection.js:669:16)
    at SMTPConnection._onData (/var/lib/ghost/versions/5.78.0/node_modules/smtp-connection/lib/smtp-connection.js:493:10)
    at TLSSocket.emit (node:events:517:28)
    at TLSSocket.emit (node:domain:489:12)
    at addChunk (node:internal/streams/readable:368:12)
    at readableAddChunk (node:internal/streams/readable:341:9)
    at Readable.push (node:internal/streams/readable:278:10)
    at TLSWrap.onStreamRead (node:internal/stream_base_commons:190:23)

I’ve tried a few variations, like using secure instead of secureConnection, using false instead of true for that variable, also trying port 465 instead of 587, but no matter what the sending fails. Does anyone have any idea what’s happening here?

As far as I can tell after a quick glance, Nodemailer (the package that drives transactional emails in Ghost) does not support “sendgrid” transport out of the box, but requires an additional package.

I have had SendGrid running in a Ghost Docker installation before, but just used plain SMTP. Worked without any issues. Maybe give that a try?

Another observation, secure connection should be false for startTLS (587) since initial negotiation is plain text.

Thanks folks! After some more fiddling I was able to get it working, I think I needed to add both the mail__transport var as well as set secureConnection to false. Here’s my final list of environment variables:

environment:
      database__client: mysql
      database__connection__host: ghostdb
      database__connection__user: root
      database__connection__password: XXXXXXXXXXXX
      database__connection__database: ghost
      mail__transport: SMTP
      mail__from: system@blog.rooday.com
      mail__options__service: Sendgrid
      mail__options__host: smtp.sendgrid.net
      mail__options__port: 587
      mail__options__secureConnection: false
      mail__options__auth__user: apikey
      mail__options__auth__pass: XXXXXXXXXXXX
      url: https://blog.rooday.com
1 Like