How-To GuidesEmail Setup

Email Setup Guide

Overview

We use two email environments to keep development safe and production reliable.

DevelopmentProduction
ServiceMailpit (self-hosted)SendGrid
What happensEmails are caught in a web inbox (never sent)Emails delivered to real recipients
SMTP Host116.203.199.125smtp.sendgrid.net
SMTP Port1025587
AuthNone neededAPI 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

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.com is verified (DKIM + SPF configured)
  • One shared API key per app — never create personal SendGrid accounts

Getting a Production API Key

  1. Ask Mo’men or team lead for the API key
  2. Add it to your production .env only
  3. 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.