Self-Hosting
Run the entire Posthawk stack on your own infrastructure with the open-source Docker images. No license fees, no usage caps, no telemetry — you only pay for your own AWS SES usage.
Posthawk is fully open-source and ships as pre-built Docker images on GitHub Container Registry (GHCR). Self-hosting means:
- Unlimited everything — no monthly email caps, no domain caps, no team-member caps
- All cloud features unlocked — including Workflow Automations and Audit Logs that are Scale-only on cloud
- Pay only for AWS SES — typically $0.10 per 1,000 emails directly from AWS
- Full source code access — though most users just pull the published Docker images
- Source on GitHub — Apache 2.0 license
Quick start
1. Create a Supabase project (cloud or self-hosted Postgres)
2. Run the schema SQL from `supabase/self-host/schema.sql` in the SQL Editor
3. Clone the repo on your server (needed for the web build — see note below) and run docker compose:
git clone https://github.com/endibuka/Courier.git posthawk
cd posthawk/docker
cp .env.example .env
# edit .env with your Supabase + AWS SES creds
docker compose -f docker-compose.prod.yml up -d> Why clone instead of just pulling images? Next.js bakes NEXT_PUBLIC_* env vars (Supabase URL, anon key) into the JS bundle at *build* time. The worker + smtp-server images are pulled from GHCR; the web image is built locally against your env so it can talk to your Supabase project. First up takes ~3-5 min.
4. Set up Nginx/Caddy in front for SSL
5. Visit https://yourdomain.com and sign up — your first signup becomes the workspace owner.
The full self-hosting guide (with all env vars, DNS setup, SES warmup, troubleshooting) lives at docker/SELF_HOSTING.md in the repo.
Configuration toggles
The same codebase powers both cloud and self-hosted deployments. Key toggle:
NEXT_PUBLIC_EDITION=cloud|self-hosted— flips the UI between cloud (with billing tabs, usage limits, Stripe) and self-hosted (everything unlocked, no billing UI)EDITION=cloud|self-hosted(worker) — gates cloud-domain verification, plan-limit checks, and SES tenant management
Self-hosted users typically set both to self-hosted.
What does NOT work in self-hosted
- Stripe billing — there's nothing to bill for, all features unlocked
- Hosted MCP server at
mcp.posthawk.dev— you'd runMCP_TRANSPORT=http MCP_PORT=3002 npx posthawk-mcpagainst your own instance - Cloud-managed SES tenants — you bring your own AWS account; tenant management is no-op since you're the only customer
Everything else — every API endpoint, every dashboard feature, every SDK — works identically.
Releasing new versions
The maintainers publish new Docker images on every git tag. You'd typically pin to a specific version (ghcr.io/endibuka/posthawk-worker:v1.2.3) and bump it after testing in staging.