Skip to content

Instantly share code, notes, and snippets.

@jeff47
Created September 8, 2025 12:37
Show Gist options
  • Select an option

  • Save jeff47/2b6e6245632b979b33fd098377403bbc to your computer and use it in GitHub Desktop.

Select an option

Save jeff47/2b6e6245632b979b33fd098377403bbc to your computer and use it in GitHub Desktop.
Automate pihole backups with teleporter

In Pihole v6+, the teleporter commandline interface moved to pihole-FTL. It outputs to a zip file in the current directory, which needs to be dealt with if you are running this in a docker container.

I run two piholes: one for my general network, and a special one for kids.

In your docker-compose.yml, add a volumes line mapping the directory on the host you want to store the teleporter files to the directory /teleporter in the docker container. In my case, those are ./pihole-teleporter/ and ./kidspi-teleporter/, off my home directory. Edit the script if you want to move them or rename them.

#!/bin/bash

DOCKER_FILE="${HOME}/docker-compose.yml"
PIHOLES="pihole kidspi" # Needs to match the container name(s) of your pihole(s)
KEEP_COPIES=4 # Will keep the X most recent

# No user options below this line.
KEEP_COPIES=$((KEEP_COPIES + 1)) # Need to add one for the tail command to work correctly
INTERACTIVE=false
[ -t 1 ] && INTERACTIVE=true

run() {
        if [ "$INTERACTIVE" = true ]; then
                "$@"
        else
                "$@" >/dev/null # If this is not an interactive terminal, hide stdout
        fi
}

for PIHOLE in ${PIHOLES}; do
        $INTERACTIVE && echo "Backing up ${PIHOLE}..."
        BACKUP_DIR="${HOME}/${PIHOLE}-teleporter"
        run docker compose -f "${DOCKER_FILE}" exec -it -w /teleporter "${PIHOLE}" pihole-FTL --teleporter

        if [ -d "$BACKUP_DIR" ]; then
                cd "$BACKUP_DIR" || continue
                # Delete old backups, always quiet unless an error occurs
                run ls -1t pi-hole_${PIHOLE}_teleporter_*.zip | tail -n +${KEEP_COPIES} | xargs -r rm --
        fi

done

This script can be run in cron.

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