Deploying a PowerDNS App
Introduction
PowerDNS is an authoritative DNS server with database backends and an HTTP API. Deploying PowerDNS with a Dockerfile on Klutch.sh gives you reproducible builds, managed secrets, and persistent storage—all configured from klutch.sh/app. This guide covers installation, repo prep, Dockerfile, environment variables, storage, a split-port deployment strategy, and sample API/DNS usage.
Prerequisites
- A Klutch.sh account (sign up)
- A GitHub repository containing your PowerDNS Dockerfile (GitHub is the only supported git source)
- External MySQL/PostgreSQL for the gmysql/gpgsql backend
- DNS domain ownership (for NS records) and a DNS client that can query via TCP on a non-standard external port
For onboarding, see the Quick Start.
Architecture and ports
- Klutch.sh supports one port per app. PowerDNS needs both DNS (TCP) and API (HTTP), so use two apps:
- DNS service: TCP traffic with internal port
5300(authoritative over TCP). Clients connect toexample-app.klutch.sh:8000externally; update resolvers to use TCP on that endpoint. UDP/53 is not available. - API/Console: HTTP traffic with internal port
8081for the REST API.
- DNS service: TCP traffic with internal port
- Set appropriate NS records to the external endpoint you expose for TCP DNS, or use the API for zone management while keeping authoritative DNS elsewhere.
Repository layout
powerdns/├── Dockerfile # Must be at repo root for auto-detection└── pdns.conf # Optional custom config, baked into the imageKeep secrets out of Git; store them in Klutch.sh environment variables.
Installation (local) and starter commands
Test locally with a database reachable on your machine:
docker build -t powerdns-local .docker run -p 5300:5300 -p 8081:8081 \ -e PDNS_GMYSQL_HOST=localhost \ -e PDNS_GMYSQL_USER=powerdns \ -e PDNS_GMYSQL_PASSWORD=changeme \ -e PDNS_GMYSQL_DBNAME=powerdns \ -e PDNS_API=yes \ -e PDNS_API_KEY=devkey \ -e PDNS_WEBSERVER_ADDRESS=0.0.0.0 \ -e PDNS_WEBSERVER_ALLOW_FROM=0.0.0.0/0 \ powerdns-localDockerfile for PowerDNS (production-ready)
Place this Dockerfile at the repo root; Klutch.sh auto-detects it.
FROM powerdns/pdns-auth-48:latest
ENV PDNS_AUTH_API_ONLY=noENV PDNS_AUTH_RECURSOR=0ENV PDNS_AUTH_DNSUPDATE=yes
EXPOSE 5300 8081CMD ["/entrypoint.sh", "--webserver-address=0.0.0.0", "--webserver-port=8081", "--local-port=5300"]Notes:
- Pin to a specific tag (e.g.,
powerdns/pdns-auth-48:4.8.4) for stability. - The command exposes TCP DNS on 5300 and the API on 8081; align these with your Klutch.sh app ports.
Environment variables (Klutch.sh)
Configure these before deploying:
PDNS_GMYSQL_HOST=<db-host>PDNS_GMYSQL_USER=<db-user>PDNS_GMYSQL_PASSWORD=<db-pass>PDNS_GMYSQL_DBNAME=<db-name>PDNS_GMYSQL_PORT=3306(or5432if using gpgsql)PDNS_API=yesPDNS_API_KEY=<secure-api-key>PDNS_WEBSERVER_ADDRESS=0.0.0.0PDNS_WEBSERVER_ALLOW_FROM=0.0.0.0/0- Optional:
PDNS_DEFAULT_TTL=300,PDNS_ALLOW_AXFR_IPS=<cidr>,PDNS_LOGLEVEL=4
If you deploy without the Dockerfile and need Nixpacks overrides:
NIXPACKS_START_CMD=/entrypoint.sh --webserver-address=0.0.0.0 --webserver-port=8081 --local-port=5300
Attach persistent volumes
Add storage in Klutch.sh (path and size only):
/var/lib/powerdns— zone data if using SQLite or local caching (optional when using remote DB)./etc/powerdns— persistent custom configs (if you mount them instead of baking into the image).
Ensure paths are writable inside the container.
Deploy PowerDNS on Klutch.sh (split-port workflow)
- Push your repository—with the Dockerfile at the root—to GitHub.
- Create the DNS app: select TCP traffic, set the internal port to
5300, add the environment variables above, and attach volumes if used. - Deploy the DNS app. Clients will query
example-app.klutch.shon external port8000via TCP; update resolvers accordingly. - Create a second app for the API: select HTTP traffic, set the internal port to
8081, and reuse the same repo and environment variables (plus volumes if needed). - Deploy the API app. Access the API at
https://example-app.klutch.shwith thePDNS_API_KEY.
Sample API usage
Create a zone:
curl -X POST https://example-app.klutch.sh/api/v1/servers/localhost/zones \ -H "X-API-Key: <PDNS_API_KEY>" \ -H "Content-Type: application/json" \ -d '{"name":"example.com.","kind":"Native","masters":[],"nameservers":["ns1.example.com."]}'Add a record:
curl -X PATCH https://example-app.klutch.sh/api/v1/servers/localhost/zones/example.com. \ -H "X-API-Key: <PDNS_API_KEY>" \ -H "Content-Type: application/json" \ -d '{"rrsets":[{"name":"www.example.com.","type":"A","ttl":300,"changetype":"REPLACE","records":[{"content":"198.51.100.10","disabled":false}]}]}'Health checks and production tips
- For the API app, use an HTTP readiness probe on
/or/api/v1/servers/localhost. - Keep DB credentials and
PDNS_API_KEYin Klutch.sh secrets; rotate regularly. - Use TCP-only DNS clients or proxy UDP→TCP outside Klutch.sh if needed.
- Pin image tags and test upgrades in staging; back up your database before changes.
- Monitor volume usage on
/var/lib/powerdns(if used) and resize proactively.
PowerDNS on Klutch.sh delivers authoritative DNS with a Dockerfile workflow, managed secrets, optional storage, and split apps for DNS and API—no extra YAML or CI required. Configure ports, attach storage, connect your database, and start serving zones over TCP.