Containerized BIND DNS Server — Deploy in Minutes
Repository: https://github.com/randyoyarzabal/bindcaptain
A modern, containerized BIND DNS solution with automated record management,
auto-generated reverse PTR zones, and a clean bc.* CLI for day-to-day
operations. Suitable for homelabs, small businesses, and enterprise
environments. Runs as a Podman container, manages everything via systemd,
and integrates with your system logger for free rotation and shipping.
git clone https://github.com/randyoyarzabal/bindcaptain.git /opt/bindcaptain
cd /opt/bindcaptain
sudo ./tools/system-setup.sh # installs Podman + deps
sudo ./tools/config-setup.sh wizard # interactive zone setup
sudo ./bindcaptain.sh install # systemd service
sudo systemctl enable --now bindcaptain
dig @<your-dns-ip> SOA <your-zone> # verifyFor Ubuntu/Debian/Arch, install Podman first (sudo apt install podman
or sudo pacman -S podman), then run the same config-setup.sh,
install, and enable --now steps above.
If your server must NOTIFY external secondaries (slaves), set
BINDCAPTAIN_NETWORK_MODE=host — see docs/networking.md.
BindCaptain intentionally gitignores config/ so site-specific
zones, IPs, and secrets never land in the public repo. A common
pattern is to keep config/ under version control in a separate
private repo (e.g. an internal Gitea/GitLab) and symlink it into
place:
ln -s /opt/ops/dns/bindcaptain /opt/bindcaptain/config
# or
export BINDCAPTAIN_CONFIG_PATH=/opt/ops/dns/bindcaptainSee docs/config-tracked-separately.md for the full pattern, deploy alternatives, and the v1.2.0 fixes that make symlinked configs work cleanly with chown/chmod across reloads.
git clone https://github.com/randyoyarzabal/bindcaptain.git
cd bindcaptain
# Auto-install Podman and dependencies (RHEL/CentOS/Rocky/AlmaLinux/Fedora)
sudo ./tools/system-setup.sh
# For Ubuntu/Debian/Arch: Install Podman manually first
# Ubuntu: sudo apt install podman podman-compose buildah skopeo
# Arch: sudo pacman -S podman podman-compose buildah skopeo# Interactive wizard (recommended)
sudo ./tools/config-setup.sh wizard
# Or manual: Copy your zone files to config/yourdomain.com/# Build and run
sudo ./bindcaptain.sh build
sudo ./bindcaptain.sh run
# Test DNS resolution
dig @localhost yourdomain.comThat's it! Your DNS server is running. See Complete Documentation for advanced features.
- Podman (container runtime)
- Git (for cloning)
- Port 53 available
- Root privileges
Supported OS: RHEL 8+, CentOS 8+, Rocky Linux 8+, AlmaLinux 8+, Fedora 30+, Ubuntu, Debian, Arch Linux
BINDCAPTAIN_CONFIG_PATH- Path to your DNS configuration directory (default:./config)TZ- Timezone setting (default:UTC)
# Use custom configuration directory
BINDCAPTAIN_CONFIG_PATH=/path/to/my/dns-config sudo ./bindcaptain.sh runNeed detailed setup instructions? See System Requirements and Manual Setup Guide for comprehensive installation steps.
# Install as systemd service (one-time)
sudo ./bindcaptain.sh install
sudo ./bindcaptain.sh enable
# Service management
sudo ./bindcaptain.sh start|stop|restart|service-statusDetailed service setup? See Systemd Service Guide for complete service management instructions.
BindCaptain exposes two distinct bc.* command surfaces. Most users only ever touch the first one:
| Surface | Where it’s sourced | Primary use case | Commands |
|---|---|---|---|
Chief plugin (bc_chief-plugin.sh) |
Operator/workstation shell, via Chief — or directly on the DNS host with BC_HOST unset |
Day-to-day DNS edits (local or remote). Wraps the in-container manager over SSH, normalizes output, and supports --json. |
bc.create, bc.update, bc.delete, bc.list, bc.refresh, bc.sync_ptr, plus bc.create_cname / bc.create_txt shortcuts |
In-container manager (bindcaptain_manager.sh) |
Sourced inside the container scope (or via sudo bash -c 'source $BC_MANAGER && …') on the DNS host |
Low-level direct calls — what the Chief wrappers dispatch to under the hood. Useful for debugging or scripted host-local automation. | bc.create_record, bc.create_cname, bc.create_txt, bc.delete_record, bc.list_records |
Important:
bc.create_record/bc.delete_record/bc.list_records(the_record-suffixed names) only exist when the in-container manager is sourced. From a normal operator shell with the Chief plugin loaded, only the high-level wrappers (bc.create,bc.delete,bc.list, …) are present — verify withbc.<TAB>completion.
Recommended usage — Chief plugin wrappers (load the plugin, then run the same commands locally on the DNS host or remotely from your workstation; see Chief bc plugin):
# Add records (TYPE defaults to A; CNAME / TXT supported)
bc.create webserver.yourdomain.com 192.168.1.100
bc.create CNAME www.yourdomain.com webserver
bc.create TXT @ yourdomain.com "v=spf1 -all"
# Update / delete
bc.update webserver.yourdomain.com 192.168.1.200
bc.delete webserver.yourdomain.com
# List (machine-readable with --json)
bc.list yourdomain.com
bc.list yourdomain.com --jsonWrite operations (bc.create / bc.update) accept only A, CNAME, and TXT — anything else is rejected with Unsupported record type.
Low-level / direct-on-host (in-container manager)
These are only callable when the manager is sourced inside the container scope:
# On the DNS host, as root:
sudo bash -c 'source /opt/bindcaptain/tools/bindcaptain_manager.sh && \
bc.create_record webserver yourdomain.com 192.168.1.100'
# Or load it into your root shell for repeated use:
source /opt/bindcaptain/tools/bindcaptain_manager.sh
bc.create_record webserver yourdomain.com 192.168.1.100 # A
bc.create_cname www yourdomain.com webserver # CNAME
bc.create_txt @ yourdomain.com "v=spf1 -all" # TXT
bc.delete_record webserver.yourdomain.com [TYPE]
bc.list_records yourdomain.comTo auto-load on root login on the DNS host, add the source …/bindcaptain_manager.sh line to root’s ~/.bashrc or ~/.profile.
Advanced DNS operations? See DNS Operations Guide for comprehensive record management and zone configuration.
# Container Management
sudo ./bindcaptain.sh build|run|stop|restart|logs|status
# Service Management
sudo ./bindcaptain.sh install|uninstall|enable|disable|start|stop-service
# DNS Management — Chief plugin wrappers (operator/remote shell)
bc.create | bc.update | bc.delete | bc.list | bc.refresh | bc.sync_ptr
# DNS Management — in-container manager (sourced on the DNS host)
bc.create_record | bc.create_cname | bc.create_txt | bc.delete_record | bc.list_recordsComplete command reference? See Cheat Sheet for all available commands and examples.
To push and fetch both this GitHub repository and a separate, private Git remote (self-hosted, team, etc.), do not store that mirror’s URL in the public tree. Choose one way to point at it, then run:
export BINDCAPTAIN_GIT_MIRROR_URL='ssh://…' # or: copy local/git-mirror.url.example → local/git-mirror.url
./tools/setup-git-dual-push.shlocal/git-mirror.url(gitignored) can hold a singlessh://…orgit@…line (see local/git-mirror.url.example). If a second remote is already in your local.git/config, the script can reuse that URL.git push origingoes to both GitHub and the mirror;git fetch --allupdates both. On a deploy host that only has SSH to the private mirror, useBINDCAPTAIN_PREFER_MIRROR_FOR_PULL=1sogit pullfast-forwards from the mirror; add a GitHub deploy key (or a key forgit@github.com) sogit fetch originand the GitHub leg ofgit push originwork.
- Deploy in Minutes - 3-step setup process
- Containerized - Clean, isolated BIND installation
- Smart Management - CLI tools for DNS record management
- Secure - Modern BIND 9.16+ with security best practices
- Auto-Reverse DNS - Automatic reverse DNS generation
- Auto-Updates - Built-in git refresh functionality
- Production-Ready - Used in real production environments
- Complete Guide — Full documentation index
- Installation — Detailed setup instructions
- DNS Operations — Managing DNS records
- Networking —
BINDCAPTAIN_NETWORK_MODE(bridge vs host) and slave-NOTIFY notes - Tracking config/ separately — keep your zones in a private repo, symlinked into place
- Secondaries / NOTIFY / rndc — primary/secondary plumbing
- Troubleshooting — Common issues and solutions
- Cheat Sheet — Quick command reference
- Changelog — Release history
Issues and pull requests welcome! See our GitHub repository.
MIT License - see LICENSE for details.
BindCaptain - Navigate your DNS with confidence