Skip to content

Repository files navigation

Bun Mail Server (MailHog/Mailpit-like)

Lightweight SMTP sink built with Bun. Accepts incoming mail (SMTP), stores messages in SQLite, and exposes an HTTP JSON API for inspection.

Features

  • SMTP server: EHLO/HELO, MAIL FROM, RCPT TO, DATA, RSET, NOOP, QUIT
  • SQLite storage of full RFC822 message + parsed headers
  • HTTP JSON API for listing, reading, marking read, and deleting
  • Configurable ports, size limits, and DB path

Run locally (bare metal)

bun install
bun run dev
  • SMTP: 127.0.0.1:2525
  • HTTP: 127.0.0.1:3000

Override where the DB file is written (default is ./mail.db):

DB_PATH=/absolute/path/mail.db bun run dev

Send a test email (manual SMTP)

python3 - <<'PY'
import socket, time
s=socket.socket(); s.connect(('127.0.0.1',2525))
s.recv(4096)
for line in [
  'HELO test\r\n',
  'MAIL FROM:<alice@example.com>\r\n',
  'RCPT TO:<bob@example.com>\r\n',
  'DATA\r\n',
  'Subject: Hello\r\n',
  '\r\n',
  'Body here.\r\n',
  '.\r\n',
  'QUIT\r\n']:
  s.sendall(line.encode()); time.sleep(0.05)
try: print(s.recv(4096).decode(), end='')
except: pass
s.close()
PY

List messages:

curl -s http://127.0.0.1:3000/api/messages | jq .

Environment

  • SMTP_HOST (default 127.0.0.1)
  • SMTP_PORT (default 2525)
  • HTTP_HOST (default 127.0.0.1)
  • HTTP_PORT (default 3000)
  • MAX_MESSAGE_SIZE (default 10485760)
  • DB_PATH (default mail.db)
  • CORS_ORIGIN (default *)

API

See openapi.json.

Endpoints:

  • GET /api/messages (optional ?q=...)
  • GET /api/messages/:id
  • POST /api/messages/:id/read body: { "read": true }
  • DELETE /api/messages/:id
  • DELETE /api/messages

Docker

Build and run:

docker build -t bun-mail-server .
docker run --rm \
  -p 3000:3000 -p 2525:2525 \
  -v $(pwd)/data:/data \
  -e DB_PATH=/data/mail.db \
  --name bun-mail bun-mail-server

Bind the DB to a host path (example):

sudo mkdir -p /home/homelab/databinds/mailtester
docker run --rm \
  -p 3000:3000 -p 2525:2525 \
  -v /home/homelab/databinds/mailtester:/data \
  -e DB_PATH=/data/mail.db \
  --name bun-mail bun-mail-server

ENV overrides inside container (defaults shown):

docker run --rm \
  -e SMTP_HOST=0.0.0.0 -e SMTP_PORT=2525 \
  -e HTTP_HOST=0.0.0.0 -e HTTP_PORT=3000 \
  -e DB_PATH=/data/mail.db -e MAX_MESSAGE_SIZE=10485760 \
  -p 3000:3000 -p 2525:2525 -v $(pwd)/data:/data \
  bun-mail-server

Docker Compose

services:
  mail:
    image: bun-mail-server
    container_name: bun-mail
    ports:
      - "3000:3000"
      - "2525:2525"
    environment:
      DB_PATH: /data/mail.db
    volumes:
      - ./data:/data

Plan

See plan.md.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages