
This article demonstrates how to install DNSControl on Ubuntu VPS to Manage PowerDNS servers.
What is DNSControl?
DNSControl is an open-source system for managing DNS records across multiple providers using a single, version-controlled configuration.
Here’s what it does and why it’s useful:
Core Idea
Instead of manually creating and editing DNS records in each provider’s web UI, you write your DNS configuration once in a JavaScript-like file (dnsconfig.js
). DNSControl then takes that file and synchronizes your records with any supported DNS providers (e.g., Cloudflare, Route53, PowerDNS, Google Cloud DNS, DigitalOcean, etc.).
Key Features
- Multi-provider support: Works with many DNS providers. You can even use multiple providers at once (primary/secondary or split-zone setups).
- Declarative configuration: Define what your DNS should look like in code, then run
dnscontrol push
to make it so. - Version control: Since configs are just text files, you can store them in Git. This makes auditing, rollbacks, and collaboration easy.
- Consistency: Helps avoid drift and ensures your records are the same everywhere.
- Automation: Great for CI/CD pipelines—DNS changes can be tested, reviewed, and deployed like software updates.
Typical Workflow
- Install DNSControl (a Go binary).
- Write
dnsconfig.js
describing your domains, records, and providers. - Test with:
dnscontrol preview
(shows what changes would be applied).
- Apply with:
dnscontrol push
Example dnsconfig.js
var REG_NONE = NewRegistrar("none", "NONE"); var CF = NewDnsProvider("cloudflare", "CLOUDFLAREAPI"); D("example.com", REG_NONE, DnsProvider(CF), A("www", "203.0.113.42"), MX("mail", 10, "mail.example.com.") );
This snippet says:
- Registrar is “none” (just a placeholder).
- DNS hosted at Cloudflare.
- Add an A record (
www → 203.0.113.42
). - Add an MX record (
mail → mail.example.com
).
Below is a clean, repeatable setup you can run on an Ubuntu 22.04/Ubuntu 24.04 VPS to manage your PowerDNS Authoritative server via DNSControl (Stack Overflow’s “DNS as code” tool).
Prerequisites
- Ubuntu VPS with sudo access.
- A domain you can test with (e.g.,
example.com
). - PowerDNS Authoritative Server installed (we’ll install it below).
- Do all steps as a sudo-capable user.
How to Install DNSControl on Ubuntu VPS to Manage PowerDNS
To install DNSControl on Ubuntu VPS to manage PowerDNS, follow the steps below:
-
Install PowerDNS Authoritative Server (if you don’t have it yet)
PowerDNS is available via apt. Choose a backend you like (SQLite, MySQL, or PostgreSQL). For quick starts, SQLite is simplest:
sudo apt update sudo apt install -y pdns-server pdns-backend-sqlite3
PowerDNS recommends installing via apt and adding a backend package; their docs cover Debian/Ubuntu specifics.
If you prefer MySQL/MariaDB as backend:
sudo apt install -y pdns-server pdns-backend-mysql
(Several how-tos use
pdns-backend-mysql
on Ubuntu.) -
Enable the PowerDNS HTTP API
DNSControl talks to PowerDNS via its HTTP API.
Edit
/etc/powerdns/pdns.conf
and add (or uncomment) these lines:# Enable the webserver + API webserver=yes webserver-address=127.0.0.1 webserver-port=8081 api=yes api-key=CHANGE_ME_TO_A_LONG_RANDOM_VALUE
Restart PowerDNS:
sudo systemctl restart pdns sudo systemctl status pdns --no-pager
Test the API from the server:
curl -H 'X-API-Key: CHANGE_ME_TO_A_LONG_RANDOM_VALUE' \ http://127.0.0.1:8081/api/v1/servers/localhost | jq .
You should get JSON describing your PowerDNS server. (By default the server id is
localhost
.)Security tip: Keep the API bound to
127.0.0.1
. If you must access it remotely, put it behind TLS and authentication (e.g., Nginx reverse proxy) and firewall it. -
Install DNSControl
You can either use a prebuilt binary or build with Go. The Go route is quickest and always current:
- Install Go (if you don’t have it):
sudo apt install -y golang
- Install DNSControl:
# Installs the latest v4 in your $GOBIN (usually ~/go/bin) go install github.com/StackExchange/dnscontrol/v4@latest
- Make sure
dnscontrol
is on your PATH:echo 'export PATH="$HOME/go/bin:$PATH"' >> ~/.profile source ~/.profile dnscontrol version
(Official docs recommend
go install .../v4@latest
; binaries are also available on the GitHub Releases page.) - Install Go (if you don’t have it):
-
Create a DNSControl project
mkdir -p ~/dnscontrol && cd ~/dnscontrol
Create two files:
-
creds.json
This stores provider credentials. Use environment variables in
creds.json
when possible (supported by DNSControl) so you don’t commit secrets.{ "powerdns": { "TYPE": "POWERDNS", "apiKey": "$PDNS_API_KEY", "apiUrl": "http://127.0.0.1:8081", "serverName": "localhost" } }
Then export your key in the shell:
export PDNS_API_KEY='CHANGE_ME_TO_A_LONG_RANDOM_VALUE'
The provider expects API URL, API key, and server name (usually
localhost
). -
dnsconfig.js
This is your “DNS as code” file. A minimal example for
example.com
:// @ts-check var REG_NONE = NewRegistrar("none"); var DSP_PD = NewDnsProvider("powerdns"); // matches the "powerdns" key in creds.json // Tell PDNS how to create the zone (if it doesn't exist): var PDNS_METADATA = { default_ns: [ "ns1.example.com.", "ns2.example.com." ], zone_kind: "Native", // or "Master"/"Slave" dnssec_on_create: false }; D("example.com", REG_NONE, DnsProvider(DSP_PD), PDNS_METADATA, // merged as domain metadata (for PDNS zone creation) DefaultTTL("5m"), // records: A("@", "203.0.113.10"), A("www","203.0.113.10"), MX("@", 10, "mail.example.com."), TXT("@", "v=spf1 -all") );
- The PowerDNS provider supports metadata like
default_ns
,zone_kind
, anddnssec_on_create
when creating zones. (Metadata objects are merged into the domain when passed toD()
.) - The general JavaScript DSL reference is here.
- The PowerDNS provider supports metadata like
-
-
Verify credentials and config
# Verify that DNSControl can authenticate to PowerDNS: dnscontrol check-creds powerdns # Dry-run: show changes but do not apply them: dnscontrol preview --full
check-creds
does a simple provider call usingcreds.json
.preview
prints planned changes without touching DNS.
-
Push changes to PowerDNS
When the preview looks right:
dnscontrol push --full
push
applies the changes to your PowerDNS via the API. (If the zone doesn’t exist, PDNS can create it using the metadata you supplied.)
-
Confirm in PowerDNS
List zones via API:
curl -H 'X-API-Key: '"$PDNS_API_KEY" \ http://127.0.0.1:8081/api/v1/servers/localhost/zones | jq '.[].name'
(You can also script zone CRUD via the PDNS API; see
/servers/{server_id}/zones
endpoints.) -
Migrating existing zones (optional)
If you already run zones in PowerDNS (or elsewhere), you can bootstrap
dnsconfig.js
from live data:# Pull zones from a provider and output in dnsconfig.js-style: dnscontrol get-zones --format=djs powerdns - all > pulled-zones.djs
Review and merge into
dnsconfig.js
. (See “Migrating zones to DNSControl”.) -
CI/CD & production tips (optional but recommended)
- Keep
dnsconfig.js
in Git; rundnscontrol preview
on PRs andpush
on merges (GitHub Actions/Docker image are available). - Never commit real API keys; use env vars or a secret manager.
- See the official “Getting Started” for more examples and commands.
- Keep
Troubleshooting
401 Unauthorized
from curl/check-creds: Wrongapi-key
or wrong value exported inPDNS_API_KEY
. Ensure DNSControl’sapiUrl
andserverName
match your PDNS instance (localhost
is the default server id).dnscontrol
not found: Ensure~/go/bin
is in yourPATH
aftergo install
.- Zone creation didn’t happen: Ensure you included PDNS metadata (e.g.,
default_ns
,zone_kind
) with theD()
call, and re-runpreview
/push
.
Why this stack?
- DNSControl gives you “DNS as code” (versioned, reviewable changes) and a safe
preview
step before applying. - PowerDNS provides a robust authoritative DNS with a solid HTTP API that DNSControl talks to directly.
Conclusion
You now know how to install DNSControl on Ubuntu VPS to manage PowerDNS.