Skip to content

Local Setup

Prerequisites

  • Rust 1.90+rustup update
  • Docker — for Postgres and LocalStack
  • sqlx-clicargo install sqlx-cli --no-default-features --features postgres

1. Start Services

bash
make up          # starts Postgres (port 5433) + LocalStack (port 4566)
make db-migrate  # runs SQLx migrations

This starts two containers via docker-compose.yml:

ServiceContainerPortProvides
Postgres 16mailman-postgres5433Database
LocalStackmailman-localstack4566S3, SQS, SES

TIP

make up is idempotent — it creates containers on first run, or no-ops if already running. Postgres uses port 5433 to avoid conflicts with any system Postgres on 5432.

LocalStack resources (S3 buckets, SQS queues, SES identity) are created automatically on first start by localstack/init-aws.sh.

Other commands:

bash
make down        # stop all services
make db-status   # show service status
make db-reset    # drop + recreate database + re-migrate

2. Create .env

bash
cp .env.example .env

The default .env points the AWS SDK at LocalStack and configures SQS queue URLs. See .env.example for all available settings.

3. Run the API

bash
cargo run --bin mailman-bin-api

The API is now at http://localhost:8080. Verify:

bash
curl http://localhost:8080/health
# → {"status":"ok"}

4. Run the Worker

With LocalStack running and .env configured, the worker connects to local SQS/S3/SES:

bash
cargo run --bin mailman-bin-worker

NOTE

Most API development doesn't need the worker running. It processes inbound email, outbound delivery, telemetry, and webhooks.

Running Tests

CommandWhat it runsDependencies
make testUnit + integration testsPostgres + LocalStack (started automatically)
make test-e2eBlack-box HTTP against running APICompose stack
make test-allEverythingCompose stack
bash
# Unit + integration tests (default — used by `make check`)
make test

# E2E tests (black-box HTTP against running API)
make test-e2e

# All tests
make test-all

# Run all CI checks (fmt, clippy, test, sqlx-check)
make check

# See all available targets
make

Docker Build

bash
# API image
docker build --target api -t mailman-api .

# Worker image
docker build --target worker -t mailman-worker .

# Run API container locally
docker run -p 8080:8080 \
  -e MAILMAN_DATABASE__URL=postgres://postgres:mailman@host.docker.internal:5433/mailman \
  mailman-api

The Dockerfile uses a multi-stage build with cargo-chef for dependency caching and distroless runtime images.