DashCaddy Documentation

Install BIND9 DNS Server

Industry-standard DNS server - powerful and flexible

Category: DNSDifficulty: AdvancedDocker image: ubuntu/bind9:latest

What is BIND9 DNS Server?

Industry-standard DNS server - powerful and flexible

BIND9 DNS Server ships as a self-contained Docker image that DashCaddy provisions with one click. DashCaddy handles the container lifecycle, DNS record, Caddy reverse-proxy entry, and HTTPS certificate so you can focus on using BIND9 DNS Server, not installing it.

Prerequisites

  • A running DashCaddy host with the dashboard accessible (default URL: https://status.sami; configurable via the dashboardHost setting in config.json).
  • You must be signed in to the dashboard with an admin session, or have an API key with admin scope (POST /api/v1/auth/keys to create one).
  • No special host paths required.
  • For HTTPS with a real certificate, Technitium DNS must be configured and the host must have port 80/443 reachable from the internet. Otherwise DashCaddy will fall back to direct-IP access or a self-signed certificate.

Install via the DashCaddy dashboard

  1. Sign in at https://status.sami (or your host's dashboard URL).
  2. Click the 📱 App Selector button on the dashboard home page.
  3. Pick BIND9 DNS Server from the DNS category.
  4. Fill in the deployment form: subdomain (default suggestion: dns2), host port (default: 953).
  5. Click Deploy. DashCaddy will pull the image, create persistent volumes, write a Caddy route, create the DNS record, and wait up to 30 seconds for the container's health check (tcp://localhost:53) to pass.
  6. When the dashboard shows the service as Running, the URL (built from your subdomain and configured TLD) is clickable. The deploy API returns a synchronous response with {success, containerId, url, message, setupInstructions} — there is no separate status-poll endpoint; the dashboard updates live.

Install via the REST API

Authenticate with an API key (or a JWT minted via POST /api/v1/auth/jwt). Send as X-API-Key: dk_... or Authorization: Bearer <jwt>.

curl -X POST https://status.sami/api/v1/apps/deploy \\ -H "X-API-Key: dk_your_api_key" \\ -H "Content-Type: application/json" \\ -d '{ "appId": "bind9", "config": { "subdomain": "dns2", "port": 953 } }'

The full body schema is in src/utilities/validate.js (Joi schema appDeploy). All config.* fields except subdomain are optional. Notable options:

  • config.port — host port (1–65535). Defaults to the template's defaultPort.
  • config.mediaPath — host directory to mount as the media library.
  • config.plexClaimToken — Plex claim token (when the upstream service needs one).
  • config.useExisting: true + existingContainerId — attach DashCaddy metadata to an already-running container instead of pulling a new image.
  • config.tailscaleOnly: true — restrict the reverse-proxy entry to your Tailscale network.
  • config.allowedIPs — array of CIDR ranges allowed past the reverse proxy.
  • config.createDns: false — skip DNS record creation (use when the subdomain already resolves).
  • config.resources{memory, cpus} limits applied to the container.

Install via the AI Intent Router (returns a structured intent)

The Intent Router returns a structured intent, not a deployed container. To deploy via AI, send natural language to:

curl -X POST https://status.sami/api/v1/ai/intent \\ -H "X-API-Key: dk_your_api_key" \\ -H "Content-Type: application/json" \\ -d '{ "message": "Deploy BIND9 DNS Server on my home host and expose it at dns2.sami" }'

The response includes intent, action, parameters, and followup — your client (or the MCP server) must then call POST /api/v1/apps/deploy with those parameters to actually provision the container.

Install via the MCP Server

For AI agents (Claude Desktop, Hermes, etc.) configure the MCP server (src/mcp/mcp-server.js) with:

DASHCADDY_URL=https://status.sami:3001  # internal API URL, may differ from dashboard URL DASHCADDY_API_KEY=dk_your_api_key

The server exposes dashcaddy_deploy_app. Note: this tool writes the Caddy route and creates the services.json entry, but it does NOT pull the Docker image or start the container. You must run docker pull ubuntu/bind9:latest and start the container yourself for the URL to actually serve traffic. For a fully-managed deployment, call POST /api/v1/apps/deploy directly from your agent.

Post-install: first-run checklist

  1. Configure zone files in /opt/bind9/config/
  2. Create named.conf.local for your .sami zone
  3. Add zone file: /opt/bind9/records/db.sami
  4. Restart container to apply changes
  5. Test with: dig @localhost sami

Volumes and persistent data

DashCaddy creates these volume mounts in the container spec:

  • /opt/bind9/config:/etc/bind
  • /opt/bind9/cache:/var/cache/bind
  • /opt/bind9/records:/var/lib/bind

All paths are host paths (left side) mapped into the container (right side). Restarting the container preserves data; reinstalling the template preserves it unless you explicitly pass config.useExisting: false AND wipe the volume. Bind mounts use the host-path conventions above (e.g. /opt/plex/config becomes a bind mount to the host directory of the same path).

Environment variables

  • BIND9_USER
  • TZ

These are baked into the template at deploy time and shipped to the container. The deploy handler does NOT allow overriding them via the API payload — to change them you must edit the template definition in dashcaddy-api/src/docker/app-templates.js.

Updating the image

There is no built-in auto-update — DashCaddy does NOT poll for new image digests. To pull a new version:

  1. SSH into the DashCaddy host and run docker pull ubuntu/bind9:latest.
  2. Restart the container: docker restart <containerId> (find the ID via GET /api/v1/services or the dashboard).
  3. Or deploy Watchtower from this catalog (separate template that polls Docker Hub and updates other containers automatically, default schedule 0 0 4 * * * = 04:00 daily).

Backups

The default backup policy includes the entire /app/data/ directory (services, config, credentials, stats) AND all Docker volumes. Backups are scheduled via backup-config.json — the default schedule is configurable, not "nightly" out of the box. To restore on a fresh host, redeploy the same template and then call POST /api/v1/apps/{appId}/restore with a backup ID from GET /api/v1/backups/history.

Troubleshooting

Common issues with BIND9 DNS Server:

  • Container won't start: check the dashboard's Logs panel. Most startup failures are permission errors on the host-path volume.
  • URL not reachable after deploy: the Caddy route was written but DNS hasn't propagated, or port 80/443 is firewalled. Check GET /api/v1/dns/records and systemctl status caddy on the host.
  • Health check timeout (deploy returns 30s after start): the container is starting but tcp://localhost:53 is not returning 200. Inspect docker logs <containerId> directly.

For layer-by-layer diagnostics, see the Troubleshooting guide.


Template ID: bind9. Source: dashcaddy-api/src/docker/app-templates.js.