Mailpit and MailDev are great when you want a local inbox for application emails. Inbucket is in the same family, but its mental model is slightly different: it behaves like disposable webmail.

Send mail to almost any address, open the matching mailbox in the browser, and inspect what your application generated.

Inbucket is an email testing service that accepts messages for arbitrary addresses and exposes them through web, REST, and POP3 interfaces.

What is Inbucket?

Inbucket is a self-hosted email testing app for developers, QA environments, and internal test stacks. Your application sends SMTP mail to Inbucket, and Inbucket stores the messages instead of delivering them to real users.

The default ports are:

  • 2500 for SMTP
  • 9000 for the web UI
  • 1100 for POP3

For host apps, configure SMTP like this:

SMTP_HOST=localhost
SMTP_PORT=2500
SMTP_SECURE=false

For apps running in the same Docker Compose network, use the service name:

SMTP_HOST=inbucket
SMTP_PORT=2500
SMTP_SECURE=false

Why Use Inbucket?

Inbucket is useful when you want local or shared disposable webmail:

  • No mailbox setup: mailboxes are created when messages arrive.
  • Any test address: send to [email protected], then open the alice mailbox.
  • Web inspection: read text, rendered HTML, raw source, and attachments.
  • REST API: query mailboxes from integration tests.
  • POP3 access: preview captured mail from desktop email clients.
  • Retention controls: automatically expire old messages and cap mailbox size.
  • No external database: HTTP, SMTP, POP3, and storage are built into the binary.

That makes it especially interesting for test environments where several people need to inspect messages without sharing a real inbox.

Tech Overview of Inbucket

Inbucket is written in Go with an Elm web UI. The compiled service bundles its own HTTP server, SMTP server, POP3 server, REST API, and storage implementation.

The Docker image uses file storage by default:

  • /config for configuration assets such as the greeting page.
  • /storage for captured message data.
  • INBUCKET_STORAGE_RETENTIONPERIOD=72h in the image defaults.
  • INBUCKET_STORAGE_MAILBOXMSGCAP=300 in the image defaults.

The flow is straightforward:

Your app -> SMTP inbucket:2500 -> Inbucket storage -> Web UI/API/POP3

Unlike MailDev and Mailpit, Inbucket’s mailbox model is front and center. With the default local mailbox naming mode, [email protected] is stored in the reader mailbox, and plus-addressing is ignored for the mailbox name.

Self-Hosting Inbucket with Docker

The Home-Lab compose file binds Inbucket to loopback, persists messages in Docker volumes, keeps the upstream retention pattern, and requires a custom cookie auth key in .env.

Home-Lab Inbucket compose reference
services:
  inbucket:
    image: inbucket/inbucket:latest
    container_name: inbucket
    restart: unless-stopped
    ports:
      - "${INBUCKET_WEB_BIND:-127.0.0.1:9000}:9000"
      - "${INBUCKET_SMTP_BIND:-127.0.0.1:2500}:2500"
      - "${INBUCKET_POP3_BIND:-127.0.0.1:1100}:1100"
    environment:
      TZ: ${TZ:-Europe/Warsaw}
      INBUCKET_LOGLEVEL: ${INBUCKET_LOGLEVEL:-info}
      INBUCKET_WEB_ADDR: 0.0.0.0:9000
      INBUCKET_SMTP_ADDR: 0.0.0.0:2500
      INBUCKET_POP3_ADDR: 0.0.0.0:1100
      INBUCKET_WEB_COOKIEAUTHKEY: ${INBUCKET_WEB_COOKIEAUTHKEY:?Set INBUCKET_WEB_COOKIEAUTHKEY in .env}
      INBUCKET_STORAGE_TYPE: file
      INBUCKET_STORAGE_PARAMS: path:/storage
      INBUCKET_STORAGE_RETENTIONPERIOD: ${INBUCKET_STORAGE_RETENTIONPERIOD:-72h}
      INBUCKET_STORAGE_MAILBOXMSGCAP: ${INBUCKET_STORAGE_MAILBOXMSGCAP:-300}
      INBUCKET_SMTP_MAXMESSAGEBYTES: ${INBUCKET_SMTP_MAXMESSAGEBYTES:-10240000}
      INBUCKET_SMTP_DISCARDDOMAINS: ${INBUCKET_SMTP_DISCARDDOMAINS:-bitbucket.local}
    volumes:
      - inbucket-config:/config
      - inbucket-storage:/storage

volumes:
  inbucket-config:
  inbucket-storage:

Create the .env file:

cp .env.sample .env

Change this value before starting:

INBUCKET_WEB_COOKIEAUTHKEY=replace-with-a-long-random-cookie-key

Then start it:

docker compose up -d

Open:

http://localhost:9000

Point a host app at:

SMTP_HOST=localhost
SMTP_PORT=2500
SMTP_SECURE=false

Or point a container in the same Compose network at:

SMTP_HOST=inbucket
SMTP_PORT=2500
SMTP_SECURE=false

Testing a Message

If the stack is running as the inbucket Compose project, send a tiny SMTP message from another container:

docker run --rm --network inbucket_default alpine:3.20 sh -c '
  apk add --no-cache busybox-extras >/dev/null &&
  {
    sleep 1;
    printf "HELO local.test\r\n";
    sleep 1;
    printf "MAIL FROM:<[email protected]>\r\n";
    sleep 1;
    printf "RCPT TO:<[email protected]>\r\n";
    sleep 1;
    printf "DATA\r\n";
    sleep 1;
    printf "Subject: Inbucket smoke test\r\n";
    printf "From: [email protected]\r\n";
    printf "To: [email protected]\r\n";
    printf "\r\n";
    printf "Hello from Docker Compose.\r\n";
    sleep 1;
    printf ".\r\n";
    sleep 1;
    printf "QUIT\r\n";
  } | nc inbucket 2500
'

Then open:

http://localhost:9000/m/reader

You can also query the REST API:

curl http://localhost:9000/api/v1/mailbox/reader

That API path is useful when a test needs to assert that a signup, reset, invitation, or transactional email exists.

Inbucket with listmonk and App Testing

Inbucket can catch local SMTP from listmonk, Rallly, Ghost, Mautic, or any app that supports custom SMTP settings.

For listmonk, use it to preview newsletter campaigns, transactional templates, unsubscribe footers, and message headers before connecting a real SMTP provider.

Inbucket does not replace your production mail delivery service. For real subscribers, switch listmonk or your app to a proper SMTP provider or supported messenger backend, then configure DNS, bounces, unsubscribe handling, and list hygiene.

Inbucket vs Mailpit vs MailDev

Tool Best fit Default SMTP Default UI Notable angle
Inbucket Disposable webmail and shared QA inboxes 2500 9000 Arbitrary mailbox names, REST, POP3
Mailpit Deeper email QA and inspection 1025 8025 HTML checks, link checks, screenshots, tagging
MailDev Developer inbox and preview flow 1025 1080 Node/TypeScript stack, responsive preview, MCP

Use Inbucket when the disposable mailbox workflow matters. Use Mailpit when you want stronger HTML/link QA. Use MailDev when you want a simple developer inbox with the modern MailDev workflow.

Safe Exposure Notes

Keep Inbucket private unless you intentionally want a shared internal test mailbox. Captured emails can contain login links, password reset URLs, invite tokens, internal hostnames, and test user data.

The compose file binds all ports to 127.0.0.1 by default. If you expose it to a LAN or reverse proxy, add the controls appropriate for your environment and avoid routing real production email into it.

Conclusion

Inbucket sits nicely beside Mailpit and MailDev. It is not trying to be a production mail server; it is a disposable test webmail service with SMTP, web, REST, POP3, storage retention, and mailbox creation built in.

For self-hosted app experiments, it gives you another clean way to answer: did the app send the email, which mailbox received it, and what did the message contain?

FAQ