Two things on a Coolify server send email: the apps you deploy, and Coolify itself (deployment, backup and server alerts). Both can send through Groundmail from your own domain. Apps use the API key or the SMTP relay; Coolify's notifications use the SMTP relay.
Prerequisites
- A Groundmail account with a verified sending domain. A subdomain such as
mail.yourdomain.comworks well. - For apps: an API key (
gm_…) from API keys, or an SMTP credential if the app only speaks SMTP. - For Coolify's notifications: an SMTP credential (
gmsmtp_…) from SMTP in the dashboard. The password is shown once, so copy it.
Apps you deploy
Add the API key
- In Coolify, open the application and select Environment Variables.
- Add
GROUNDMAIL_API_KEYwith your key as the value. In Developer view you can paste it as a.envline instead. - Your app only needs the key at runtime, so set Build time to Not available during build. That keeps it out of the build logs and image layers.
- Save, then Restart the app. (A Redeploy is only needed when a build-time value changes.)
Production and preview deployments have separate variable sections; add the key to each one that sends.
For a Docker Compose app, reference the variable in your compose file and Coolify lists it under Environment Variables for you to fill in. :? makes Coolify refuse to deploy while it's empty:
services:
app:
environment:
- GROUNDMAIL_API_KEY=${GROUNDMAIL_API_KEY:?}Send
Node.js
npm install groundmailimport { Groundmail } from 'groundmail'
const groundmail = new Groundmail(process.env.GROUNDMAIL_API_KEY)
await groundmail.emails.send({
from: 'App <no-reply@mail.yourdomain.com>',
to: 'user@example.com',
subject: 'Reset your password',
html: '<p>Click the link to reset your password.</p>',
})Other stacks: Python, Go, PHP, Ruby, Laravel, Rails, or POST https://api.groundmail.dev/emails from anything: see the API reference.
Apps that only speak SMTP
Self-hosted apps such as Ghost, n8n, Plausible or WordPress take SMTP settings. Put the SMTP relay settings in their environment variables:
| Setting | Value |
|---|---|
| Host | smtp.groundmail.dev |
| Port | 587 (or 2525) |
| Encryption | STARTTLS. Leave "secure", "SSL" or "implicit TLS" off: there's no port 465. |
| Username | groundmail |
| Password | Your SMTP credential (gmsmtp_…) |
| From address | An address on your verified domain |
Coolify's own notification email
Coolify emails you about deployments, backups, scheduled tasks and servers. To send those through Groundmail:
- In Coolify, open Notifications and select Email.
- Set Email service to Use team email settings.
- Fill in From name and From address (both required). The from address must be on your verified domain.
- In the SMTP server section:
| Field | Value |
|---|---|
| Host | smtp.groundmail.dev |
| Port | 587 |
| Encryption | StartTLS |
| SMTP username | groundmail |
| SMTP password | Your SMTP credential (gmsmtp_…) |
| Timeout | Leave empty, or 30 |
- Click Save changes in the SMTP server section, then set SMTP delivery to enabled and save.
- Under Notification events, pick the events you want, click Send test and enter an address you can read. The test shows up under Emails in the Groundmail dashboard with its delivery status.
Don't pick TLS/SSL: that's implicit TLS for port 465, which Groundmail doesn't offer, so the connection fails.
Several teams on one self-hosted instance? Put the same settings in Settings → Email once, send a test, then set each team's Email service to Use system-wide settings.
Troubleshooting
| Problem | Fix |
|---|---|
Connection timeout to smtp.groundmail.dev:587 |
Your server's host blocks outbound 587 (DigitalOcean and Vultr do on new accounts). Use port 2525 with the same settings, or send from apps over HTTPS with the API key. |
| TLS handshake error, or the test hangs | Encryption is set to TLS/SSL. Use StartTLS on port 587 or 2525. |
535 authentication failed |
The username must be groundmail and the password an SMTP credential, not an API key. Credentials are shown once; create a new one if you lost it. |
| Saving the email settings fails | From name and from address are both required. |
GROUNDMAIL_API_KEY is undefined in the app |
Restart the app after saving variables. Check the variable is in the production (or preview) section the deployment uses. |
550 … domain is not verified |
The from address isn't on a domain you verified under Domains. |
Related: SMTP relay · Tools with SMTP settings · Node.js SDK · Railway