Skip to content

Instantly share code, notes, and snippets.

@besmirzanaj
Last active September 20, 2025 02:49
Show Gist options
  • Select an option

  • Save besmirzanaj/490c7f8ff61f6e9681fa5656220e3910 to your computer and use it in GitHub Desktop.

Select an option

Save besmirzanaj/490c7f8ff61f6e9681fa5656220e3910 to your computer and use it in GitHub Desktop.
sync two technitium servers
#!/bin/bash
# Author: Besmir Zanaj, 2024
# This is a very raw script to backup configs (no logs and no stats) from a technitium server
# to another
#
# first create two tokens: one on the source server and another one on the destination one
# fill out the vars below
# create a cronjob with this script on the destinaton host
# eg:
# 30 */6 * * * /path-to/technitium-sync.sh
set -euxo pipefail
src_dns_server='source.ip.address'
dst_dns_server='dest.ip.address'
src_dns_serverdomain='fqdn.of.source.server'
dst_dns_serverdomain='fqdn.of.dest.server'
src_dns_token='SOURCE_TECHNITIUM_TOKEN_HERE'
dst_dns_token='DEST_TECHNITIUM_TOKEN_HERE'
backup_file="/tmp/technitium-backup.zip"
# update the dhcp scope as per your local settings
dhcp_scope_name="local-home"
# Ensure required tools are installed
command -v curl >/dev/null 2>&1 || { echo "curl is not installed. Aborting." >&2; exit 1; }
# Check the primary server's health before running the script
echo "Checking primary Technitium server status"
status_code=$(curl --write-out %{http_code} --silent --output /dev/null http://$src_dns_server:5380)
if [[ "$status_code" -ne 200 ]] ; then
echo "Primary DNS server is not available. Skipping backup"
exit 1
else
echo "Getting the backup archive from the primary server"
curl -s "http://$src_dns_server:5380/api/settings/backup?token=$src_dns_token&blockLists=true&logs=false&scopes=true&stats=false&zones=true&allowedZones=true&blockedZones=true&dnsSettings=true&logSettings=true&authConfig=true&apps=true" -o $backup_file
fi
# restore_backup
if [[ -f "$backup_file" ]]; then
echo "Restoring the backup on $HOSTNAME"
curl -s --form file="@$backup_file" "http://$dst_dns_server:5380/api/settings/restore?token=$dst_dns_token&blockLists=true&logs=true&scopes=true&stats=true&apps=true&zones=true&allowedZones=true&blockedZones=true&dnsSettings=true&logSettings=true&deleteExistingFiles=true&authConfig=true" --output /dev/null
# wait for server to come back
echo "Waiting for 10 seconds for the destination server to start up"
sleep 10
# set dnsServerDomain on destination server
echo "Updating DNS server Domain in destination server"
curl -X POST "http://$dst_dns_server:5380/api/settings/set?token=$dst_dns_token&dnsServerDomain=$dst_dns_serverdomain"
# disable DHCP on the destination server
echo "disabling DHCP in destination server"
curl -X POST "http://$dst_dns_server:5380/api/dhcp/scopes/disable?token=$dst_dns_token&name=$dhcp_scope_name"
# cleanup
echo "Cleaning up temporary files"
rm -rf $backup_file
fi
@besmirzanaj
Copy link
Author

I Like this solution, just need to make sure that the primary DNS server is hosting the zone(s) as "Primary" and the secondary server is configured to host the zone(s) as Secondary. This will need further explanation or tutorials from my original blog post, or re-write it (Which I think would be best)

Docs: https://blog.technitium.com/2022/06/how-to-self-host-your-own-domain-name.html

I tried the Primary, Secondary guide from the article above and it worked flawlessly (I assume it worked for you as well since you proposed the solution :) )

Will have to find the time to properly write up this. Thank you for the contribution

@ShauneBoy
Copy link

ShauneBoy commented Jan 14, 2025

Just what I've been looking for (having just moved from a combination of pi-hole and the DNS server running on my NAS - mainly forced to move as NAS died so thought I would "do it properly") - DNS Syncing is working a treat (having read the above) - setup as Master and Secondary zones but have a couple of questions...

Can you (easily) just replicate the DHCP settings? As think this would complete the setup... The original sync script sync'd everything - whilst the new "swap DHCP server" script just monitors the DHCP - but I have some reservations defined and would like not have to remember to update both DHCP servers ;)... Also, guess it would keep the stand-by DHCP server updated with the current IP addresses in use? [as when I swapped from Pi-Hole, I noted that the clients picked up totally new IP addresses and didn't keep what they had been previously assigned - so would that be the case again if the DHCP server swapped?]

But also wondering if it would be enough to leave the DHCP server enabled on the secondary machine but set the OFFER time to something like 4 seconds? [so the Primary one would normally answer?] - although that doesn't solve the replication of the reservations/current leases :)...

Sorry if any of this seems obvious!

@besmirzanaj
Copy link
Author

Following the updated script, to optimize the DHCP leases, the solution is really simple.

On the Secondary technitium server DHCP settings, configure the "Offer Delay Time" to something higher than 1s (1000 ms), and leave the default 100ms on the Primary one. That means that the Primary Server will always be the first to offer the IP assignment and if it is not available, the second DNS server will take over.

iScreen Shoter - Google Chrome - 250114180425

@brthurr
Copy link

brthurr commented Apr 30, 2025

Am I safe to assume that if I'm not using the Technitium DHCP server then I can just remove those lines? I let my Unifi gateway handle DHCP and just use Technitium for DNS.

@besmirzanaj
Copy link
Author

yes, definitely, I like the dhcp integration, but that is not necessary

@Lebowski89
Copy link

Lebowski89 commented Jun 28, 2025

Hi, any reason why you're not doing Docker Swarm services? That solves the high availability issue right there.

For Swarm, you cannot do network_mode: "host", but to work around that you do something like this:

    networks:
      - outside

networks:
  outside:
    external:
      name: 'host'

I use a combination of Ansible and Docker Swarm to deploy all my docker services, including Technitium.

Edit: Just tried it myself, works just fine.

Screenshot_219

Each Technitium instance can have its own settings (just remove the DNS_SERVER_DOMAIN=dns01.home.arpa and do it in the app itself).

@besmirzanaj
Copy link
Author

hi @Lebowski89, thank you for sharing this. Unfortunately I don't have a cluster of docker servers.

@Lebowski89
Copy link

hi @Lebowski89, thank you for sharing this. Unfortunately I don't have a cluster of docker servers.

np, thank you for your blog. I just thought, if you wanted to install docker on your raspberry pi, you could make it a docker swarm worker and use your main server to deploy technitium to it. I've never owned a rpi, though, so not sure if installing docker on them has issues. Using a Beelink Mini-PC as a Swarm worker for the second Technitium instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment