A minimalist web interface for your BIND9 DNS server.
Edit zone files, manage records, and keep your self-hosted infrastructure running smoothly.
- π Zone File Editor β Edit
db.*zone files with a clean, table-based UI. No morevion the command line. - π§ Record Management β Add, edit, and delete DNS records: A, AAAA, CNAME, MX, TXT, PTR, NS, SOA.
- π Config Viewer β Browse
named.confand other BIND configuration files in read-only mode. - π Authentication β Password-protected access via environment variables. Simple, no database required.
- β»οΈ Dynamic Updates (RFC 2136) β Record edits go through nsupdate with TSIG authentication β no container restart needed, SOA serial bumps automatically.
- π DNSSEC inline-signing β Toggle per-zone DNSSEC signing with a single switch. BIND manages keys and signs automatically. View CDS/CDNSKEY/DS records to publish at your registrar.
- π Statistics Dashboard β Server counters, per-zone query statistics, memory usage, and task manager state β all served via BIND's statistics-channels API.
- π¨ Monochrome Design β Clean, distraction-free black-and-white interface that means business.
- π³ Docker Native β Ready-to-use Docker image on Docker Hub. Works with your existing BIND9 container.
Get up and running in under 2 minutes. You just need Docker.
mkdir bind-dns-gui && cd bind-dns-guimkdir -p bind/configBind starts with an empty named.conf.local β you don't need any zone files to begin. The first thing you do after logging into the GUI is click Create zone, which writes the zone file and registers it with BIND via rndc addzone. No templates to copy, no config to edit by hand.
If you're migrating from an existing BIND server, drop your db.* files into bind/config/ and add zone blocks to named.conf.local before starting the stack. BIND will load and serve them automatically β no command needed β and the GUI will list them read-only right away.
To make those zones editable through the GUI, each zone block needs:
allow-update { key "bind-gui-key"; };
If your existing blocks already say allow-update { none; }, run the one-shot migration script:
docker compose exec bind-gui node scripts/migrate-to-dynamic.mjsIt rewrites the config and runs rndc reconfig so the change takes effect without a container restart. If your existing blocks have no allow-update clause at all, add the line manually.
Use the compose.yaml from this repo as your starting point. It defines both the BIND9 server and the GUI, connected over an isolated Docker network.
Copy the example file and edit it:
cp .env.example .envThen fill in your values:
AUTH_SECRET=$(openssl rand -base64 32)
ADMIN_USERNAME=admin
ADMIN_PASSWORD=changeme-to-something-strongThis key authenticates communication between the GUI and BIND9:
docker compose run --rm bind9 tsig-keygen -a hmac-sha256 bind-gui-key > bind/config/bind-gui.keySecurity: The key file (
bind/config/bind-gui.key) is automatically excluded from Git via.gitignore.
docker compose up -dVisit http://localhost:3001 and log in with your credentials.
That's it. You now have a web UI for your DNS server.
For your network to actually use this DNS server, configure your router's DHCP settings to hand out the IP of the machine running BIND9 as the primary DNS server. Every device on your network will then resolve domains through your own server β giving you full control over DNS records, local hostnames, and ad-blocking if you choose.
Tip: Make sure the machine running BIND9 has a static IP address so it doesn't change after a router reboot.
| Topic | Description |
|---|---|
| Configuration | Environment variables, zone files, reverse proxy setup |
| Architecture | How it works, tech stack, API routes, design system |
| Security | Auth, best practices, network isolation |
| Development | Local setup, project structure, building from source |
Pre-built images are available on Docker Hub:
docker pull migsperez/bind-dns-gui:latestImages are tagged with:
latestβ latest stable releasev1.2.3β full semantic version1.2β major.minor version
- You log into the web GUI and edit your DNS records in a table-based editor.
- The GUI computes a diff between the current records and your changes.
- The diff is sent as an nsupdate (RFC 2136) transaction β a DNS UPDATE message authenticated with a shared TSIG key.
- BIND9 applies the update immediately: it journals the change, auto-bumps the SOA serial, and (with DNSSEC inline-signing) re-signs the zone.
- For creating or deleting zones, the GUI uses
rndc addzone/rndc delzoneβ no container restart needed. - No container restarts are required for any zone operation. The Docker socket is retained only as a fallback for the version display.
Your zone files remain on disk as the static source of truth; dynamic journal files (.jnl) capture incremental changes. No lock-in.
Screenshots coming soon.
Contributions are welcome! See Development for local setup instructions.
