Email Setup Guide
Overview
We use two email environments to keep development safe and production reliable.
| Development | Production | |
|---|---|---|
| Service | Mailpit (self-hosted) | SendGrid |
| What happens | Emails are caught in a web inbox (never sent) | Emails delivered to real recipients |
| SMTP Host | 116.203.199.125 | smtp.sendgrid.net |
| SMTP Port | 1025 | 587 |
| Auth | None needed | API key required |
Development Setup (Mailpit)
What is Mailpit?
A self-hosted email testing tool. Any email your app sends goes to Mailpit’s inbox instead of a real mailbox. No emails are actually delivered — they’re caught and displayed in a web UI.
Web UI
- URL:
http://116.203.199.125:8025 - Username:
premast - Password:
Mailpit2026!
Configure Your App
Add to your .env or .env.local:
SMTP_HOST=116.203.199.125
SMTP_PORT=1025
[email protected]Code Examples
Option 1: SMTP Transport (Recommended for dev)
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST || '116.203.199.125',
port: parseInt(process.env.SMTP_PORT || '1025'),
secure: false,
});
async function sendEmail({ to, subject, html }) {
return transporter.sendMail({
from: process.env.SMTP_FROM || '[email protected]',
to,
subject,
html,
});
}Option 2: SendGrid SDK with Dev Toggle
const sgMail = require('@sendgrid/mail');
if (process.env.NODE_ENV === 'production') {
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
}
async function sendEmail({ to, subject, html }) {
if (process.env.NODE_ENV === 'production') {
return sgMail.send({
to,
from: process.env.SMTP_FROM,
subject,
html,
});
} else {
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: parseInt(process.env.SMTP_PORT),
secure: false,
});
return transporter.sendMail({ from: process.env.SMTP_FROM, to, subject, html });
}
}What You Can Do with Mailpit
- View all emails your app sends (HTML rendered)
- Check email content, subject, from/to addresses
- Test signup flows, password resets, notifications
- Send unlimited emails — no limits, no costs
- Search through emails
- View raw email source (headers, MIME)
Production Setup (SendGrid)
Environment Variables
NODE_ENV=production
SENDGRID_API_KEY=SG.xxxxx
[email protected]How It Works
- Production apps use the SendGrid API to send real emails
- Domain
premast.comis verified (DKIM + SPF configured) - One shared API key per app — never create personal SendGrid accounts
Getting a Production API Key
- Ask Mo’men or team lead for the API key
- Add it to your production
.envonly - Never commit API keys to git
Deployment Flow
Local Development → Mailpit (no real emails)
↓
Staging / Preview → Mailpit (no real emails)
↓
Production → SendGrid (real emails delivered)In Dokploy deployment config:
- Dev/Staging apps:
SMTP_HOST=116.203.199.125+SMTP_PORT=1025 - Production apps:
SENDGRID_API_KEY=SG.xxxxx+NODE_ENV=production
Environment File Template
# === Development (default) ===
NODE_ENV=development
SMTP_HOST=116.203.199.125
SMTP_PORT=1025
[email protected]
# === Production (set in deployment platform) ===
# NODE_ENV=production
# SENDGRID_API_KEY=SG.xxxxx
# [email protected]Rules
⛔ Never create personal SendGrid accounts for testing. Use Mailpit.
⚠️ Never use SendGrid API keys in development environments.
ℹ️ Always point dev and staging environments to Mailpit.
FAQ
I need to test if emails actually arrive in Gmail/Outlook Use Mailpit first to verify content/formatting. For delivery testing, ask Mo’men for temporary SendGrid access.
My app only supports SendGrid SDK, not SMTP Add a Mailpit SMTP fallback (see code examples above). All apps should support both modes.
Can I create my own SendGrid account for testing? No. This is what caused the previous outage. Use Mailpit for all testing.
The Mailpit inbox is full of old emails Click “Delete all” in the web UI. Max 5,000 messages are stored.