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/migrations/20240101000000_initial_schema.sql` in the SQL Editor
3. Pull and run the Docker images:
```yaml
# docker-compose.yml
services:
redis:
image: redis:7-alpine
container_name: posthawk-redis
command: redis-server --requirepass ${REDIS_PASSWORD}
worker:
image: ghcr.io/endibuka/posthawk-worker:latest
container_name: posthawk-worker
ports: ["3001:3001", "587:587"]
env_file: .env
depends_on: [redis]
smtp-server:
image: ghcr.io/endibuka/posthawk-smtp-server:latest
container_name: posthawk-smtp
ports: ["25:25", "587:587"]
env_file: .env
web:
image: ghcr.io/endibuka/posthawk-web:latest
container_name: posthawk-web
ports: ["3000:3000"]
env_file: .env
```
4. Create a `.env` with Supabase keys, AWS SES creds, and Redis password
5. `docker-compose up -d`
6. Set up Nginx/Caddy in front for SSL
7. Visit `https://yourdomain.com` and sign up
The full self-hosting guide (with all env vars, DNS setup, SES warmup, troubleshooting) lives at [docker/SELF_HOSTING.md](https://github.com/endibuka/Posthawk/blob/main/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.