DEV Community

jasonmills94
jasonmills94

Posted on

A Docker-Based AWS SES Smoke Test With Disposable Inboxes

Use Docker and a disposable mailbox to verify AWS SES delivery in CI before release without touching shared inboxes or leaking test mail.

Shipping an app that "sent the email" is not the same as shipping an app that delivered a usable message. In AWS stacks, the miss usually shows up late: a container points at the wrong SES region, a preview environment uses stale credentials, or the message lands with broken links after templating. A disposable email address check is a simple final guardrail, and its easy to automate when your mail sender already runs in Docker.

This is the pattern I recommend when teams are searching for temp mail com style testing, but need something cleaner for production-like CI. The goal is not to replace unit tests or the Amazon SES mailbox simulator. The goal is to prove that your real app container, with real environment wiring, can send one controlled message and that the inbox content is worth shipping.

Why this check belongs in the release path

AWS SES is strict in useful ways. If your account is still in the sandbox, you can only send to verified identities or the mailbox simulator. Even after production access, delivery problems still happen becuase the application layer and the cloud layer drift separately.

A practical smoke test catches things that mocks often miss:

  • wrong AWS_REGION or SES endpoint selection
  • missing secrets in the container runtime
  • template variables that render empty in preview builds
  • broken confirmation links caused by bad environment URLs
  • unexpected sender identity changes between staging and release

That list looks basic, but it doesnt stay basic when three services, one worker, and a release job all touch outbound email.

A small Docker pattern that keeps the test deterministic

Keep the sender in the same Docker image you deploy, but trigger a narrow email scenario from CI. For example, seed a temporary user, call the notification path once, then poll a disposable inbox API for the matching subject line.

services:
  app:
    image: ghcr.io/acme/platform-web:${GIT_SHA}
    env_file: .env.ci
    command: ["./scripts/run-smoke-email-check.sh"]
Enter fullscreen mode Exit fullscreen mode

Inside run-smoke-email-check.sh, keep the assertions boring:

set -euo pipefail

./bin/create-smoke-user
./bin/trigger-welcome-email --user smoke-ci@example.test
./bin/assert-inbox-message \
  --subject "Welcome to Acme" \
  --contains "Verify your email" \
  --timeout 45
Enter fullscreen mode Exit fullscreen mode

The container should send through the same AWS configuration your app normally uses. Your inbox assertion step should verify more than "message exists". Check the subject, one critical body string, and one generated link. If youre testing a multilingual product, assert the locale too.

One more rule: isolate each run with a fresh inbox token or address alias. Teams that reuse a shared mailbox spend time filtering old messages instead of validating the current release. If someone on your team keeps googling fake e mail com options, this is probably the operational problem they are trying to solve.

What to assert in CI

For a release gate, I would keep the checklist small:

  1. the app container can authenticate to AWS SES
  2. the expected email event is triggered by the real code path
  3. one disposable inbox receives the message within a fixed timeout
  4. the rendered body includes the expected CTA and environment-specific URL
  5. no fallback template or debug text leaks into the message

A disposable inbox is especially useful when preview environments are short-lived. You dont need to provision a long-term mailbox, and you avoid mixing test mail from parallel branches. That makes failures easier to reason about during incident review, which matters more than people admit.

If you already run Kubernetes alert mailbox checks, the same habit applies here: validate the full path, not just the event trigger. Email bugs often hide in the last mile.

Where this fits with other cloud delivery checks

I would not make this your only mail test. It fits between fast application tests and broader operational checks:

  • unit tests verify template branches and serializer logic
  • integration tests verify the notification workflow
  • this Docker smoke test verifies live AWS wiring and final rendering
  • post-deploy checks verify alarms, retries, and observability

That last layer is where quiet alarm email validation complements the smoke test. One proves a product email can ship correctly; the other proves your operational email path still works when the system gets noisy.

The tradeoff is small added runtime in CI and one more secret boundary to manage. Still, the cost is usually worth it if email is part of signup, password reset, billing, or incident response. A broken email step rarely looks dramatic in logs, so a cheap release check saves time later and thats usually enough reason.

Q&A

Should I use the SES mailbox simulator instead of a disposable inbox?

Use both for different jobs. The SES mailbox simulator is great for AWS-level behavior and bounce or complaint scenarios. A disposable inbox is better when you need to inspect the final rendered message that a user-like mailbox would receive.

How long should the pipeline wait for the email?

Keep it short and explicit, usually 30 to 60 seconds. If you need much longer, the issue may be queueing, retries, or environment drift rather then a slow inbox.

Does this work only for welcome emails?

No. It also fits password reset, magic link, invoice, and approval workflows. Start with the message type that would hurt most if it silently failed in production.

What is the biggest mistake in these checks?

Treating "HTTP 200 from the send endpoint" as enough. The useful signal comes from confirming the message arrived with the right content, links, and sender configuration.

Top comments (0)