Skip to main contentSkip to navigation
[email protected]
Client AreaSupport
Hosting Mammoth
HostingMammothYour Data, Our Responsibility
Home
Solutions
Hosting Services
Store
Pricing
About
Blog
API
Contact

Stay Ahead of the Curve

Get the latest insights on cybersecurity, AI innovations, and enterprise data solutions delivered to your inbox.

Hosting Mammoth
HostingMammothEnterprise Solutions

Enterprise-grade data solutions. Hosting, recovery, cybersecurity, and AI-powered services for businesses worldwide.

[email protected]
Sun - Fri, 9:00am - 5:00pm

Services

  • Cloud Hosting
  • Data Recovery
  • Cybersecurity
  • Legal Support
  • MSP Services
  • Web Development
  • AI Services
  • Free Server Migration

Hosting

  • VPS Hosting (NVMe SSD)
  • VDS Hosting (NVMe)
  • Storage VPS (High SSD)
  • GPU Servers
  • Managed Services
  • Cloud Firewall
  • Load Balancer
  • One-Click Apps
  • n8n Hosting
  • Object Storage
  • FAQ

Company

  • Store
  • Pricing
  • About Us
  • Locations
  • Blog
  • Testimonials
  • Contact
  • Affiliate Program
  • White-Label
  • Terms of Service
  • Privacy Policy
  • Browser Cookies
  • SLA

Support

  • Client Area
  • Submit Ticket
  • Knowledge Base
  • Server Status
  • API Documentation

© 2026 Hosting Mammoth. All rights reserved.

Knowledge Base
Getting StartedAccount ManagementVPS HostingGPU ServersStorage VPSCloud FirewallLoad BalancerServer ManagementBilling & PaymentsSupport & TicketsAffiliate ProgramReseller ProgramMarketplace & Appsn8n HostingManaged ServicesServer MigrationAPI & DevelopersSecurityTroubleshootingGlossaryInstall Guides
  1. Home
  2. /
  3. Support
  4. /
  5. Install Guides
  6. /
  7. How To Install Powerdns Ubuntu
GUIDEInstall Guides

How to Install PowerDNS on Ubuntu 24.04 VPS — Authoritative DNS with MySQL Backend

26 min read

How to Install PowerDNS on Ubuntu 24.04 VPS — Authoritative DNS with MySQL Backend

Running your own authoritative DNS server is one of the highest-leverage things a hosting operator, SaaS provider, or serious homelab builder can do. You stop depending on Cloudflare or Route 53 for zone control, you get a real API for provisioning, and you can serve signed records at latencies your upstream registrar cannot match. This guide walks you through a production-grade install of PowerDNS Authoritative Server on an Ubuntu 24.04 VPS with a MariaDB backend, the PowerDNS-Admin web UI for zone management, full DNSSEC, and an optional Recursor deployment.

Prefer a managed alternative? Every CloudCore VPS comes with free DNS hosting via our managed anycast network. If you want total control, keep reading — this guide gets you there in about 45 minutes.

Table of Contents

  • What is PowerDNS?
  • Why Self-Host PowerDNS?
  • Prerequisites
  • Step 1: Update System Packages
  • Step 2: Install and Secure MariaDB
  • Step 3: Create the PowerDNS Database
  • Step 4: Install PowerDNS Authoritative Server
  • Step 5: Load the MySQL Schema
  • Step 6: Configure the MySQL Backend
  • Step 7: Verify PowerDNS Is Running
  • Step 8: Create Your First Zone
  • Step 9: Install PowerDNS-Admin Web UI
  • Step 10: Enable DNSSEC
  • Step 11: Install PowerDNS Recursor (Optional)
  • Step 12: Harden the Firewall
  • Performance and Tuning
  • Troubleshooting
  • FAQ
  • Next Steps
  • What is PowerDNS?

    PowerDNS is an open-source DNS suite developed by PowerDNS.COM BV (now part of Open-Xchange). It ships as three primary daemons: the Authoritative Server (pdns_server), which answers queries for zones you own; the Recursor (pdns_recursor), a standalone recursive resolver; and dnsdist, a DNS-aware load balancer. The Authoritative Server is the piece most people mean when they say "PowerDNS" and the focus of this tutorial.

    What sets PowerDNS apart from BIND and NSD is its backend architecture. Instead of reading zones from flat text files, PowerDNS pulls records from a pluggable backend — MySQL, PostgreSQL, SQLite, LDAP, LMDB, or a remote HTTP API. That decision makes PowerDNS a natural fit for hosting control panels, multi-tenant platforms, and any environment where zones need to change programmatically without SIGHUPs or zone reloads.

    The full documentation at doc.powerdns.com is the authoritative (pun intended) reference. It covers every configuration directive, every backend, and every pdnsutil subcommand in detail — bookmark it.

    PowerDNS is used in production by hyperscale operators including large European ISPs, hosting providers serving millions of zones, and CDN companies that need a scriptable DNS plane. It speaks native DNSSEC, supports zone transfers (AXFR/IXFR), publishes Prometheus metrics out of the box, and exposes a JSON REST API that is first-class — not an afterthought.

    Why Self-Host PowerDNS?

    Running your own authoritative DNS instead of renting it from a SaaS provider offers concrete advantages:

    • Full API access — Every zone, record, and DNSSEC key is manageable via a versioned HTTP API. You can wire DNS into your provisioning pipeline, Terraform modules, or customer control panel.
    • Programmable backends — Store zones in the same database as your application. Join DNS records to tenants, products, or customers with a foreign key.
    • Unlimited zones and records — No per-zone fees, no per-query overage, no "enterprise plan" gate for the features that matter.
    • Real DNSSEC — PowerDNS has excellent DNSSEC support including NSEC3, automatic key rollover, and online signing. One command secures a zone.
    • Anycast-ready — Run identical instances in multiple regions behind BGP anycast, or use hidden-primary/visible-secondary topologies for high availability.
    • Privacy and compliance — Query logs, zone data, and customer metadata stay on your infrastructure. GDPR and data-residency requirements become trivial.
    • Integration with your stack — PowerDNS pairs naturally with MariaDB for storage, ships metrics to Prometheus, and plugs into web UIs like PowerDNS-Admin.

    Cost and Control Comparison

    ScenarioCloudflare DNS (Free/Paid)Route 53Self-Hosted PowerDNS (CloudCore Starter)
    Monthly costFree / USD 5+ per domain (Enterprise)USD 0.50/zone + query feesEUR 7.99/mo flat
    Zones includedFree tier limitsPay per zoneUnlimited
    Query chargesNone (free), tiered (paid)Yes (USD 0.40/million)None
    Full APIYes (rate-limited)YesYes (yours, no limits)
    DNSSECYesYesYes
    Custom record typesLimitedLimitedAny RFC type
    Vendor lock-inYesYesNone
    Data residencyGlobalAWS regionsYour VPS region
    For any operator managing more than 20-30 zones programmatically, a single Starter VPS running PowerDNS pays for itself inside the first month.

    Prerequisites

    Before you begin, make sure you have:

    • A VPS running Ubuntu 24.04 LTS with root or sudo access
    • SSH access to your server
    • A registered domain with the ability to set glue records at your registrar (for example, ns1.example.com -> your.vps.ip)
    • Two public IP addresses if you want the textbook two-nameserver setup (you can also run primary on this VPS and a secondary on a second VPS)
    • Ports 53 UDP and 53 TCP reachable from the public internet
    • At least 2 GB of RAM (4 GB recommended if you also run PowerDNS-Admin)
    Recommended Plan: CloudCore Starter
    >
    For typical authoritative DNS hosting (up to several thousand zones with PowerDNS-Admin running alongside), we recommend the CloudCore Starter plan:
    >
    - 2 vCPU cores
    - 4 GB RAM
    - 50 GB NVMe SSD
    - Unmetered bandwidth
    - EUR 7.99/month
    >
    If you are running two nameservers for redundancy (strongly recommended), spin up two Starter instances in different regions. For very large deployments (100k+ zones, high QPS, anycast), step up to the Professional or Enterprise tier.

    Connect to your server via SSH:

    bash
    ssh root@your-server-ip

    Step 1: Update System Packages

    Start by updating your package index and upgrading installed packages. This ensures you have the latest security patches before introducing a service that will be exposed on a well-known port.

    bash
    sudo apt update && sudo apt upgrade -y

    Expected output (abbreviated):

    text
    Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
    Hit:2 http://archive.ubuntu.com/ubuntu noble-updates InRelease
    Reading package lists... Done
    Building dependency tree... Done
    Calculating upgrade... Done
    0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

    If the kernel was upgraded, reboot before continuing:

    bash
    sudo reboot

    Also disable and remove systemd-resolved's stub listener, which occupies port 53 by default on Ubuntu and will conflict with PowerDNS:

    bash
    sudo systemctl disable --now systemd-resolved
    sudo rm /etc/resolv.conf
    echo "nameserver 1.1.1.1
    nameserver 9.9.9.9" | sudo tee /etc/resolv.conf

    This points the server's own DNS resolution at public resolvers so that apt and similar tools continue to work while PowerDNS takes ownership of port 53.

    Step 2: Install and Secure MariaDB

    PowerDNS supports several backends, but MariaDB (a drop-in MySQL fork) is the most common choice and the one we will use here. If you want deeper treatment of MariaDB itself, see our dedicated MariaDB install guide.

    Install MariaDB server and client:

    bash
    sudo apt install -y mariadb-server mariadb-client

    Start and enable the service:

    bash
    sudo systemctl enable --now mariadb

    Run the interactive hardening script to set a root password, remove the anonymous user, disable remote root login, and drop the test database:

    bash
    sudo mysql_secure_installation

    Accept the defaults (Y) for everything except when it asks to switch to unix_socket authentication — your choice depends on preference. Set a strong root password when prompted.

    Verify MariaDB is running:

    bash
    sudo systemctl status mariadb

    Expected output:

    text
    ● mariadb.service - MariaDB 10.11 database server
         Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; preset: enabled)
         Active: active (running) since Wed 2026-04-16 10:05:22 UTC; 30s ago

    Step 3: Create the PowerDNS Database

    Log into MariaDB as root:

    bash
    sudo mysql -u root -p

    Create a dedicated database and user for PowerDNS. Replace CHANGE_THIS_STRONG_PASSWORD with a real random password.

    sql
    CREATE DATABASE pdns CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    CREATE USER 'pdns'@'localhost' IDENTIFIED BY 'CHANGE_THIS_STRONG_PASSWORD';
    GRANT ALL PRIVILEGES ON pdns.* TO 'pdns'@'localhost';
    FLUSH PRIVILEGES;
    EXIT;

    Keep the password — you will need it in the PowerDNS configuration file a few steps from now.

    Step 4: Install PowerDNS Authoritative Server

    Ubuntu 24.04 ships PowerDNS 4.9 in the main repositories, which is modern enough for production use. If you need the absolute latest (4.10+), the PowerDNS project publishes its own repository at repo.powerdns.com — for most deployments, the distro package is the right call.

    Install the authoritative server and the MySQL backend module:

    bash
    sudo apt install -y pdns-server pdns-backend-mysql

    The post-install script will start pdns.service immediately and it will fail because we have not yet configured the backend. That is expected — stop it so the next steps can proceed cleanly:

    bash
    sudo systemctl stop pdns

    Step 5: Load the MySQL Schema

    PowerDNS ships its MySQL schema as a SQL file. Locate and load it:

    bash
    sudo mysql -u root -p pdns < /usr/share/pdns-backend-mysql/schema/schema.mysql.sql

    If the path is different on your system, find it with:

    bash
    dpkg -L pdns-backend-mysql | grep schema

    Verify the tables were created:

    bash
    sudo mysql -u root -p -e "USE pdns; SHOW TABLES;"

    Expected output:

    text
    +------------------+
    | Tables_in_pdns   |
    +------------------+
    | comments         |
    | cryptokeys       |
    | domainmetadata   |
    | domains          |
    | records          |
    | supermasters     |
    | tsigkeys         |
    +------------------+

    Seven tables — the schema is loaded.

    Step 6: Configure the MySQL Backend

    Ubuntu's PowerDNS package reads fragment configuration files from /etc/powerdns/pdns.d/. The MySQL backend file is already there as pdns.local.gmysql.conf — open and edit it:

    bash
    sudo nano /etc/powerdns/pdns.d/pdns.local.gmysql.conf

    Replace the contents with:

    ini
    # MySQL/MariaDB Backend Configuration
    launch+=gmysql
    gmysql-host=127.0.0.1
    gmysql-port=3306
    gmysql-dbname=pdns
    gmysql-user=pdns
    gmysql-password=CHANGE_THIS_STRONG_PASSWORD
    gmysql-dnssec=yes

    Use the same password you set in Step 3.

    Also edit the main configuration file to enable the HTTP API (which PowerDNS-Admin will use) and set the API key:

    bash
    sudo nano /etc/powerdns/pdns.conf

    Find or add the following lines:

    ini
    # Listen on all interfaces
    local-address=0.0.0.0

    Enable the HTTP API on localhost

    api=yes api-key=CHANGE_THIS_TO_A_LONG_RANDOM_STRING webserver=yes webserver-address=127.0.0.1 webserver-port=8081 webserver-allow-from=127.0.0.1

    Basic security/robustness

    disable-axfr=no allow-axfr-ips=127.0.0.1

    Default SOA parameters for new zones

    default-soa-content=ns1.@ hostmaster.@ 0 10800 3600 604800 3600

    Generate a strong API key (for example with openssl rand -hex 32) and paste it in place of CHANGE_THIS_TO_A_LONG_RANDOM_STRING.

    Lock down the config file permissions — it now contains database and API credentials:

    bash
    sudo chmod 640 /etc/powerdns/pdns.conf /etc/powerdns/pdns.d/pdns.local.gmysql.conf
    sudo chown root:pdns /etc/powerdns/pdns.conf /etc/powerdns/pdns.d/pdns.local.gmysql.conf

    Start PowerDNS:

    bash
    sudo systemctl enable --now pdns

    Step 7: Verify PowerDNS Is Running

    Confirm the service is active:

    bash
    sudo systemctl status pdns

    Expected output:

    text
    ● pdns.service - PowerDNS Authoritative Server
         Loaded: loaded (/lib/systemd/system/pdns.service; enabled; preset: enabled)
         Active: active (running) since Wed 2026-04-16 10:20:14 UTC; 10s ago

    Check that it is actually listening on port 53:

    bash
    sudo ss -tulpn | grep pdns

    Expected output:

    text
    udp   UNCONN  0       0                    0.0.0.0:53         0.0.0.0:*   users:(("pdns_server",pid=1547,fd=5))
    tcp   LISTEN  0       128                  0.0.0.0:53         0.0.0.0:*   users:(("pdns_server",pid=1547,fd=6))
    tcp   LISTEN  0       128                127.0.0.1:8081       0.0.0.0:*   users:(("pdns_server",pid=1547,fd=8))

    Test the API from localhost:

    bash
    curl -H 'X-API-Key: YOUR_API_KEY' http://127.0.0.1:8081/api/v1/servers

    Expected output (JSON):

    json
    [{"type":"Server","id":"localhost","daemon_type":"authoritative","version":"4.9.x","url":"/api/v1/servers/localhost","config_url":"/api/v1/servers/localhost/config{/config_setting}","zones_url":"/api/v1/servers/localhost/zones{/zone}"}]

    PowerDNS is running and the API is responsive.

    Step 8: Create Your First Zone

    PowerDNS ships a powerful command-line tool called pdnsutil for zone management. Create a zone:

    bash
    sudo pdnsutil create-zone example.com ns1.example.com

    Add records to it:

    bash
    sudo pdnsutil add-record example.com '' A 3600 203.0.113.10
    sudo pdnsutil add-record example.com www A 3600 203.0.113.10
    sudo pdnsutil add-record example.com '' MX 3600 '10 mail.example.com.'
    sudo pdnsutil add-record example.com mail A 3600 203.0.113.20
    sudo pdnsutil add-record example.com ns1 A 3600 203.0.113.10
    sudo pdnsutil add-record example.com ns2 A 3600 203.0.113.11

    List records in the zone to confirm:

    bash
    sudo pdnsutil list-zone example.com

    Test resolution against your own server using dig:

    bash
    dig @127.0.0.1 example.com SOA
    dig @127.0.0.1 www.example.com A

    Expected output (abbreviated):

    text
    ;; ANSWER SECTION:
    example.com.  3600  IN  SOA  ns1.example.com. hostmaster.example.com. 2026041601 10800 3600 604800 3600

    ;; ANSWER SECTION: www.example.com. 3600 IN A 203.0.113.10

    Once your registrar's glue records point ns1.example.com and ns2.example.com at your VPS IPs, external resolvers will begin answering these queries worldwide.

    Step 9: Install PowerDNS-Admin Web UI

    pdnsutil is fine for ops work, but teams benefit from a web UI. PowerDNS-Admin is a mature, open-source Flask application that talks to the PowerDNS API.

    The cleanest install path is Docker. Install Docker first:

    bash
    sudo apt install -y docker.io docker-compose-v2
    sudo systemctl enable --now docker

    Create a working directory and compose file:

    bash
    sudo mkdir -p /opt/pdns-admin
    cd /opt/pdns-admin
    sudo nano docker-compose.yml

    Paste the following (substitute strong values for the SECRET_KEY and database password):

    yaml
    services:
      pdns-admin-db:
        image: mariadb:10.11
        restart: unless-stopped
        environment:
          MARIADB_ROOT_PASSWORD: CHANGE_ROOT_PW
          MARIADB_DATABASE: pdnsadmin
          MARIADB_USER: pdnsadmin
          MARIADB_PASSWORD: CHANGE_APP_PW
        volumes:
          - ./db:/var/lib/mysql

    pdns-admin: image: powerdnsadmin/pda-legacy:latest restart: unless-stopped depends_on: - pdns-admin-db environment: SECRET_KEY: CHANGE_TO_LONG_RANDOM_STRING SQLALCHEMY_DATABASE_URI: mysql://pdnsadmin:CHANGE_APP_PW@pdns-admin-db/pdnsadmin GUNICORN_TIMEOUT: 60 GUNICORN_WORKERS: 2 ports: - "127.0.0.1:9191:80"

    Bring it up:

    bash
    sudo docker compose up -d

    The UI is now accessible at http://127.0.0.1:9191 on the VPS. For production, expose it via Nginx with TLS:

    bash
    sudo apt install -y nginx certbot python3-certbot-nginx
    bash
    sudo nano /etc/nginx/sites-available/pdns-admin
    nginx
    server {
        listen 80;
        server_name dns.example.com;

    location / { proxy_pass http://127.0.0.1:9191; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }

    bash
    sudo ln -s /etc/nginx/sites-available/pdns-admin /etc/nginx/sites-enabled/
    sudo nginx -t && sudo systemctl reload nginx
    sudo certbot --nginx -d dns.example.com

    Open https://dns.example.com in a browser. Register the first user — this account automatically becomes the administrator. Then go to Settings -> PDNS and fill in:

    • PDNS API URL: http://127.0.0.1:8081
    • PDNS VERSION: 4.9.0
    • PDNS API KEY: the API key you set in Step 6
    Click Save then Test Connection. You should see a green success banner, and your existing example.com zone will appear under Dashboard -> Zones.

    Step 10: Enable DNSSEC

    DNSSEC adds cryptographic signatures to your zone so resolvers can validate that responses have not been tampered with. PowerDNS makes this one command:

    bash
    sudo pdnsutil secure-zone example.com

    Expected output:

    text
    Securing zone with default key size
    Zone example.com secured
    Adding NSEC ordering information

    Verify the zone is signed:

    bash
    sudo pdnsutil show-zone example.com

    The output includes the DNSKEY records, the KSK (Key Signing Key), and the ZSK (Zone Signing Key). To publish the DS record at your registrar, extract it:

    bash
    sudo pdnsutil export-zone-ds example.com

    Expected output:

    text
    example.com IN DS 60485 13 2 a1b2c3d4e5f6...
    example.com IN DS 60485 13 4 1234567890abcdef...

    Copy one of these DS records (SHA-256 is line 2, the most widely accepted) into your registrar's DNSSEC configuration panel. After a short propagation delay, the chain of trust from the root zone down to your domain will be complete. Test with an online DNSSEC analyzer like dnsviz.net or dnssec-analyzer.verisignlabs.com.

    To switch an existing zone to NSEC3 (which hides the zone walk against enumeration):

    bash
    sudo pdnsutil set-nsec3 example.com '1 0 100 ABCDEF'

    Step 11: Install PowerDNS Recursor (Optional)

    The Authoritative Server does not do recursion — it only answers for zones it hosts. If you also want a recursive resolver on this VPS (for your own applications, or to offer public DNS), install the Recursor separately. Note that a proper recursive resolver like Unbound is often a better fit for that role; PowerDNS Recursor is the right call when you want a single-vendor DNS stack.

    Because both daemons want port 53, they cannot share the same IP. The pattern below binds the Recursor to 127.0.0.1 for localhost use:

    bash
    sudo apt install -y pdns-recursor
    sudo nano /etc/powerdns/recursor.conf

    Set:

    ini
    local-address=127.0.0.1
    local-port=5353
    allow-from=127.0.0.0/8
    dnssec=validate

    We use port 5353 locally to avoid any conflict with the authoritative server. Enable and start:

    bash
    sudo systemctl enable --now pdns-recursor

    Test:

    bash
    dig @127.0.0.1 -p 5353 google.com

    If you want recursion to serve clients on port 53, bind it to a second IP address on the server and adjust local-port=53.

    For ad-blocking or local DNS override use cases, consider dedicated tools instead of PowerDNS Recursor — see our guides for Pi-hole and AdGuard Home.

    Step 12: Harden the Firewall

    Allow DNS traffic on ports 53 UDP and TCP and keep everything else locked down:

    bash
    sudo ufw allow 22/tcp comment 'SSH'
    sudo ufw allow 53/tcp comment 'DNS TCP'
    sudo ufw allow 53/udp comment 'DNS UDP'
    sudo ufw allow 80/tcp comment 'HTTP (ACME)'
    sudo ufw allow 443/tcp comment 'HTTPS (PowerDNS-Admin)'
    sudo ufw --force enable
    sudo ufw status

    Do not expose port 8081 (the PowerDNS HTTP API) to the public internet — it listens on 127.0.0.1 by design. Likewise, keep 9191 (PowerDNS-Admin container) bound to localhost and reach it only through the Nginx reverse proxy with TLS.

    If you opened the Recursor on a public IP, add rate-limiting at the firewall or dnsdist layer to prevent your resolver from being used as a DDoS amplifier.

    Performance and Tuning

    A vanilla Ubuntu install of PowerDNS handles thousands of queries per second on the Starter plan without changes. For higher loads, the following tuning in /etc/powerdns/pdns.conf matters most:

    DirectiveDefaultRecommendedWhat it does
    receiver-threads12-4Threads that parse incoming queries. Match physical core count.
    distributor-threads33-8Threads that hand queries to the backend.
    query-cache-ttl2060Seconds to cache backend query results. Higher = fewer DB hits.
    cache-ttl2060Packet cache TTL for identical queries.
    max-cache-entries10000002000000+Raise on busy servers with RAM to spare.
    overload-queue-length00-25Drop queries beyond this instead of queuing during spikes.
    After editing, restart with:

    bash
    sudo systemctl restart pdns

    Enable the built-in Prometheus metrics endpoint for monitoring:

    ini
    webserver=yes
    api=yes

    Scrape http://127.0.0.1:8081/metrics from a Prometheus instance on the same server (or through an authenticated tunnel). Key metrics to graph: pdns_auth_udp_queries, pdns_auth_servfail_packets, pdns_auth_qsize_q (queue depth), and pdns_auth_cache_hit_rate.

    Database Tuning

    PowerDNS is almost always database-bound before it is CPU-bound. Two quick wins:

    • Index the records table — the Ubuntu schema already does this, but double-check with SHOW INDEX FROM records; in MariaDB.
    • Raise the query cache in my.cnf: query_cache_size=64M and innodb_buffer_pool_size=1G on a 4 GB server.
    For very large deployments (millions of records), consider the LMDB backend, which keeps everything in a memory-mapped file and eliminates the SQL round-trip entirely.

    Troubleshooting

    ProblemCauseSolution
    pdns.service fails to start with Address already in usesystemd-resolved or another service on port 53sudo systemctl disable --now systemd-resolved and confirm with sudo ss -tulpn \</td><td>grep :53
    Unable to launch backend: Unable to connect to databaseWrong password in pdns.local.gmysql.conf or MariaDB not runningTest manually: mysql -u pdns -p pdns. Fix credentials and systemctl restart pdns
    dig @127.0.0.1 example.com returns REFUSEDZone does not exist or AXFR disabledList zones: sudo pdnsutil list-all-zones. Recreate if missing.
    dig from outside returns no answerFirewall blocking 53 or NS glue not set at registrarsudo ufw status and log in to registrar to verify glue records
    PowerDNS-Admin shows "Connection refused" to APIAPI not enabled or wrong keyEnsure api=yes, webserver=yes, and the key matches. curl -H 'X-API-Key: ...' http://127.0.0.1:8081/api/v1/servers
    DNSSEC validation fails at dnsviz.netDS record not published at registrar or mismatchedRe-run pdnsutil export-zone-ds and update registrar. DNSSEC changes can take up to 48 hours to propagate.
    SERVFAIL on all queries after config changeSyntax error in pdns.confsudo pdns_server --config-check or check journalctl -u pdns -n 50
    Slow queries under loadDatabase I/O bottleneckRaise query-cache-ttl, increase innodb_buffer_pool_size in MariaDB

    Viewing Logs

    bash
    sudo journalctl -u pdns -f
    sudo journalctl -u pdns-recursor -f

    Enable query logging temporarily for debugging (noisy — do not leave on in production):

    bash
    sudo pdns_control set log-dns-queries yes

    Disable with no when done.

    FAQ

    What is the difference between PowerDNS Authoritative and PowerDNS Recursor?

    The Authoritative Server answers queries for zones you own, returning the definitive records you have configured. The Recursor resolves queries on behalf of clients by walking the public DNS hierarchy from the root servers down. They are separate binaries (pdns_server and pdns_recursor) and should never share the same port. Most deployments run only the Authoritative Server and point their own applications at a recursive resolver like Cloudflare 1.1.1.1 or a local Unbound instance.

    Do I need DNSSEC for a production PowerDNS deployment?

    DNSSEC is strongly recommended for any public-facing zone. It cryptographically signs your records to prevent DNS spoofing, cache poisoning, and on-path tampering. PowerDNS makes DNSSEC trivial with a single pdnsutil secure-zone command, and the performance overhead is negligible for modern hardware. The one catch is that your registrar must accept the resulting DS record and publish it to the parent zone to complete the chain of trust. All major registrars support this today.

    How much RAM does PowerDNS need?

    PowerDNS Authoritative Server with a MySQL backend runs comfortably in 512 MB of RAM for a few dozen zones, and 2 GB is sufficient for thousands of zones with the PowerDNS-Admin UI running in parallel. The CloudCore Starter plan (2 vCPU, 4 GB RAM) handles typical hosting provider loads without strain. For deployments serving tens of thousands of zones or high query-per-second rates, step up to 8 GB and tune the packet cache and database buffer pool aggressively.

    Can I run PowerDNS Authoritative and Recursor on the same server?

    Yes, but they must listen on different IP addresses or ports because both want UDP/TCP 53. The common pattern is to bind the Authoritative Server to the public IP on port 53 and the Recursor to 127.0.0.1 on an alternate port like 5353. A cleaner production pattern is to keep them on separate servers entirely — authoritative on your nameserver hosts, recursor close to your application servers.

    Is PowerDNS better than BIND9?

    Neither is strictly better; they solve different operator problems. PowerDNS stores zones in SQL (or LMDB, LDAP, etc.) which makes programmatic management and web UIs trivial, and its HTTP API is first-class. BIND9 uses flat zone files, is the reference implementation for DNS, and remains ubiquitous in enterprise and telco networks. For hosting platforms that need to provision thousands of zones via automation, PowerDNS is typically the easier choice. For a single corporate nameserver following traditional zone-file workflows, BIND is still an excellent choice.

    How do I add slave/secondary servers?

    On the primary, allow AXFR to the secondary's IP in pdns.conf via allow-axfr-ips=203.0.113.20 and set also-notify=203.0.113.20. On the secondary, run another PowerDNS instance with slave=yes and use pdnsutil create-slave-zone example.com 203.0.113.10 to subscribe to the primary. Zone transfers happen automatically on NOTIFY or polling interval.

    Can I import zones from BIND format?

    Yes. pdnsutil load-zone example.com /path/to/example.com.zone reads a standard BIND zone file and inserts every record into the MySQL backend. This is the fastest path for migrating away from BIND without manually re-entering records.

    Next Steps

    Now that PowerDNS is running on your VPS, here are recommended next steps to build on your setup:

    • Spin up a secondary nameserver — Two nameservers in different datacenters (or regions) is the minimum for resilience. Deploy a second CloudCore Starter, install PowerDNS in slave mode, and configure AXFR from your primary.
    • Wire PowerDNS into your provisioning pipeline — The HTTP API lets you create zones, add records, and rotate DNSSEC keys from Terraform, Ansible, or your application code. Replace manual zone creation with an API call at customer signup.
    • Enable Prometheus monitoring — Scrape the /metrics endpoint, build Grafana dashboards for QPS and cache hit rate, and alert on pdns_auth_servfail_packets spikes. Pair with a blackbox exporter probing your nameservers from external locations.
    • Deploy dnsdist in front — For anycast or multi-homed deployments, put dnsdist in front of one or more authoritative backends. It handles load balancing, query routing, rate limiting, and DoH/DoT termination.
    • Explore related DNS tooling — If you also need a caching resolver, install Unbound alongside. For DNS-level ad-blocking in your home or office network, combine PowerDNS with Pi-hole or AdGuard Home. For a traditional file-based nameserver, see our BIND9 install guide. And for serious backend tuning, the MariaDB install guide covers everything PowerDNS's storage layer benefits from.
    • Read the official docs — The PowerDNS documentation is excellent. Start with the "Authoritative Server" section and the "API" reference for everything covered here at deeper technical detail.

    Need anycast DNS without the ops burden?
    >
    Every CloudCore VPS plan includes free managed anycast DNS hosting on our global network. Point your domain's nameservers and you are done — no pdns.conf to tune, no DNSSEC keys to rotate, no secondary server to babysit.
    >
    - Unlimited zones and records
    - Automatic DNSSEC
    - Sub-20ms query latency from every major region
    - Full API with Terraform provider
    >
    Launch a CloudCore VPS — plans start at EUR 7.99/month.

    Was this article helpful?

    ← Back to Install GuidesBrowse all categories →

    Still have questions?

    Contact Support →Submit a Ticket