Feuerfest

Just the private blog of a Linux sysadmin

Using nebula-sync to synchronize your Pi-hole instances

As I have 2 running Pi-hole instances I have the problem of keeping them in sync. I do want all local DNS entries to be present on both. Also I do want the same filter lists, exceptions, etc.

Entering: nebula-sync. After Pi-hole released version 6 and made huge changes towards the architecture & API, the often used gravity-sync stopped working and was archived.

As nebula-sync can be run as a docker image the setup is fairly easy.

I just logged into my Portainer instance and spun up a new stack with the following YAML. I disable the gravity run after nebula-sync as this currently breaks the replica. The webserver process is killed and doesn't come back. Hence no connections to port 80 (HTTP) or 443 (HTTPS) are possible and therefore the API can't be reached either.

This is currently investigated/worked on in the following issue: Pi-hole FTL issue #2395: FTL takes 5 minutes to reboot?

---
services:
  nebula-sync:
    image: ghcr.io/lovelaze/nebula-sync:latest
    container_name: nebula-sync
    environment:
    - PRIMARY=http://ip1.ip1.ip1.ip1|password1
    - REPLICAS=http://ip2.ip2.ip2.ip2|password2
    - FULL_SYNC=true
    - RUN_GRAVITY=false   # running Gravity after sync breaks the replica, see: https://github.com/pi-hole/FTL/issues/2395
    - CRON=*/15 * * * *
    - TZ=Europe/Berlin

And if everything works we see the following:

2025-05-26T16:01:24Z INF Starting nebula-sync v0.11.0
2025-05-26T16:01:24Z INF Running sync mode=full replicas=1
2025-05-26T16:01:24Z INF Authenticating clients...
2025-05-26T16:01:25Z INF Syncing teleporters...
2025-05-26T16:01:25Z INF Syncing configs...
2025-05-26T16:01:25Z INF Running gravity...
2025-05-26T16:01:25Z INF Invalidating sessions...
2025-05-26T16:01:25Z INF Sync completed

When I did have RUN_GRAVITY=true in my stack I would always see the first sync succeeding. This run would however kill the webserver - hence the API isn't reachable any more and the nebula-sync container would only log the following error message:

2025-05-26T16:34:29Z INF Starting nebula-sync v0.11.0
2025-05-26T16:34:29Z INF Running sync mode=full replicas=1
2025-05-26T16:34:29Z INF Authenticating clients...
2025-05-26T16:34:31Z INF Syncing teleporters...
2025-05-26T16:34:31Z INF Syncing configs...
2025-05-26T16:34:31Z INF Running gravity...
2025-05-26T16:34:31Z INF Invalidating sessions...
2025-05-26T16:34:31Z INF Sync completed

2025-05-26T16:35:00Z INF Running sync mode=full replicas=1
2025-05-26T16:35:00Z INF Authenticating clients...
2025-05-26T16:35:02Z INF Invalidating sessions...
2025-05-26T16:35:04Z WRN Failed to invalidate session for target: http://ip2.ip2.ip2.ip2
2025-05-26T16:35:04Z ERR Sync failed error="authenticate: http://ip2.ip2.ip2.ip2/api/auth: Post \"http://ip2.ip2.ip2.ip2/api/auth\": dial tcp ip2.ip2.ip2.ip2:80: connect: connection refused"

Tag: Pi-hole