I run PiHole for ad-blocking on my home network. I’m an SRE in my day job, so of course I’m not running a single instance of something as important as DNS. I also don’t want to have to update things like local DNS entries or blocklists in multiple places, that will cause weird and annoying inconsistencies in my DNS.

Enter orbital-sync.

Installation

docker-compose

I’m running orbital-sync via docker-compose with this docker-compose.yaml file.

# docker-compose.yaml version: '3' services:  orbital-sync:  image: mattwebbio/orbital-sync:1  environment:  PRIMARY_HOST_BASE_URL: $PRIMARY_HOST_BASE_URL  PRIMARY_HOST_PASSWORD: $PRIMARY_HOST_PASSWORD  SECONDARY_HOSTS_1_BASE_URL: $SECONDARY_HOSTS_1_BASE_URL  SECONDARY_HOSTS_1_PASSWORD: $SECONDARY_HOSTS_1_PASSWORD  SECONDARY_HOSTS_2_BASE_URL: $SECONDARY_HOSTS_2_BASE_URL  SECONDARY_HOSTS_2_PASSWORD: $SECONDARY_HOSTS_2_PASSWORD  # I only have two secondary hosts, but you could sync a third one  # SECONDARY_HOSTS_3_BASE_URL: 'http://server:8080'  # SECONDARY_HOSTS_3_PASSWORD: 'your_password4'  # SECONDARY_HOSTS_3_PATH: '/apps/pi-hole'  INTERVAL_MINUTES: $INTERVAL_MINUTES  # Run it in the same docker network I run the master pihole in for simplicity. # You can comment this stanza out if you're not using a ssl proxy. networks:  default:  external:  name: ssl_proxy_network 

Configuration

I have a .env file in the same directory as docker-compose.yaml where I set the configuration variables.

# I run orbital-sync on the same host as the master pihole in the same # docker network I use for my SSL nginx proxy, so I can refer to it here # by container name. PRIMARY_HOST_BASE_URL=http://pihole PRIMARY_HOST_PASSWORD=YOUR_MASTER_PIHOLE_ADMIN_PASSWORD SECONDARY_HOSTS_1_BASE_URL=https://dns-secondary-one.example.com SECONDARY_HOSTS_1_PASSWORD=SECONDARY_ONE_PIHOLE_ADMIN_PASSWORD SECONDARY_HOSTS_2_BASE_URL=https://dns-secondary-two.example.com SECONDARY_HOSTS_2_PASSWORD=SECONDARY_TWO_PIHOLE_ADMIN_PASSWORD # I sync the primary to the secondaries every ten minutes. INTERVAL_MINUTES=10 # I only run two secondaries, but I could sync a third if I wanted #SECONDARY_HOSTS_3_BASE_URL=https://dns-secondary-three.example.com #SECONDARY_HOSTS_3_PASSWORD=SECONDARY_THREE_PIHOLE_ADMIN_PASSWORD 

The SSL proxy setup is documented at Set up nginx-proxy-manager with LetsEncrypt SSL certificates

Running

Now you can run docker-compose up -d and your settings will be synced from your master pihole to its secondaries.

Here’s a sanitized example docker log:

$ docker-compose logs orbital-sync_1 | 12/6/2024, 4:44:28 PM: ➡️ Signing in to http://pihole/admin... orbital-sync_1 | 12/6/2024, 4:44:28 PM: ✔️ Successfully signed in to http://pihole/admin! orbital-sync_1 | 12/6/2024, 4:44:28 PM: ➡️ Downloading backup from http://pihole/admin... orbital-sync_1 | 12/6/2024, 4:44:28 PM: ✔️ Backup from http://pihole/admin completed! orbital-sync_1 | 12/6/2024, 4:44:28 PM: ➡️ Signing in to https://dns-s1.example.com/admin... orbital-sync_1 | 12/6/2024, 4:44:28 PM: ✔️ Successfully signed in to https://dns-s1.example.com/admin! orbital-sync_1 | 12/6/2024, 4:44:28 PM: ➡️ Uploading backup to https://dns-s1.example.com/admin... orbital-sync_1 | 12/6/2024, 4:44:46 PM: ✔️ Backup uploaded to https://dns-s1.example.com/admin! orbital-sync_1 | 12/6/2024, 4:44:46 PM: ➡️ Updating gravity on https://dns-s1.example.com/admin... orbital-sync_1 | 12/6/2024, 4:44:49 PM: ✔️ Gravity updated on https://dns-s1.example.com/admin! orbital-sync_1 | 12/6/2024, 4:44:49 PM: ✔️ Success: 1/1 hosts synced. orbital-sync_1 | 12/6/2024, 4:44:49 PM: Waiting 10 minutes...```