SMTP Mailcow server

I’m deploying Ghost with docker-compose as follows:

services:
  ghost:
    image: ghost:5.94.0
    container_name: ghost
    hostname: ghost
    volumes:
      - /mnt/user/appdata/ghost/content:/var/lib/ghost/content:z
    expose:
    - "3306"
    environment:
      NODE_ENV: production
      url: https://blog.my.domain
      database__client: mysql
      database__connection__host: mysql
      database__connection__user: ghostusr
      database__connection__password: ...
      database__connection__database: ghostdata
      mail__transport: SMTP
      mail__options__host: mail.my.domain
      mail__options__secure: false
      mail__options__tls__rejectUnauthorized: false
      mail__options__port: 587
      mail__options__auth__user: ghost@my.domain
      mail__options__auth__pass: ...
      mail__from: "'MyDomain Blog' <ghost@my.domain>"
    ports:
      - 8080:2368
    restart: always
    links:
      - mysql

  mysql:
    image: mysql:9.0.1
    container_name: mysql
    volumes:
       - /mnt/user/appdata/ghost/mysql:/var/lib/mysql:z  # Persist storage
    expose:
      - "3306"
    environment:
      - MYSQL_ROOT_PASSWORD=...
      - MYSQL_DATABASE=ghostdata
      - MYSQL_USER=ghostusr
      - MYSQL_PASSWORD=...
    restart: always

I’m hosting mailcow with mailcow-dockerized in a VM, where I configured the domain “my.domain”, an e-mail “ghost@my.domain”, and webmail is available through Caddy (with its correspondent SSL cert) with cloudflare (Deactivated proxying for mail).

This is the error I’m facing now (I had to set mail__options__secure: false and email__options__tls__rejectUnauthorized: false because I was getting that the certs are self-signed, which they are not):

2024-09-13 11:33:36] ERROR Failed to send email. Reason: Can't send mail - all recipients were rejected: 553 5.7.1 <noreply@blog.my.domain>: Sender address rejected: not owned by user ghost@my.domain.

Failed to send email. Reason: Can't send mail - all recipients were rejected: 553 5.7.1 <noreply@blog.my.domain>: Sender address rejected: not owned by user ghost@my.domain.

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

Error ID:
    03cc63f0-71c4-11ef-9a1d-37db0307a4bc

Error Code: 
    EENVELOPE

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

Error: Can't send mail - all recipients were rejected: 553 5.7.1 <noreply@blog.my.domain>: Sender address rejected: not owned by user ghost@my.domain
    at createMailError (/var/lib/ghost/versions/5.94.0/core/server/services/mail/GhostMailer.js:105:12)
    at SMTPConnection._formatError (/var/lib/ghost/versions/5.94.0/node_modules/nodemailer/lib/smtp-connection/index.js:807:19)
    at SMTPConnection._actionRCPT (/var/lib/ghost/versions/5.94.0/node_modules/nodemailer/lib/smtp-connection/index.js:1676:28)
    at SMTPConnection.<anonymous> (/var/lib/ghost/versions/5.94.0/node_modules/nodemailer/lib/smtp-connection/index.js:1629:30)
    at SMTPConnection._processResponse (/var/lib/ghost/versions/5.94.0/node_modules/nodemailer/lib/smtp-connection/index.js:991:20)
    at SMTPConnection._onData (/var/lib/ghost/versions/5.94.0/node_modules/nodemailer/lib/smtp-connection/index.js:772:14)
    at SMTPConnection._onSocketData (/var/lib/ghost/versions/5.94.0/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)
    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)

What am I doing wrong? What is noreply@blog.my.domain doing there? I don’t have any blog.my.domain configured at Ghost nor Mailcow. I can confirm the Mailcow mail service is up and working, as I can receive and send e-mails.

Mailcow isn’t an SMTP service, it’s a collection of containers, each with a single purpose. That design is described here:

The container it uses for sending email is Postfix.

Overall, the system seems fairly complex. To send outgoing email using that, you’ll need for your Postfix container to a expose port to receive SMTP requests from Ghost and make sure they are networked such on they can connect.

On the other side, Postfix needs to configured to send outgoing email somehow. Maybe the Mailcow does how to do that.

The simpler solution I use to use Mailgun for both bulk email and also using their SMTP interface to send out transactional emails through them as well. This is a popular, simple method for setting up SMTP with Ghost, assuming you are going to use the Newsletter+Mailgun integration.

I have a mailcow instance running for a couple of weeks now. It is a dedicated VM for mailcow only.

My ghost blog is running on another VM with all my other docker deployments.

I just switched to my smtp settings to the mailcow ones instead of mailgun, which I was using before.

I think I did nothing special other than setting up mailcow according to their documentation and that is about it.

I had to change some email in the ghost settings and of course, the smtp settings for the ghost docker compose.

I think it is now working properly. At least I get mails now about comments to my mailcow email.