Nebula-Sync

Introduction

Nebula-Sync is a free and open source tool designed to synchronize the configuration of multiple Pi-hole v6.x instances. If you run multiple Pi-hole servers in your network for redundancy or different locations, Nebula-Sync ensures they all stay in sync automatically. You can choose between full synchronization using Pi-hole's Teleporter feature or selective synchronization of specific settings. The tool runs on a schedule you define and can be easily deployed using Docker.

The Docker Compose File

---
services:
  nebula-sync:
    image: docker.io/lovelaze/nebula-sync:latest
    container_name: nebula-sync
    hostname: nebula-sync
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    user: "1000"
    env_file:
      - .env
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
    networks:
      - proxy
    labels:
      - com.centurylinklabs.watchtower.enable=true
      - logging=promtail
      - logging_jobname=containerlogs

networks:
  proxy:
    external: true

docker-compose.yml

This Docker Compose file defines a single service named "nebula-sync". The service is built from the "lovelaze/nebula-sync:latest" Docker image, which is the latest version available. The container name is set to "nebula-sync" as well.

The "restart" section ensures that the container will always be restarted if it exits (unless manually stopped). This is useful for ensuring that the service is always available, especially if it crashes or is shut down unexpectedly.

The "security_opt" section prevents your container processes from gaining additional privileges. This is an important security consideration.

The "user" section runs the container as user ID 1000. This is particularly important when using Docker secrets, as the user needs read permissions to the secret files. You can adjust this to match your system's user ID if needed.

The "env_file" section loads environment variables from a separate .env file. This is the recommended approach for managing your Nebula-Sync configuration, as it keeps sensitive information like passwords separate from your docker-compose.yml file.

The "volumes" section maps timezone configuration files to ensure logs and cron schedules use your local timezone.

The "networks" section connects the container to an external network called "proxy". This allows Nebula-Sync to communicate with your Pi-hole instances.

The "labels" section allows the Watchtower service to keep this container updated automatically and configures Promtail logging for centralized log collection.

Nebula-Sync requires a few essential environment variables to function. Create a .env file in the same directory as your docker-compose.yml with the following configuration:

# Required settings
PRIMARY=http://ph1.example.com|password
REPLICAS=http://ph2.example.com|password,http://ph3.example.com|password
FULL_SYNC=true

# Optional settings
CRON=0 * * * *
RUN_GRAVITY=true
TZ=Europe/Stockholm

The PRIMARY variable specifies your primary Pi-hole instance, which serves as the source of truth for your configuration. The REPLICAS variable lists all secondary Pi-hole instances that should be synchronized, separated by commas.

When FULL_SYNC is set to true, Nebula-Sync performs a complete Teleporter import/export from the primary to all replicas. This ensures all settings and configurations are synchronized. If you prefer more granular control, you can set FULL_SYNC to false and use the selective sync options like SYNC_CONFIG_DNS, SYNC_CONFIG_DHCP, and others.

The CRON variable defines when synchronization should run. In this example, it runs at the top of every hour. The RUN_GRAVITY option tells Nebula-Sync to run gravity after syncing, which updates your Pi-hole blocklists.

Running Nebula-Sync with Docker Compose

To run Nebula-Sync with Docker Compose, first, make sure you have Docker and Docker Compose installed on your machine. Then, create a new directory for your project and save the above Docker Compose file as "docker-compose.yml" in that directory. Create your .env file with your Pi-hole configuration details.

Before starting, ensure your Pi-hole instances are accessible from the Nebula-Sync container and that you're using the correct passwords. If you're using Pi-hole's app passwords feature, make sure to enable the webserver.api.app_sudo setting on your replica servers to avoid authentication errors.

Next, run the following command from the same directory:

docker compose up -d

This command will start the Nebula-Sync container in the background and detach from it. The container will run according to your cron schedule and automatically synchronize your Pi-hole instances.

You can check the logs to verify synchronisation is working:

docker logs nebula-sync

Conclusion

In this article, we explored how to set up and run Nebula-Sync using Docker Compose. We looked at the different sections of the Docker Compose file and explained how they work together to create a functional synchronization service for your Pi-hole instances. By running Nebula-Sync with Docker Compose, you can easily maintain consistent configuration across multiple Pi-hole servers, ensuring your network-wide ad blocking and DNS filtering remains synchronized without manual intervention.