Email Setup Issue [Zoho]

I’m setting up a new install on Ubuntu, I’m using Zoho as my email provider. I’ve got 2FA enabled for the admin account but not the noreply account, so I’m using the 2FA application password I created for the SMTP password.

I’ve got the website running behind NGINX, the emails are the only problem I’m facing currently.

Here is the output of my discourse doctor:

DISCOURSE DOCTOR Sun Nov 23 06:50:30 UTC 2025

OS: Linux node-1 6.8.0-87-generic #88-Ubuntu SMP PREEMPT_DYNAMIC Sat Oct 11 09:28:41 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux





Found containers/app.yml




==================== YML SETTINGS ====================

DISCOURSE_HOSTNAME=forums.website.co.uk

SMTP_ADDRESS=smtp.zoho.eu

DEVELOPER_EMAILS=REDACTED 

SMTP_PASSWORD=REDACTED 

SMTP_PORT=587




LETSENCRYPT_ACCOUNT_EMAIL=REDACTED 




==================== DOCKER INFO ====================

DOCKER VERSION: Docker version 29.0.2, build 8108357




DOCKER PROCESSES (docker ps -a)




CONTAINER ID   IMAGE                 COMMAND        CREATED          STATUS          PORTS                                     NAMES

706f63d5ced8   local_discourse/app   "/sbin/boot"   11 minutes ago   Up 11 minutes   0.0.0.0:9888->80/tcp, [::]:9888->80/tcp   app





Discourse container app is running





==================== PLUGINS ====================

          - git clone https://github.com/discourse/docker_manager.git




No non-official plugins detected.




See https://github.com/discourse/discourse/blob/main/lib/plugin/metadata.rb for the official list.




========================================

Discourse version at forums.website.co.uk: NOT FOUND

Discourse version at localhost: NOT FOUND





==================== MEMORY INFORMATION ====================

OS: Linux

RAM (MB): 59013




               total        used        free      shared  buff/cache   available

Mem:           56279        3618       39659         124       13752       52661

Swap:           8191           0        8191




==================== DISK SPACE CHECK ====================

---------- OS Disk Space ----------

Filesystem      Size  Used Avail Use% Mounted on

/dev/sda2       6.5T   20G  6.2T   1% /




==================== DISK INFORMATION ====================

Disk /dev/sda: 6.55 TiB, 7201260396544 bytes, 14064961712 sectors

Disk model: LOGICAL VOLUME  

Units: sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 262144 bytes / 1572864 bytes

Disklabel type: gpt

Disk identifier: F7288ACB-CABA-4C6C-8024-D51FD6F8704E




Device     Start         End     Sectors  Size Type

/dev/sda1   2048        4095        2048    1M BIOS boot

/dev/sda2   4096 14064959487 14064955392  6.5T Linux filesystem




==================== END DISK INFORMATION ====================




==================== MAIL TEST ====================

For a robust test, get an address from http://www.mail-tester.com/

Sending mail to REDACTED  . . 

Testing sending to jordan@website.co.uk using smtp.zoho.eu:587, username:admin@website.co.uk with login auth.

SMTP server connection successful.

Sending to jordan@website.co.uk…

==================================== ERROR =====================================

Sending mail failed:

EOFError: end of file reached

=================================== SOLUTION ===================================

Post this output to https://meta.discourse.org/ for assistance.

================================================================================




==================== DONE! ====================

My app.yml setup:

## this is the all-in-one, standalone Discourse Docker container template

##

## After making changes to this file, you MUST rebuild

## /var/discourse/launcher rebuild app

##

## BE *VERY* CAREFUL WHEN EDITING!

## YAML FILES ARE SUPER SUPER SENSITIVE TO MISTAKES IN WHITESPACE OR ALIGNMENT!

## visit http://www.yamllint.com/ to validate this file as needed




templates:

  - "templates/postgres.template.yml"

  - "templates/redis.template.yml"

  - "templates/web.template.yml"

  - "templates/web.ratelimited.template.yml"

  ## Uncomment these two lines if you wish to add Lets Encrypt (https)

  ## - "templates/web.ssl.template.yml"

  ## - "templates/web.letsencrypt.ssl.template.yml"




## which TCP/IP ports should this container expose?

## If you want Discourse to share a port with another webserver like Apache or nginx,

## see 
 for details

expose:

  - "9888:80"   # http

#  - "443:443" # https




params:

  db_default_text_search_config: "pg_catalog.english"




  ## Set db_shared_buffers to a max of 25% of the total memory.

  ## will be set automatically by bootstrap based on detected RAM, or you can override

  db_shared_buffers: "4096MB"




  ## can improve sorting performance, but adds memory usage per-connection

  #db_work_mem: "40MB"




  ## Which Git revision should this container use? (default: latest)

  #version: latest




env:

  LC_ALL: en_US.UTF-8

  LANG: en_US.UTF-8

  LANGUAGE: en_US.UTF-8

  # DISCOURSE_DEFAULT_LOCALE: en




  ## How many concurrent web requests are supported? Depends on memory and CPU cores.

  ## will be set automatically by bootstrap based on detected CPUs, or you can override

  UNICORN_WORKERS: 8




  ## TODO: The domain name this Discourse instance will respond to

  ## Required. Discourse will not work with a bare IP number.

  DISCOURSE_HOSTNAME: forums.website.co.uk




  ## Uncomment if you want the container to be started with the same

  ## hostname (-h option) as specified above (default "$hostname-$config")

  #DOCKER_USE_HOSTNAME: true




  ## TODO: List of comma delimited emails that will be made admin and developer

  ## on initial signup example 'user1@example.com,user2@example.com'

  DISCOURSE_DEVELOPER_EMAILS: 'blood@website.co.uk,admin@website.co.uk'




  ## TODO: Configure the mail server

  ##       (used for validation of new accounts, notifications, digests, etc.)

  ## required: hostname of the SMTP mail server used to send mail

  DISCOURSE_SMTP_ADDRESS: smtp.zoho.eu

  ## uncomment to set the port to something other than the default (25)

  DISCOURSE_SMTP_PORT: 587

  ## USER_NAME / PASSWORD required if the SMTP provider needs authentication

  ## WARNING: a '#' in the SMTP password can be misinterpreted; ensure it's inside string quotes, e.g.:

  ##   DISCOURSE_SMTP_PASSWORD: "#pass#ord"

  DISCOURSE_SMTP_USER_NAME: admin@website.co.uk

  DISCOURSE_SMTP_PASSWORD: "app-password"

  ## uncomment to enable implicit TLS at connection time, probably needed for using port 465

  DISCOURSE_SMTP_FORCE_TLS: false

  DISCOURSE_SMTP_ENABLE_START_TLS: true

  ## uncomment to set the HELO/EHLO domain, only set if required by provider

  DISCOURSE_SMTP_DOMAIN: website.co.uk

  ## the address from which notifications are sent

  DISCOURSE_NOTIFICATION_EMAIL: noreply@wesbite.co.uk

  ## uncomment to change server certificate verification

  DISCOURSE_SMTP_OPENSSL_VERIFY_MODE: none # peer|none

  ## uncomment to override the authentication method

  DISCOURSE_SMTP_AUTHENTICATION: login # plain|login|cram_md5




  ## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate

  LETSENCRYPT_ACCOUNT_EMAIL: me@example.com




  ## The http or https CDN address for this Discourse instance (configured to pull)

  ## see 
 for details

  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com




  ## The maxmind geolocation IP account ID and license key for IP address lookups

  ## see 
 for details

  #DISCOURSE_MAXMIND_ACCOUNT_ID: 123456

  #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456




## The Docker container is stateless; all data is stored in /shared

volumes:

  - volume:

      host: /var/discourse/shared/standalone

      guest: /shared

  - volume:

      host: /var/discourse/shared/standalone/log/var-log

      guest: /var/log




## Plugins go here

## see 
 for details

hooks:

  after_code:

    - exec:

        cd: $home/plugins

        cmd:

          - git clone https://github.com/discourse/docker_manager.git




## Any custom commands to run after building

run:

  - exec: echo "Beginning of custom commands"

  ## If you want to set the 'From' email address for your first registration, uncomment and change:

  ## After getting the first signup email, re-comment the line. It only needs to run once.

  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"

  - exec: echo "End of custom commands"

I’ve also tested the handshake with OpenSSL and it’s giving me the green light.

Currently unsure what the issue would be right now to why this wouldn’t be working. I have PiHole setup in front on the network though I have the same noreply email sending emails from my VaultWarden setup.

(Yeah going for another yearly install (hopefully) got further than any other attempt so far though.)

Edit:

I’ve done a fresh/clean install and I’m seeing this on start up when running “./launcher build app”:
"2220:C 23 Nov 2025 07:51:18.640 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 2220:C 23 Nov 2025 07:51:18.640 # Redis version=7.0.15, bits=64, commit=00000000, modified=0, pid=2220, just started 2220:C 23 Nov 2025 07:51:18.640 # Configuration loaded 2220:M 23 Nov 2025 07:51:18.641 * Increased maximum number of open files to 10032 (it was originally set to 1024). 2220:M 23 Nov 2025 07:51:18.641 * monotonic clock: POSIX clock_gettime 2220:M 23 Nov 2025 07:51:18.641 # Warning: Could not create server TCP listening socket *:6379: bind: Address already in use 2220:M 23 Nov 2025 07:51:18.641 # Failed listening on port 6379 (TCP), aborting. "

Any help would be greatly appreciated,
~Blood