Directus sends password resets, user invitations and the emails your Flows produce, and by default it hands them to sendmail — which a container usually does not have. Mail is configured entirely through environment variables, so connecting it to Postwing takes a few lines and a restart.
| Setting | Value |
|---|---|
| SMTP host | smtp.postwing.app |
| Port | 587 |
| Encryption | STARTTLS (the connection is upgraded to TLS before login) |
| Username | The login of an SMTP token for your domain |
| Password | The password of that token — shown once, when the token is created |
EMAIL_TRANSPORT="smtp"
EMAIL_FROM="noreply@your-domain.com"
EMAIL_SMTP_HOST="smtp.postwing.app"
EMAIL_SMTP_PORT=587
EMAIL_SMTP_SECURE=false
EMAIL_SMTP_USER="token-login@your-domain.com"
EMAIL_SMTP_PASSWORD="your-token-password"
# Links in password reset and invite emails are built from this
PUBLIC_URL="https://cms.your-domain.com"| Variable | Value |
|---|---|
EMAIL_TRANSPORT | smtp |
EMAIL_FROM | noreply@your-domain.com — on your verified domain |
EMAIL_SMTP_HOST | smtp.postwing.app |
EMAIL_SMTP_PORT | 587 |
EMAIL_SMTP_SECURE | false for 587, true for 465 |
EMAIL_SMTP_USER | The login of an SMTP token for your domain |
EMAIL_SMTP_PASSWORD | That token's password |
EMAIL_SMTP_NAME | Optional — the hostname Directus announces in EHLO |
no-reply@example.com. Every email Directus sends — including those from Flows — uses this one address, so it must be on your verified domain for DKIM and SPF to align. The same variables in the environment block:
services:
directus:
image: directus/directus:11
environment:
PUBLIC_URL: "https://cms.your-domain.com"
EMAIL_TRANSPORT: "smtp"
EMAIL_FROM: "noreply@your-domain.com"
EMAIL_SMTP_HOST: "smtp.postwing.app"
EMAIL_SMTP_PORT: "587"
EMAIL_SMTP_SECURE: "false"
EMAIL_SMTP_USER: "token-login@your-domain.com"
EMAIL_SMTP_PASSWORD: "your-token-password" Add a Send Email operation to a Flow. It takes To, Subject, CC, BCC, Reply To and a body type — WYSIWYG, Markdown or a Liquid template from EMAIL_TEMPLATES_PATH. There is no From field: the sender is always EMAIL_FROM. For a contact form, put the visitor's address in Reply To.
Restart Directus and read the log — with EMAIL_VERIFY_SETUP on (the default) it checks the SMTP connection at startup and warns if it fails. Then use Forgot password on the sign-in page or invite a user from the User Directory, or build a Flow with a manual trigger and a Send Email operation.
| Error | Cause and fix |
|---|---|
| Nothing is sent, no SMTP errors | EMAIL_TRANSPORT is not smtp, so Directus is still using sendmail. |
| Startup warning about the email connection | Wrong host, port, EMAIL_SMTP_SECURE or credentials. |
| Connection timeout | Outbound port blocked. Use 8587 with EMAIL_SMTP_SECURE=false or 8465 with true. |
535 authentication failed | Wrong token login or password. |
| Reset or invite link is broken | PUBLIC_URL is not set to the public address. |
| Mail goes to spam or is rejected | EMAIL_FROM is still no-reply@example.com or another unverified domain. |
With environment variables, not in the Data Studio. Set EMAIL_TRANSPORT to smtp, then EMAIL_SMTP_HOST, EMAIL_SMTP_PORT, EMAIL_SMTP_USER, EMAIL_SMTP_PASSWORD and EMAIL_SMTP_SECURE, plus EMAIL_FROM for the sender, and restart Directus. Without EMAIL_TRANSPORT Directus uses sendmail.
false with port 587 — the connection is upgraded with STARTTLS before the password is sent. true with port 465, where TLS starts immediately. Leave EMAIL_SMTP_IGNORE_TLS unset: turning it on skips STARTTLS and sends the credentials in plaintext.
That is the default value of EMAIL_FROM. Set it to an address on your verified domain — mail from example.com fails DKIM and SPF and is rejected or filtered as spam.
Directus builds the links in forgot-password and invite emails from PUBLIC_URL. Set it to the address where your Directus instance is reachable from the internet.
No. The operation has To, Subject, CC, BCC, Reply To, a body type (WYSIWYG, Markdown or Template) and the body itself; the sender is always EMAIL_FROM. To answer a form submitter, put their address in Reply To rather than trying to send as them.
EMAIL_VERIFY_SETUP is on by default, so Directus checks the transport at startup and logs a warning if it cannot connect. Read the container log right after a restart.