Skip to content

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 to example-app.klutch.sh:8000 externally; update resolvers to use TCP on that endpoint. UDP/53 is not available.
    • API/Console: HTTP traffic with internal port 8081 for the REST API.
  • 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 image

Keep 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:

Terminal window
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-local

Dockerfile 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=no
ENV PDNS_AUTH_RECURSOR=0
ENV PDNS_AUTH_DNSUPDATE=yes
EXPOSE 5300 8081
CMD ["/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 (or 5432 if using gpgsql)
  • PDNS_API=yes
  • PDNS_API_KEY=<secure-api-key>
  • PDNS_WEBSERVER_ADDRESS=0.0.0.0
  • PDNS_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)

  1. Push your repository—with the Dockerfile at the root—to GitHub.
  2. Create the DNS app: select TCP traffic, set the internal port to 5300, add the environment variables above, and attach volumes if used.
  3. Deploy the DNS app. Clients will query example-app.klutch.sh on external port 8000 via TCP; update resolvers accordingly.
  4. 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).
  5. Deploy the API app. Access the API at https://example-app.klutch.sh with the PDNS_API_KEY.

Sample API usage

Create a zone:

Terminal window
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:

Terminal window
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_KEY in 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.