Your mail. Your machine.
Sendtrap Community is the MIT-licensed, self-hosted email sandbox: point your application's outgoing mail at it and every message is captured, parsed, and browsable — nothing is ever delivered. It runs on your own machine or network, with no external account and no internet access required.
What you get
Community is a single-workspace edition of Sendtrap, built on the same MIT-licensed sendtrap/core package that powers the hosted Cloud (see Open source for how the pieces fit together). The capture-and-inspect engine is identical:
- •An SMTP server that catches instead of sends — php artisan mail:smtp-server accepts SMTP (including STARTTLS) on port 1025 by default and files every message into an inbox.
- •Projects and inboxes — organise captured mail per app or environment; each inbox has its own SMTP credentials and API token.
- •A message browser — HTML/text/raw views, MIME structure, attachments, envelope and BCC capture, merge-tag detection.
- •Message checks — deliverability lint checks and HTML client compatibility scored against the caniemail dataset, fully offline from a checked-in snapshot. HTML Check has no plan gate in Community — the API surface that needs Starter+ on Cloud is simply on.
- •The full REST API — the same token-authenticated endpoints as Cloud, including wait & assert and the Mailtrap-compatible aliases. The API reference applies as-is; only the plan-gating notes don't.
- •Public share links, webhooks and auto-forwarding for individual messages.
Install (Docker)
The fastest path: one durable container carrying the web UI/API (:8080), the SMTP ingestion daemon (:1025), a queue worker and the scheduler — SQLite and all state on a single volume, nothing else to install. Images are published to GHCR and cosign-signed.
ADMIN_PASSWORD="$(openssl rand -base64 15)" && echo "admin password: ${ADMIN_PASSWORD}"
docker run -d --name sendtrap \
-p 80:8080 -p 1025:1025 \
-e APP_URL=http://localhost \
-e SENDTRAP_ADMIN_NAME="Admin" \
-e SENDTRAP_ADMIN_EMAIL="admin@example.com" \
-e SENDTRAP_ADMIN_PASSWORD="$ADMIN_PASSWORD" \
-v sendtrap-data:/data \
ghcr.io/sendtraphq/sendtrap-community:latest
# then see a first message straight away — no app wiring needed
docker exec sendtrap php artisan sendtrap:send-test
Open APP_URL, log in as the admin user, and the seeded test message is waiting in the starter inbox. The repository also ships a hardened reference docker-compose.yml (read-only rootfs, dropped capabilities) and an ephemeral CI profile (SENDTRAP_MODE=ci — zero-config, deterministic credentials, boots seeded in seconds for test jobs). See docker/README.md for the full runbook: build, run, backup/restore, upgrade, external MySQL/Postgres/Redis/S3 backends, and ready-to-copy CI job examples.
Requirements (from source)
The Docker path above needs only Docker. Running from source needs:
| Requirement | Notes |
|---|---|
| PHP 8.3+ | With the sqlite3 extension — SQLite is the default database, so there's no separate database server to run |
| Composer | Installs PHP dependencies, including sendtrap/core |
| Node.js 20+ & npm | Builds the front-end assets once — nothing Node runs in production |
Install (from source)
Clone, install dependencies, then let sendtrap:install do the rest — it runs the migrations, creates the single workspace, and creates the first owner user. It's idempotent: run it as many times as you like and it converges to exactly one workspace and one bootstrap owner.
git clone https://github.com/sendtraphq/sendtrap-community.git
cd sendtrap-community
composer install
cp .env.example .env
php artisan key:generate
# Migrations + the single workspace + the first owner user
# (prompts for name/email/password)
php artisan sendtrap:install
npm install
npm run build
php artisan serve # web UI on http://localhost:8000
php artisan mail:smtp-server # SMTP ingestion on port 1025
For scripted setups, sendtrap:install takes --name, --email, --password and --workspace flags; add --force to run non-interactively — it fails instead of prompting if an owner field is missing on a fresh install.
Then seed a first message with php artisan sendtrap:send-test (add --via-smtp to prove the full SMTP wire against the running daemon). When you're ready for real mail, point your application's outgoing mail at smtp://localhost:1025 using the credentials shown on the inbox's page in the UI, and watch messages appear.
Production notes
For anything beyond a laptop, treat it like any Laravel app: set APP_ENV=production and APP_DEBUG=false in .env, serve public/ behind a real web server, and run the SMTP server and queue worker under a process supervisor.
Prefer not to run it all by hand? The durable container image above packages the whole stack, and the same image carries an ephemeral, CI-oriented profile — see Sendtrap in CI for the ready-made job recipe.
Configuration
Everything is driven by .env — the shipped .env.example documents each block. The essentials:
| Variable | Description |
|---|---|
| SENDTRAP_SMTP_BIND | Interface the ingestion SMTP server listens on (default 0.0.0.0) |
| SENDTRAP_SMTP_PORT | Port it listens on (default 1025). This is the server your application sends mail to — not outbound mail credentials |
| SENDTRAP_INSTANCE_ALLOWED_IPS | Optional install-time allowlist for SMTP clients — comma-separated addresses or CIDR ranges, applied to the workspace by sendtrap:install and editable afterwards on the owner Settings page |
| SPAMCHECK_ENABLED | Optional external spam-check service — off by default; Community is offline-first, and the Spam tab shows a "not configured" state rather than an error |
Instance limits
There are no plans in Community — instead, every cap Cloud enforces per plan is an optional per-instance limit you set yourself. All of them are unset by default.
| Variable | Caps |
|---|---|
| SENDTRAP_SENDS_PER_MINUTE | Ingestion rate, per minute |
| SENDTRAP_SENDS_PER_MONTH | Ingestion quota, per calendar month |
| SENDTRAP_FORWARDS_PER_MONTH | Auto-forwards, per calendar month |
| SENDTRAP_EMAIL_SIZE_BYTES | Per-message size, in bytes |
| SENDTRAP_PROJECTS_LIMIT | Number of projects |
| SENDTRAP_INBOXES_LIMIT | Number of inboxes |
| SENDTRAP_USERS_LIMIT | Number of users (the bootstrap owner is exempt) |
| SENDTRAP_MESSAGES_PER_INBOX | Messages kept per inbox (oldest trimmed) |
| SENDTRAP_RETENTION_DAYS | Age-based message retention, in days (pruned daily) |
| SENDTRAP_STORAGE_BYTES | Workspace-wide storage across all messages and attachments |
| SENDTRAP_API_REQUESTS_PER_MINUTE | Token-authenticated API requests per minute (unset falls back to a 300/min ceiling) |
Storage
Raw messages and attachments live on the local disk by default. To use S3-compatible object storage instead, fill the AWS_* keys in .env (any S3-compatible endpoint works), then either set FILESYSTEM_DISK=s3 for new mail, or migrate everything that's already there:
php artisan storage:migrate-to-s3
Both the local and s3 disks are always configured (the migrate command needs both by name), so switching is a config change, not a code change.
Users & roles
There's no public registration and no social login — users are created by the installer and then by owners, on the Users page. Every user has exactly one of three roles:
| Role | Can |
|---|---|
| owner | Everything — manage users, workspace settings, projects, inboxes and mail |
| member | Manage projects, inboxes and mail — not users or workspace settings |
| viewer | Read-only — browse messages; SMTP and API credentials are never shown |
Updating
git pull
composer install
php artisan migrate
npm install && npm run build
Community pins sendtrap/core with a ^0.1 constraint. On a 0.x line, breaking changes may land in minor releases (semver 0.x semantics) — read the release notes before a minor bump.
What's Cloud-only
Community deliberately leaves out the multi-tenant layer, not the product. You don't get:
- •Teams — Community is one workspace with owner/member/viewer roles; there are no separate teams to create or switch between.
- •Billing and plans — no subscriptions, no upgrade prompts; caps are the instance limits you configure.
- •Public registration and social login — users are provisioned by owners.
- •A support team — support is public docs and the issue tracker, best-effort.
Want teams, billing-backed limits that scale without ops work, and someone else running the servers? That's the hosted Cloud — see pricing.
Rather not run it yourself?
The hosted Cloud is the same engine with teams, billing and zero ops — free to start.
Create your inboxNo credit card required