SPF record management application
- Python 64.2%
- TypeScript 34.7%
- CSS 0.5%
- JavaScript 0.5%
Coolify's healthcheck uses curl or wget to reach the health endpoint. Both images were missing these tools, causing the apps to fail healthchecks and show as exited:unhealthy. - Dockerfile.api: added curl to apt-get install line alongside libpq5 - Dockerfile.web: added curl install in the runtime stage Fixes: spfpletter-api and spfpletter-web exited:unhealthy on Coolify |
||
|---|---|---|
| .github | ||
| .vscode | ||
| alembic | ||
| api | ||
| app | ||
| components | ||
| config | ||
| deploy | ||
| docs | ||
| e2e | ||
| lib | ||
| public | ||
| tests | ||
| .dockerignore | ||
| .env.local.example | ||
| .gitignore | ||
| .npmrc | ||
| alembic.ini | ||
| components.json | ||
| compose.yml | ||
| eslint.config.mjs | ||
| next.config.js | ||
| package-lock.json | ||
| package.json | ||
| playwright.config.ts | ||
| postcss.config.js | ||
| pyrightconfig.json | ||
| pytest.ini | ||
| README.md | ||
| requirements.txt | ||
| tsconfig.json | ||
| vitest.config.ts | ||
| vitest.setup.ts | ||
SPF Pletter
SPF flattening and managed (hosted) SPF records. Flattens a domain's SPF to
stay under the 10-DNS-lookup limit, and can host the flattened record as a
managed TXT record (customers point an include: or redirect= at our zone),
kept current by an auto-refresh loop with snapshot history, revert, and
webhook notifications.
Stack
- Frontend — Next.js 16 (App Router) + React 19 + Tailwind 4, in
app/andcomponents/. - Backend — FastAPI + SQLModel + Alembic, in
api/. DNS via dnspython; hosted records published through the PowerDNS HTTP API. - DB — SQLite for dev (auto-created), Postgres for production
(Alembic-managed; see
docs/migrations.md).
Quickstart
Requires Node 20+, Python 3.11+, and uv.
npm install
cp .env.local.example .env.local # fill in secrets; see docs/operations.md
npm run dev # Next.js :3000 + FastAPI :8000
Then open http://localhost:3000 (try /preview for the anonymous flatten
flow) or the API docs at http://127.0.0.1:8000/api/py/docs.
Tests & checks
uv run python -m pytest -q # backend suite
npx tsc --noEmit # TS typecheck
npx eslint . # lint
Documentation
| Doc | Contents |
|---|---|
CLAUDE.md |
Architecture map, conventions, and gotchas (written for AI agents, useful for humans too) |
docs/operations.md |
Hosted-DNS env vars, auto-refresh, failure behavior |
docs/migrations.md |
Schema/deploy discipline, revision runbook |
docs/webhooks.md |
Webhook payload contract |
docs/dns-hardening.md |
PowerDNS API lockdown architecture |
docs/incident-checklist.md |
DNS publishing incident runbook |
deploy/ |
Ready-to-apply PowerDNS/nginx hardening configs |