If you’re like me, you love self-hosting your own projects. But as the number of services you run grows, so does the list of DNS records.
I used to log into my Cloudflare dashboard constantly, adding A record after A record. It felt messy, and I ended up with dozens of entries for my main domain.
I wanted a cleaner solution – a way to isolate my self-hosted projects (like Beszel) from my main site, gain full control over their DNS, and maybe even learn a thing or two about how DNS really works under the hood.
That’s where CoreDNS comes in. It’s a tiny, incredibly fast, and easy-to-configure DNS server that’s perfect for this. With a single configuration file and a lightweight Docker container, you can build your own authoritative DNS server.
In this guide, I'll walk you through the exact steps I took to set up my own authoritative DNS server for a subdomain.
We’re going to build the official source of truth for a dedicated zone, like lab.yourdomain.com. It’s a game-changer for managing a growing collection of self-hosted services.
Any public DNS query for *.lab.yourdomain.com will be correctly delegated and answered by your CoreDNS server, giving you full, instant control over your records.
Don’t worry if this is new – I'll walk you through it, step by step.
If you want more write-ups like this one, subscribe to my newsletter – I send an email when I publish new guides and walkthroughs.
The Big Picture: What We're Building (and What We're Not)
Before we get our hands dirty, let’s zoom out.
Our goal is to build our very own authoritative DNS server. Think of it as creating a definitive, private address book for our own projects.
This guide focuses on using a subdomain (like lab.yourdomain.com) for this project, with our CoreDNS server living at ns1.lab.yourdomain.com.
This approach is known as using an "in-bailiwick" nameserver, a fancy way of saying the nameserver (ns1.lab...) resides within the same subdomain (lab...) that it manages.
It’s a clean and scalable way to structure your DNS. I chose this method to neatly separate my lab services from my main site without needing to buy a new domain, and it's a fantastic, low-cost way to learn if you already own one.
If you decide to create another DNS environment later (like dev.yourdomain.com), you can repeat the pattern without everything getting tangled up.
However, the principles here can also be adapted if you want to use a dedicated root domain (e.g., your-new-cool-project.com).
A quick note on SEO: A common worry is whether using a subdomain will hurt your main site’s search engine ranking. Don’t worry, it won’t. Google and other search engines treat subdomains as separate properties. As long as your projects don’t create security issues, your main domain’s SEO will be completely unaffected.
Authoritative vs. Recursive: A Crucial Distinction
It is vital to understand the type of server we are building.
A DNS server can play two main roles:
- Authoritative Server (What we are building): This server holds the "master copy" of records for a specific zone. It only answers questions about domains it controls. When asked about
beszel.lab.ivansalloum.com, it confidently says, "I know the answer! It's192.168.1.100." It is the source of truth. - Recursive Resolver (What we are NOT building): This is the type of DNS server you typically use for your computer or home router (like Cloudflare's
1.1.1.1or Google's8.8.8.8). Its job is to go out and find the answer to any query. When you ask it forgoogle.com, it recursively talks to other DNS servers across the internet to find the correct IP address for you.
Our configuration is purely authoritative. It knows nothing about the outside world.
If we allow our server to answer generic queries for anyone on the internet, it would become an "Open Resolver."
Hackers actively hunt for these unsecured servers to launch massive DDoS attacks (called Amplification Attacks) against victims. By keeping our server strictly Authoritative, we keep our infrastructure – and the internet – safer.
If you point your laptop's DNS settings only to your new CoreDNS server and then try to visit google.com, this is what happens:
- Your server looks at its own
Corefile. - It sees it's only responsible for
lab.yourdomain.com. - It essentially replies, "I don't know who
google.comis, and it's not my job to find out."
The request will fail, and for you, the internet will appear "broken."
Our server is only meant to be found by public resolvers (like Cloudflare or Google) that are looking for answers about our specific subdomain.
Preparing Your Server
Before we dive into CoreDNS specifics, we need to get your server ready.
I’m writing this guide based on my experience with an Ubuntu 24.04 LTS server hosted on a Hetzner VPS, but the steps should be broadly applicable to most Linux distributions.
Set Your Server's Hostname
It’s good practice to give your server a meaningful hostname.
For this setup, it makes sense to use the nameserver's own FQDN (Fully Qualified Domain Name):
sudo hostnamectl set-hostname ns1.lab.ivansalloum.comThis command updates your server's hostname to reflect its role as the nameserver for your lab environment.
Remember to replace ivansalloum.com with your actual domain!
Register Your Nameserver's IP (Glue Records)
It's absolutely crucial to register the IP addresses for your nameserver with your domain registrar or DNS provider. These are often called "glue records" and they tell the internet where ns1.lab.ivansalloum.com actually lives.
Without them, no one will be able to find your custom DNS server.
You'll need to create A and optionally AAAA records for your nameserver's hostname (ns1.lab.ivansalloum.com) at your DNS provider.
Ensure these records are set up to directly point to your server's IP addresses and are not proxied if your provider offers that option (e.g., Cloudflare's orange cloud). DNS traffic for nameservers must hit your server directly.
Also, do not add an A record for just lab at this stage; we are only creating records for ns1.lab itself. The lab subdomain will be delegated later.
Free Up Port 53 (Stop systemd-resolved)
DNS services communicate primarily over port 53.
systemd-resolved (Ubuntu’s local DNS stub) might already be listening on this port, preventing CoreDNS from binding to it. We need to disable its stub listener.
You can check if port 53 is in use with:
sudo lsof -i :53If you see systemd-resolved listed, follow these steps to disable it.
First, create the directory for systemd-resolved overrides:
sudo mkdir -p /etc/systemd/resolved.conf.d/Then, set appropriate permissions for the newly created directory:
sudo chmod 755 /etc/systemd/resolved.conf.d/Next, disable the DNSStubListener by writing the configuration to a file:
printf "[Resolve]\nDNSStubListener=no\n" | sudo tee /etc/systemd/resolved.conf.d/noresolved.confFinally, restart systemd-resolved to apply the changes:
sudo systemctl restart systemd-resolved.serviceAfter restarting, sudo lsof -i :53 should no longer show systemd-resolved listening.
Configure Your Firewall (UFW)
For your CoreDNS server to receive queries, you'll need to open the necessary ports in your firewall.
DNS traffic primarily uses UDP port 53, but TCP port 53 is also essential:
sudo ufw allow 53/udp
sudo ufw allow 53/tcp
sudo ufw enable # If UFW is not already enabledAlmost all DNS queries use UDP because it's fast and lightweight. However, if a DNS response is too large, or for critical operations like zone transfers (especially important if you ever add a secondary DNS server), TCP is used.
Install Docker
We'll be running CoreDNS inside a Docker container for ease of deployment and management.
It's crucial to use up-to-date Docker Engine and Docker Compose versions because Ubuntu's default repositories often contain outdated packages.
For optimal performance and the latest features, always rely on Docker's official repositories.
Create CoreDNS Directories
We need a dedicated place for CoreDNS's configuration and zone files:
sudo mkdir -p /opt/coredns/{config,zones}
sudo chmod -R 755 /opt/corednsWith these preparations done, your server is ready to host your authoritative CoreDNS instance!
We've just done the necessary prep for CoreDNS. If you'd like to see my complete checklist for setting up a new Ubuntu server from scratch for optimal security and performance, I've detailed everything in this guide: Preparing Your Ubuntu Server for First Use
Creating Your First Zone File
Now for the fun part. We need to create a zone file. This is a plain text file that acts as the database for your subdomain.
It contains all the DNS records – like A, AAAA, CNAME, etc. – that tell the world where to direct traffic for hosts within your zone.
First, navigate to the zones directory we created earlier:
cd /opt/coredns/zonesNext, create and open the zone file. It's a common convention to name this file db. followed by your zone name. In my case, it's db.lab.ivansalloum.com:
sudo vim db.lab.ivansalloum.comNow, paste the following template into the file. This is the heart of your DNS setup:
$ORIGIN lab.ivansalloum.com.
$TTL 3600
@ IN SOA ns1.lab.ivansalloum.com. admin.ivansalloum.com. (
2025120601 ; Serial (YYYYMMDDnn) - CHANGE THIS ON EVERY EDIT!
7200 ; Refresh (2 hours)
120 ; Retry (2 minutes)
2419200 ; Expire (28 days)
3600 ; Negative Cache TTL (1 hour)
)
IN NS ns1.lab.ivansalloum.com.
ns1 IN A YOUR_SERVER_IPV4
ns1 IN AAAA YOUR_SERVER_IPV6
; --- Your Custom Records Go Here ---
beszel IN A 192.168.1.100
hestia IN A 192.168.1.1
; --- Optional Wildcard For Instant Testing ---
* IN A 192.168.0.10Once you've pasted the template, here are the three critical edits you must make before saving:
- Go through the template and replace
lab.ivansalloum.com.,ns1.lab.ivansalloum.com.,- and
admin.ivansalloum.com. - with your actual subdomain, nameserver FQDN, and admin email.
- Replace
YOUR_SERVER_IPV4andYOUR_SERVER_IPV6with the actual public IP addresses of your CoreDNS server. If you don't use IPv6, simply delete that line entirely. - The line
2025120601is the zone's version number. It's crucial that you increment this number every time you edit the file. A common format isYYYYMMDDnn, wherennis the revision number for the day. For this first setup, I recommend setting it to today's date inYYYYMMDDnnformat. This makes it easy to track your initial zone version.
Save the file and exit the editor (:wq in vim).
A Note on Zone File Naming
You might be wondering why we named our zone file db.lab.ivansalloum.com.
The db. prefix is purely for convention and readability; it's a holdover from BIND, one of the oldest DNS servers, where db stood for "database."
You could name your file records.txt if you wanted, as long as you point to it correctly in your Corefile.
Sticking to convention, however, makes your setup instantly familiar to other sysadmins (and your future self).
What Did We Just Create?
After saving your new zone file, you've essentially created the instruction manual for your lab.ivansalloum.com subdomain. In short, it does two main things:
- Declares Authority: The
SOAandNSrecords act like official stamps, announcing that your server is in charge of this zone. - Builds an Address Book: The
A,AAAA, and other records map your service names (likebeszel) to their IP addresses.
The most important "address book" entries are the A and AAAA records for ns1 itself. These are called glue records, and they're critical because they tell the internet how to find your nameserver in the first place.
Think of it as setting up the front desk (SOA, NS) and then filling out the directory (A, AAAA, etc.) for your new DNS office. Pretty neat, right?
Configuring CoreDNS with the Corefile
Our zone file is ready, holding all our DNS records.
But how do we tell CoreDNS to actually use it? This is where the Corefile comes in, and honestly, its simplicity is the main reason I fell in love with CoreDNS.
Instead of wrestling with complex, multi-file setups, CoreDNS uses one single, human-readable file to manage everything. It’s where we tell CoreDNS what zones to serve, what plugins to use, and how to behave.
Let's get it set up.
Navigate to the config directory you created earlier:
cd /opt/coredns/configNow, create and open the Corefile itself:
sudo vim CorefilePaste this small block of text in. This is all you need to get a basic authoritative server running:
lab.ivansalloum.com:53 {
log
errors
file /zones/db.lab.ivansalloum.com
}Save and close the file.
This configuration is elegantly powerful. The first line, lab.ivansalloum.com:53, tells CoreDNS to listen for queries for our zone on port 53.
Inside the block, we enable two incredibly useful plugins, log and errors, which are lifesavers for debugging and seeing your server in action.
Finally, the file /zones/db.lab.ivansalloum.com line is the heart of our setup. This plugin points CoreDNS to our zone file, making it the official, authoritative source for all the records within it. The path /zones/db.lab.ivansalloum.com is relative to the inside of our future Docker container.
And that's it. We've defined our records and told CoreDNS how to serve them.
Docker Compose Configuration
Now that we have our zone file and Corefile configured, it's time to bring our CoreDNS server to life. For this, I absolutely love using Docker.
We'll use docker compose to define and run our CoreDNS service. This allows us to set up all the necessary parameters – like ports, volumes, and restart policies – in a single, easy-to-read file.
Let's create our docker-compose.yml file in the main /opt/coredns directory:
sudo vim /opt/coredns/docker-compose.ymlPaste the following content into the file:
services:
coredns:
image: coredns/coredns:latest
container_name: coredns
restart: unless-stopped
ports:
- "53:53/udp"
- "53:53/tcp"
volumes:
- ./config/Corefile:/Corefile:ro
- ./zones:/zones:roSave and close the file.
This docker-compose file defines how our CoreDNS server will run. In short, it:
- Pulls the official CoreDNS image and names the container
coredns. - Sets the
restartpolicy tounless-stopped, which is a must-have for any self-hosted service to ensure it automatically starts up after a reboot. - Maps the DNS ports (
53/udpand53/tcp) from your host server to the container. - Mounts our configuration files (the
Corefileand ourzonesdirectory) into the container in read-only mode, so CoreDNS can use them.
With this docker-compose.yml in place, we're just one command away from launching our very own authoritative DNS server!
Launching CoreDNS and Local Testing
We've prepared our server, crafted our zone file, and configured CoreDNS. Now, let's fire up our container and make sure everything is working as expected.
First, navigate to the main /opt/coredns directory where your docker-compose.yml file is located:
cd /opt/corednsNow, launch CoreDNS with Docker Compose in detached mode (-d), meaning it will run in the background:
sudo docker compose up -dYou should see output indicating that the coredns container has been created and started.
With our CoreDNS server now running, let's immediately verify it's answering queries locally before we go live. This local verification step is crucial as it confirms our setup works before we expose it to the internet.
We'll use the dig command-line tool to do this. The trick is to query your own server's IP address directly, bypassing any other DNS resolvers. When we query our server directly, we're bypassing public resolvers to test our server in isolation.
A DNS resolver is a server (like
1.1.1.1 or 8.8.8.8) that clients (your computer) query to find the IP address of a domain name. It handles the entire process of finding the authoritative nameserver and returning the answer to you.Remember to replace YOUR_SERVER_IPV4 with your server's actual public IPv4 address.
First, let's confirm our server is authoritative for the zone by querying the SOA record:
dig @YOUR_SERVER_IPV4 lab.ivansalloum.com SOAYou should see your SOA record returned, matching the details you put in db.lab.ivansalloum.com.
Next, let's query one of the specific test records we added, like beszel:
dig @YOUR_SERVER_IPV4 beszel.lab.ivansalloum.comThis should return the A record for beszel (e.g., 192.168.1.100).
Finally, if you included the optional wildcard record, test it:
dig @YOUR_SERVER_IPV4 anything.lab.ivansalloum.comThis should resolve to the IP address defined in your wildcard entry.
If all these dig commands return the expected answers, congratulations! Your authoritative DNS server is fully functional and ready to serve requests for your subdomain.
The next step is to tell the rest of the internet to start asking your server for these records.
We're almost there!
Delegating Your Subdomain
Our CoreDNS server is humming along locally.
The final, exhilarating step is to tell the world – specifically, through your domain registrar or DNS provider (in my case, Cloudflare) – that for your chosen subdomain, your CoreDNS server is now the one in charge. This is called delegation.
It's a powerful moment, making your self-hosted DNS server officially responsible for lab.ivansalloum.com (or whatever subdomain you chose).
Head over to your domain registrar or DNS provider and add a new NS (Nameserver) record for your subdomain with the following details::
- Type:
NS - Name:
lab(or your chosen subdomain part, e.g.,lab.ivansalloum.com) - Value:
ns1.lab.ivansalloum.com.(your nameserver's FQDN, with a trailing dot!) - TTL:
Autois usually fine.
Before you save this record, there are a few crucial sanity checks to perform:
- Don't Forget Your Glue Records: This entire process will only work if you've already created the
AandAAAArecords forns1.lab.ivansalloum.comas we did in the "Preparing Your Server" section. These "glue records" are what allow the internet to find your nameserver in the first place. - Ensure "DNS Only" Mode: If your provider (like Cloudflare) offers a proxy service, make sure it is disabled for this NS record (e.g., a "grey cloud" in Cloudflare). The internet needs to be able to reach your nameserver directly.
- Avoid Conflicting Records: Make sure you do NOT have an
Arecord forlabitself. A subdomain can either be delegated (with anNSrecord) or point to an IP (with anArecord), but it can't do both.
Once you've confirmed these points and saved your new NS record, you're ready for the final validation.
Public Validation: Confirming Your Delegation
The CoreDNS server is running, the zone file is configured, and your DNS provider has been updated to delegate your subdomain.
Now comes the exciting part: confirming that the entire internet sees your CoreDNS server as the authoritative source for your subdomain.
While DNS changes can sometimes take a while to propagate, subdomain delegation is usually quite fast – I've often seen it go live within 1 to 10 minutes.
Once you've given it a moment, you can verify your setup from any machine other than your CoreDNS server. This ensures you're querying external DNS resolvers, just like the rest of the world. We'll also use dig for this.
First, let's ask a public resolver (like 1.1.1.1) to confirm that our new nameserver is correctly set up for the subdomain:
dig lab.ivansalloum.com NS @1.1.1.1You should see your nameserver (ns1.lab.ivansalloum.com.) in the answer section, which confirms the delegation is visible.
Next, let's test that your CoreDNS server is serving the actual records. Try querying one of the custom records you created in your zone file:
dig beszel.lab.ivansalloum.com @1.1.1.1This should return the A record for beszel that you defined earlier.
If both of these commands work, your authoritative DNS server is officially live and serving records to the internet!
Managing Your DNS Records
Now that your authoritative DNS server is live, the best part is how easy it is to manage your records. The process is simple and gives you full control.
Here’s the step-by-step workflow to update or add new records.
Step 1: Edit Your Zone File
First, open your zone file:
sudo vim /opt/coredns/zones/db.lab.ivansalloum.comNow, you can either change an existing record or add new ones.
CoreDNS supports all standard DNS record types, including A, AAAA, CNAME, TXT, and more.
For example, to add new A, CNAME, and TXT records, you would add lines similar to these:
; --- Your Custom Records Go Here ---
beszel IN A 192.168.1.100
hestia IN A 192.168.1.1
wordpress IN A 192.168.1.105 ; A record for our new WordPress instance
www.beszel IN CNAME beszel.lab.ivansalloum.com. ; CNAME for www.beszel pointing to beszel
@ IN TXT "v=spf1 include:_spf.example.com ~all" ; TXT record for SPFRemember to replace the example values with your own service names and data.
Step 2: Increment the Serial Number (Crucial!)
This is a critical step, primarily for secondary DNS servers (if you ever add them) to know your zone file has changed and needs updating.
The only strict rule is that the serial number must be a single number that strictly increases every time you make a change. However, using the YYYYMMDDnn format (Year, Month, Day, and a two-digit revision for changes on that day) is a widely-adopted best practice for human readability and sanity.
Here's how to manage it:
- First change of the day: Update the date part to today's date and set the two-digit counter to
01. For example, if your old serial was2025120202and today is December 7th, 2025, your new serial would be2025120701. - Subsequent changes on the same day: Only increment the last two digits. For example, a second change on December 7th would make it
2025120702.
Always remember to increment this number whenever you modify your zone file.
Step 3: Restart the CoreDNS Container
After saving and closing the file, you need to restart the CoreDNS container so it reloads your updated zone file.
Navigate to the directory where your docker-compose.yml file is located:
cd /opt/corednsThen, simply run the restart command:
sudo docker compose restartThis command will gracefully restart the coredns service. It's very fast, usually taking just a second or two.
Once it restarts, CoreDNS will have loaded your new records.
Step 4: Verify Your Changes
Finally, to be sure everything worked, test your new record with dig from your local machine:
dig wordpress.lab.ivansalloum.com @1.1.1.1You should see the new IP address (192.168.1.105) reflected in the answer.
That's it! You can repeat this process any time you need to add, update, or remove a DNS record.
Automating Zone Reloads (The Pro Way)
Manually restarting the CoreDNS container after every zone file change is simple and effective, but there’s an even better, more professional way: using the reload plugin.
This plugin watches your zone file for changes and, if it detects any, gracefully reloads the zone in the background with zero downtime. You never have to restart the container for simple record updates again!
Let's enable it.
Edit your Corefile one more time:
sudo vim /opt/coredns/config/CorefileAdd the reload plugin to the top of your server block. It should look like this:
lab.ivansalloum.com:53 {
reload
log
errors
file /zones/db.lab.ivansalloum.com
}Save the file, and then restart the container one last time to activate the reload plugin itself:
cd /opt/coredns
sudo docker compose restartFrom now on, you can simply edit your db.lab.ivansalloum.com file, and CoreDNS will automatically apply the changes within about 30 seconds (the default check interval).
This small change makes managing your DNS records an even more seamless experience.
The reload plugin is smart. It only reloads the zone if it detects that the serial number has increased.
If you forget to increment the serial number, the plugin will assume nothing has changed and won't apply your updates.
So, the workflow remains:
- Edit your records,
- increment the serial,
- and save the file.
The restart step is now automated for you.
Seeing the Difference: dig in Action
We've talked about the difference between an authoritative server and a recursive resolver, but let's see it live using dig.
This is the best way to truly understand the roles they play.
Query 1: A Standard Recursive Query
When you run dig for a public domain, your computer uses the default DNS resolver provided by your router or ISP:
dig ivansalloum.comThis is a recursive resolver.
Notice the flags in the header of the response: qr rd ra.
qr= Query Responserd= Recursion Desired (You asked the resolver to find the answer for you)ra= Recursion Available (The resolver is confirming it can do this)
The resolver went out and found the answer for you.
Query 2: Specifying a Public Resolver
We can get the same kind of recursive answer by specifying a different public resolver, like Cloudflare's 1.1.1.1:
dig ivansalloum.com @1.1.1.1Again, you'll see the ra flag.
1.1.1.1 is a recursive resolver, and it happily found the answer.
Query 3: Asking Our Authoritative Server for a Public Domain (The "Broken" Test)
Now, let's ask our new CoreDNS server to find ivansalloum.com:
dig ivansalloum.com @YOUR_SERVER_IPV4The result is completely different.
The status is REFUSED, and you might see a warning like recursion requested but not available.
Our server correctly refused the query because it's not a public resolver and has no idea who ivansalloum.com is.
Query 4: Asking Our Authoritative Server for a Zone It Controls
This is where our server shines.
Let's ask it for a record from the zone it's responsible for:
dig beszel.lab.ivansalloum.com @YOUR_SERVER_IPV4
This query succeeds beautifully! Now, look very closely at the flags in the header: qr aa rd.
That aa flag is the key. It stands for Authoritative Answer. This is the DNS system's way of confirming that the answer came directly from the server that is the ultimate source of truth for that domain.
You will not see this aa flag when you query for beszel.lab.ivansalloum.com using a public resolver like 1.1.1.1, because 1.1.1.1 is just relaying the answer it found from your server.
This aa flag is your proof that you have successfully built and queried a true authoritative DNS server.
Backup and Recovery with Hetzner Snapshots
Even with a stable DNS server, having a disaster recovery plan is essential for peace of mind.
For my setup on Hetzner, their snapshot feature combined with IP protection has proven to be a robust and reliable solution for disaster recovery.
The goal was to simulate a total server failure and see if I could bring my DNS server back to life from a backup.
Here's the strategy I used, combining two powerful Hetzner features.
The Strategy: Protected IPs + Snapshots
- Enable IP Protection: Before anything else, I went to my Hetzner Cloud Console and enabled "IP protection" on my server's public IPv4 and IPv6 addresses. This is a critical feature that prevents your IPs from being lost if the server is deleted. It turns them into floating IPs that you can re-assign to a new server.
- Take a Snapshot: With my CoreDNS server running and serving records for a test service (
beszel.lab.ivansalloum.com), I took a manual snapshot of the server.
My Disaster Recovery Test
With the snapshot created and the IPs protected, it was time for the real test: I deleted the server entirely.
An interesting thing happened right after. On my home WiFi, beszel.lab.ivansalloum.com still worked for a few minutes. This is DNS caching in action! My local router or ISP's resolver had cached the record and didn't need to ask for it again.
However, when I switched to my phone's 5G network (a "fresh" resolver), the domain failed to resolve immediately. This perfectly demonstrates why DNS resilience is so important – cached records will eventually expire, and a single server outage will be felt.
Next, I provisioned a new server from the snapshot I had created. During the creation process, I re-attached my protected IPv4 and IPv6 addresses to the new instance.
The result? Within moments of the new server booting up, CoreDNS was back online.
My beszel.lab.ivansalloum.com domain started resolving correctly on all networks.
It just worked.
Automated Backups & Protection
While manual snapshots are great for point-in-time recovery, Hetzner offers additional layers of protection:
- Automated Backups: For more frequent and automated restore points, consider enabling Hetzner's backup add-on. For a small additional cost (typically 20% of the server cost), this service provides daily backups that are kept for a week. A key advantage is that you can convert any automated backup into a manual snapshot before performing a restore or server deletion.
- Deletion Protection: To prevent accidental deletion of your server (and thus, your DNS service), always enable deletion protection in the Hetzner Cloud Console. It's a simple toggle that can save you a lot of headache.
This comprehensive approach ensures you're well-covered for any eventuality.
Conclusion and Final Thoughts
Congratulations! You've successfully deployed your very own authoritative DNS server with CoreDNS, giving you unparalleled control over your subdomains.
This setup empowers you to:
- Isolate your self-hosted projects: Keep your main domain's DNS clean and separate.
- Enjoy instant control: Add, update, or remove records in seconds, without waiting for third-party providers.
- Deepen your DNS understanding: You've walked through the core concepts of DNS delegation, zone files, and record management.
This journey into self-hosting your DNS is a fantastic step towards greater independence and control in your personal infrastructure.
Keep experimenting, keep learning, and enjoy the power you now have at your fingertips.
If you run into any issues or need further help, feel free to revisit this guide or reach out for assistance.
If you found this guide helpful, consider subscribing to my newsletter (beneath the “Read next” section) for more tips and walkthroughs on self-hosting, security, and everything in between!
And if have thoughts and feedback, drop them in the discussion section; I always enjoy seeing how others build on this.
Discussion