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.