Install and configure
The authoritative server is the pdns-server package plus a backend: the module that stores zones. PowerDNS supports zone files (the BIND backend), SQL databases and more. This lesson uses SQLite, the simplest database backend: a single file, nothing extra to run, and the full feature set, including DNSSEC and the API.
apt install pdns-server pdns-backend-sqlite3
Freshly installed, Debian's PowerDNS refuses to start: its configuration has an empty launch= line, so there's no backend to answer from. That's deliberate, but it surprises everyone the first time.
Three steps make it a working server:
- Create the database from the schema the package ships, and give it to the
pdnsuser. - Configure it with a file in
/etc/powerdns/pdns.d/, which Debian'spdns.confincludes. Keeping your settings there makes package upgrades painless. - Restart with
systemctl restart pdns, and check the log.
The configuration does more than choose the backend. It sets the address to answer on, makes this the primary (so it sends NOTIFY to secondaries), says which secondary may transfer zones, and turns on the HTTP API, listening only on 127.0.0.1. The API key is like a root password for your DNS: never expose the API beyond the hosts that need it.
root@ns1:~# cat /etc/debian_version; dpkg-query -W pdns-server pdns-backend-sqlite3; dpkg-query -W pdns-recursor 2>/dev/null; dig -v
13.7
pdns-backend-sqlite3 4.9.17-0+deb13u1
pdns-server 4.9.17-0+deb13u1
DiG 9.20.29-1~deb13u1-Debian
root@recursor:~# dpkg-query -W pdns-recursor
pdns-recursor 5.2.13-0+deb13u1- Lines 2–4: Debian 13 with PowerDNS Authoritative 4.9 and its SQLite backend…
- Line 5: …dig from BIND 9.20 for testing…
- Line 8: …and PowerDNS Recursor 5.2 on the resolver.
root@ns1:~# journalctl -u pdns --no-pager -o cat | grep -m1 -B1 "no backends"
Starting pdns.service - PowerDNS Authoritative Server...
Unable to launch, no backends configured for querying- Line 3: Debian's
pdns.confhas an emptylaunch=: no backend, so nothing to answer from.
# /etc/powerdns/pdns.d/ns1.conf: the primary authoritative server.
# Zones and records live in a SQLite database.
launch=gsqlite3
gsqlite3-database=/var/lib/powerdns/pdns.sqlite3
gsqlite3-dnssec=yes
# Answer on the server's public address.
local-address=203.0.113.53
# New zones get a real SOA: this server as primary, serial bumped on every change.
default-soa-content=ns1.example.net. hostmaster.@ 0 10800 3600 604800 3600
# This is the primary: send NOTIFY when a zone changes,
# and let the secondary (ns2) transfer zones.
primary=yes
allow-axfr-ips=203.0.113.54
# The HTTP API, reachable from this server only.
api=yes
api-key=lab-only-api-key
webserver=yes
webserver-address=127.0.0.1
webserver-port=8081
webserver-allow-from=127.0.0.1- Lines 4–6: The SQLite backend: one database file.
gsqlite3-dnssecis needed for DNSSEC (see the DNSSEC section). - Line 9: Answer on the public address only.
- Line 12: Every new zone gets a proper SOA instead of the placeholder.
@becomes the zone name. - Lines 16–17: This is the primary: it sends NOTIFY, and only ns2 may transfer zones.
- Lines 20–25: The HTTP API, on localhost only. The key is effectively a root password for your DNS.
root@ns1:~# sqlite3 /var/lib/powerdns/pdns.sqlite3 < /usr/share/pdns-backend-sqlite3/schema/schema.sqlite3.sql && chown pdns:pdns /var/lib/powerdns/pdns.sqlite3 && ls -l /var/lib/powerdns/
total 80
-rw-r--r-- 1 pdns pdns 77824 Oct 21 05:39 pdns.sqlite3
root@ns1:~# systemctl restart pdns && systemctl status pdns --no-pager | head -9
● pdns.service - PowerDNS Authoritative Server
Loaded: loaded (/usr/lib/systemd/system/pdns.service; enabled; preset: enabled)
Active: active (running) since Wed 2026-10-21 05:39:08 UTC; 3ms ago
Invocation: 46bee13e86704f21805d6e4bf599687f
Docs: man:pdns_server(1)
man:pdns_control(1)
https://doc.powerdns.com
Main PID: 295 (pdns_server)
Tasks: 11 (limit: 9562)
root@ns1:~# journalctl -u pdns --no-pager -o cat --since "-20s" | tail -6
PowerDNS comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it according to the terms of the GPL version 2.
[webserver] Listening for HTTP requests on 127.0.0.1:8081
Primary/secondary communicator launching
Creating backend connection for TCP
About to create 3 backend threads for UDP
Started pdns.service - PowerDNS Authoritative Server.- Lines 1–3: The schema from the package, into a database owned by the pdns user.
- Line 8: Running.
- Line 18: The API is listening, on localhost only.
- Line 19: The primary/secondary communicator: sends NOTIFY and handles transfers.