Installation
PDNS Manager runs as a Docker Compose stack of two containers: a Python/FastAPI backend (which also serves the built React frontend) and a MariaDB. There are three ways to set it up depending on how much hand-holding you want.
Requirements
- Docker ≥ 20 with the Compose plugin (
docker composeas a subcommand, not the legacydocker-compose). - A free port 5380 on the host. Change the
ports:mapping incompose.yamlif it's already taken. - At least one running PowerDNS Authoritative server (4.x) with the HTTP API enabled – see below.
- Optional:
opensslon the host so the setup script can generate strong random secrets.
Option A · One-liner
The script clones the repo, asks a few questions, generates a complete .env with random passwords, starts the containers and waits for the healthcheck. Fastest path for 90 % of cases.
curl -sSLO https://raw.githubusercontent.com/29barra29/PowerDNS-PDNS-MANAGER/main/install.sh && bash install.sh What it does, in order:
- Checks that it's interactive (warns on
curl | bashwithout a TTY). - Asks for the UI language (German / English).
- Verifies Docker, the Compose plugin, and that port 5380 is free (fallback chain
lsof → ss → netstat). - Picks an install path (default
./pdns-manager) and clones the repo – with a tarball fallback to the latest release tag ifgitis missing. - Calls
setup.shfor the.env. docker compose up -d, then actively pollshttp://localhost:5380/health(max 120 s).
Option B · Clone & setup wizard
Same outcome as A, just without the download wrapper:
git clone https://github.com/29barra29/PowerDNS-PDNS-MANAGER.git
cd dns-manager
./setup.sh
docker compose up -d The wizard walks you through:
- App name (branding, can be changed later in the panel).
- Admin password: (1) random, (2) self-registration in the browser, (3) set manually.
- SMTP optional – host, port, user, password, sender. (Stored in
.envasMAIL_*; in production SMTP usually comes from the panel anyway, which lives in MariaDB.) - Will HTTPS sit in front later? Sets
AUTH_COOKIE_SECUREaccordingly. - First PowerDNS server optional – name, URL, API key. Can be added in the panel later.
The wizard writes .env atomically (via .env.tmp + mv, with a cleanup trap on Ctrl-C) and creates a timestamped backup beforehand.
Option C · Manual
For people who don't like wizards and want to set every variable themselves:
git clone https://github.com/29barra29/PowerDNS-PDNS-MANAGER.git
cd dns-manager
cp .env.example .env
# Mandatory: DB_ROOT_PASSWORD, DB_PASSWORD, JWT_SECRET_KEY
sed -i "s|^JWT_SECRET_KEY=.*|JWT_SECRET_KEY=$(openssl rand -hex 64)|" .env
nano .env
chmod 600 .env
docker compose up -d First login
- Browser to
http://localhost:5380(or the server's IP). -
With
ENABLE_REGISTRATION=true(the wizard default) the browser shows the setup wizard. The first user created becomes admin automatically; afterwards registration disables itself. - If no password was set, the backend generates one on first start and stores it inside the container plus once in the log:
docker compose logs backend | grep -i "initial admin"
docker compose exec backend cat /app/.initial-admin-password Enable the PowerDNS API
For the manager to talk to a PowerDNS server, its HTTP API has to be active. Minimal config in /etc/powerdns/pdns.conf:
api=yes
api-key=your-secure-api-key
webserver=yes
webserver-address=0.0.0.0
webserver-port=8081
webserver-allow-from=0.0.0.0/0 Then run systemctl restart pdns.
Add the PowerDNS server in the panel
In the panel under Settings → DNS servers → Add server:
- Name – free display name.
- URL – e.g.
http://pdns.intern:8081, or via the container networkhttp://pdns:8081. - API key – same value as in
pdns.conf. - Writable? Leave on if the manager may push changes. With multiple PowerDNS instances on the same DB, mark only one as writable; the rest are pure read replicas.
Hit Test connection, save – done. Multiple servers are fine; the zone list automatically merges duplicates.
What lives on disk?
After start there are two volumes (default location /var/lib/docker/volumes/):
mariadb_data– the entire database including users, zone permissions, settings, tokens, audit log, webhooks.backend_uploads– uploaded files (mainly the branding logo). Untouched by./update.sh.
Containers are named dns-manager-api and dns-manager-db, network dns-manager-net.
Next steps
- First steps – create your first zone, records, DNSSEC.
- Configuration (.env) – every variable explained.
- Security & hardening – reverse proxy, cookies, firewall.