Skip to content

fini-net/fini-coredns-example

FINI coredns example

GitHub Issues GitHub Pull Requests GitHub License GitHub watchers

A complete example demonstrating how to use DNSControl to generate DNS zone files and serve them with CoreDNS in a container.

What's Included

This repository provides:

  • JavaScript DNS Configuration: Define DNS records using DNSControl's JavaScript syntax for example.com and example.org domains
  • Automated Zone File Generation: Convert JavaScript configurations to BIND zone files with just push
  • Containerized DNS Server: Ready-to-run CoreDNS container serving the generated zones
  • Automated Testing: Go test suite validating DNS responses for 10+ specific records
  • Development Workflow: Complete just command recipes for building, testing, and deploying
  • GitHub Container Registry: Pre-built container images available at ghcr.io/fini-net/fini-coredns-example

Quick Start

  1. Generate zone files: just push (uses DNSControl to create BIND files from JavaScript)
  2. Build container: just build_con (creates local container with CoreDNS + zone files)
  3. Start DNS server: just run_con (runs container on port 1029)
  4. Test functionality: just test_dns (validates DNS responses) or dig @localhost -p 1029 www.example.com

The development process documents all available just subcommands for working with this repository.

Working with the container

To generate the container on your local machine run just build_con.

To run the built container run just run_con. A DNS server should be available on port 1029. You can see it working with dig like so:

% dig @localhost -p 1029 www.example.com

; <<>> DiG 9.10.6 <<>> @localhost -p 1029 www.example.com
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3344
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 4, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.example.com.               IN      A

;; ANSWER SECTION:
www.example.com.        3600    IN      CNAME   server1.example.com.
server1.example.com.    3600    IN      A       10.0.0.101

;; AUTHORITY SECTION:
example.com.            3600    IN      NS      ns0.example.com.
example.com.            3600    IN      NS      ns1.example.com.
example.com.            3600    IN      NS      ns2.example.com.
example.com.            3600    IN      NS      ns3.example.com.

;; Query time: 6 msec
;; SERVER: ::1#1029(::1)
;; WHEN: Sat Jul 05 20:26:48 PDT 2025
;; MSG SIZE  rcvd: 287

That is the same CNAME and IP that you can see in the zone file.

Easier working wih the container

To save you some typing you could run just test_con to get this experience:

% just test_con
Expect to see in dig output:
;; ANSWER SECTION:
www.example.com.        3600    IN      CNAME   server1.example.com.
server1.example.com.    3600    IN      A       10.0.0.101

dig @localhost -p 1029 www.example.com

; <<>> DiG 9.10.6 <<>> @localhost -p 1029 www.example.com
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36425
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 4, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.example.com.               IN      A

;; ANSWER SECTION:
www.example.com.        3600    IN      CNAME   server1.example.com.
server1.example.com.    3600    IN      A       10.0.0.101

;; AUTHORITY SECTION:
example.com.            3600    IN      NS      ns0.example.com.
example.com.            3600    IN      NS      ns1.example.com.
example.com.            3600    IN      NS      ns2.example.com.
example.com.            3600    IN      NS      ns3.example.com.

;; Query time: 2 msec
;; SERVER: ::1#1029(::1)
;; WHEN: Thu Jul 10 12:37:44 PDT 2025
;; MSG SIZE  rcvd: 287

Looks great until we can automate it!™

Container commands reference

For direct podman usage without just:

# Run the container (DNS server on port 1029)
podman run -d --name corednstest -p 1029:53/udp fini-coredns-example

# Test the DNS server
dig @localhost -p 1029 www.example.com

# Stop and clean up
podman stop corednstest
podman rm corednstest

# Inspect container metadata
podman inspect fini-coredns-example | jq '.[0].Labels'

Testing

The repository includes automated Go tests that validate DNS responses from the container:

% just test_dns
Make sure container is running: just run_con
=== RUN   TestDNSRecords
=== RUN   TestDNSRecords/example.com_root_A_record
=== RUN   TestDNSRecords/server1.example.com_A_record
=== RUN   TestDNSRecords/ns0.example.com_A_record
=== RUN   TestDNSRecords/www.example.com_CNAME_record
=== RUN   TestDNSRecords/ftp.example.com_CNAME_record
=== RUN   TestDNSRecords/server1.example.com_AAAA_record
=== RUN   TestDNSRecords/server1.example.com_TXT_record
=== RUN   TestDNSRecords/example.org_root_A_record
=== RUN   TestDNSRecords/www.example.org_A_record
=== RUN   TestDNSRecords/calendar.example.org_CNAME_record
--- PASS: TestDNSRecords (0.01s)
    --- PASS: TestDNSRecords/example.com_root_A_record (0.00s)
    --- PASS: TestDNSRecords/server1.example.com_A_record (0.00s)
    --- PASS: TestDNSRecords/ns0.example.com_A_record (0.00s)
    --- PASS: TestDNSRecords/www.example.com_CNAME_record (0.00s)
    --- PASS: TestDNSRecords/ftp.example.com_CNAME_record (0.00s)
    --- PASS: TestDNSRecords/server1.example.com_AAAA_record (0.00s)
    --- PASS: TestDNSRecords/server1.example.com_TXT_record (0.00s)
    --- PASS: TestDNSRecords/example.org_root_A_record (0.00s)
    --- PASS: TestDNSRecords/www.example.org_A_record (0.00s)
    --- PASS: TestDNSRecords/calendar.example.org_CNAME_record (0.00s)
=== RUN   TestContainerHealthCheck
--- PASS: TestContainerHealthCheck (0.00s)
=== RUN   TestNSRecords
--- PASS: TestNSRecords (0.00s)
=== RUN   TestMXRecords
=== RUN   TestMXRecords/example.com
=== RUN   TestMXRecords/example.org
--- PASS: TestMXRecords (0.00s)
    --- PASS: TestMXRecords/example.com (0.00s)
    --- PASS: TestMXRecords/example.org (0.00s)
PASS
ok  	github.com/fini-net/fini-coredns-example/test	0.220s

The test suite validates specific DNS records including A, AAAA, CNAME, TXT, NS, and MX records across both example domains. Tests require the container to be running first via just run_con.

Standards

The domains and IPs in the examples contained in this repo should comply with

to avoid interfering with any existing infrastructure.

Contibuting

Support & Security

Thanks