Sign inSign up

simota/devcloud-mail

By simota

•Updated 3 days ago

Local SMTP mail catcher with web UI and MailHog-compatible API (ports 1025/8025), from devcloud.

Image
0

97

simota/devcloud-mail repository overview

⁠devcloud-mail

A local SMTP mail catcher with its own web UI and a MailHog-compatible HTTP API, for development and automated tests. It is the mail service of devcloud⁠, packaged as a standalone Rust binary.

It uses MailHog's ports (SMTP 1025, HTTP 8025), so in most setups you can swap the image and keep tests that call the MailHog API. It is not intended for production mail handling.

⁠Quick start

docker run --rm -p 127.0.0.1:1025:1025 -p 127.0.0.1:8025:8025 simota/devcloud-mail

Send mail to localhost:1025 and open http://localhost:8025/⁠.

For a MailHog-like empty inbox on every start, add -e DEVCLOUD_MAILBOX_EPHEMERAL=true. Without it, mail persists in the /data volume across restarts.

⁠Docker Compose
services:
  mailhog:
    image: simota/devcloud-mail:0.1.0
    environment:
      DEVCLOUD_MAILBOX_EPHEMERAL: "true"
    ports:
      - "127.0.0.1:1025:1025"
      - "127.0.0.1:8025:8025"

Other containers in the same Compose project can reach it as mailhog:1025 (SMTP) and http://mailhog:8025 (API).

⁠Web UI

  • Message list with search, paging and live updates (no reload needed)
  • HTML / plain text / source / attachments views; HTML is rendered in a sandboxed iframe (scripts never run, links open in a new tab)
  • Correct decoding of quoted-printable / base64 bodies, RFC 2047 headers, RFC 2231 file names and charsets including ISO-2022-JP, Shift_JIS and EUC-JP
  • Delete a message or clear the inbox; keyboard navigation (j/k, /, Delete); dark mode

⁠MailHog-compatible API

EndpointNotes
GET /api/v2/messages?start=&limit=Same JSON shape and paging rules (default 50, max 250)
GET /api/v2/search?kind=from|to|containing&query=Case-insensitive, on undecoded content
GET / DELETE /api/v1/messagesList (max 1000) / delete all
GET / DELETE /api/v1/messages/{id}Single message / delete
GET /api/v1/messages/{id}/download.eml download
GET /api/v1/messages/{id}/mime/part/{n}/downloadMIME part download
GET /api/v1/eventsServer-Sent Events, one message JSON per new mail

Message JSON (ID, From, To, Content, Created, MIME, Raw) matches MailHog v1.0.1; bodies and headers are returned undecoded, as MailHog does. Compatibility is checked against a real mailhog/mailhog:v1.0.1 container.

⁠Configuration

VariableDefault (image)Description
DEVCLOUD_MAILBOX_EPHEMERALunsettrue/1/yes: empty inbox on every start, nothing written to /data
DEVCLOUD_MAILBOX_STORAGE/dataStorage directory (single writer; do not share between containers)
DEVCLOUD_MAILBOX_MAX_BYTES10485760Maximum message size; 0 = unlimited
DEVCLOUD_MAILBOX_AUTH_MODErelaxedoff / relaxed / strict (HTTP Basic auth on the whole UI and API)
DEVCLOUD_MAILBOX_USERNAME / _PASSWORDemptyCredentials; both required in strict mode
DEVCLOUD_MAILBOX_ALLOWED_HOSTSemptyExtra HTTP Host names, comma-separated; * disables the check
DEVCLOUD_MAILBOX_HOSTNAMEmailhog.exampleHostname used in synthesized Received headers

Host names: localhost, IP addresses, *.localhost, host.docker.internal and single-label names such as Compose service names (mailhog, mail) are allowed by default. Dotted names such as mailhog.local or Kubernetes service DNS names need DEVCLOUD_MAILBOX_ALLOWED_HOSTS (or *); otherwise the server answers 403 with instructions.

The container runs as non-root (UID 10001). For a bind mount, make the directory writable by that UID. It stops cleanly on SIGTERM (docker stop).

⁠Differences from MailHog

  • No WebSocket (/api/v2/websocket), Jim, Release (outgoing relay), STARTTLS, MongoDB/maildir storage or MH_* variables.
  • Message IDs look like msg_…; unknown IDs return 404 (MailHog returns null / 500).
  • Mail persists by default (use DEVCLOUD_MAILBOX_EPHEMERAL=true for MailHog's behaviour).
  • SSE sends one compact data: line per message and : comments as keep-alives (equivalent for EventSource clients).
  • Safety limits: 1 MiB SMTP line, 64 concurrent SSE streams, sanitized download headers; unsafe attachment types are served as application/octet-stream.

Tag summary

Content type

Image

Digest

sha256:bf85ed4eb…

Size

27.9 MB

Last updated

3 days ago

docker pull simota/devcloud-mail