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 run MCP_TRANSPORT=http MCP_PORT=3002 npx posthawk-mcp against 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.