Pi-hole Maintenance and Advanced Configuration
After the Pi is set up and running, use this page as a reference for running manual updates, configuring backups of your Pi configuration, or to use a USB drive to store logs.
All of these sections are optional.
Update Pi-hole
Section titled “Update Pi-hole”Update the Pi-hole software and refresh the Gravity database with updated lists.
Run these whenever Pi-hole releases a new version, or after adding or changing blocklists.
sudo pihole -uppihole -gBack Up Your Configuration
Section titled “Back Up Your Configuration”Pi-hole’s Teleporter exports your full configuration: blocklists, allowlists, custom domains, regex rules, DNS settings, and DHCP config.
- In the Pi-hole web interface, go to Settings > Teleporter.
- Select Export to download a backup file.
To restore after a rebuild or SD card failure, use the Import option on the same page and select the backup file.
Re-export after making significant changes to lists or settings. Store the backup file somewhere other than the Pi, such as on your local computer, a NAS, or cloud storage.
Advanced Pi-hole Configuration with pihole.toml
Section titled “Advanced Pi-hole Configuration with pihole.toml”If you need to configure Pi-hole’s DNS behavior outside the web interface, edit /etc/pihole/pihole.toml directly.
After editing, restart the FTL service to apply changes:
sudo systemctl restart pihole-FTLpihole-FTL is the core Pi-hole system service.
It needs to be restarted when you make core configuration changes.
Example: change upstream DNS
Section titled “Example: change upstream DNS”In the [dns] section of pihole.toml:
[dns]upstreams = ["127.0.0.1#5335", "1.1.1.1"] # unbound on localhost, Cloudflare backupOr for Cloudflare directly:
[dns]upstreams = ["1.1.1.1", "1.0.0.1"]Reference: full pihole.toml
Section titled “Reference: full pihole.toml”This is the full pihole.toml from my setup, with comments stripped and the password hash redacted.
Values marked ### CHANGED were modified from the Pi-hole default.
pihole.toml (v6.5, comments stripped)
# Pi-hole configuration file (v6.5)# Reference config - comments stripped, default values preserved for reference.# Values marked ### CHANGED were modified from the Pi-hole default.# To apply: copy to /etc/pihole/pihole.toml, then sudo systemctl restart pihole-FTL
[dns] upstreams = [ "127.0.0.1#5335", "1.1.1.1" ] ### CHANGED, default = [] CNAMEdeepInspect = true blockESNI = true EDNS0ECS = true ignoreLocalhost = false showDNSSEC = true analyzeOnlyAandAAAA = false piholePTR = "PI.HOLE" replyWhenBusy = "ALLOW" blockTTL = 2 hosts = [] domainNeeded = false expandHosts = false bogusPriv = true dnssec = false interface = "eth0" ### CHANGED, default = "" hostRecord = "" listeningMode = "LOCAL" queryLogging = true cnameRecords = [] port = 53 localise = true revServers = []
[dns.domain] name = "lan" local = true
[dns.cache] size = 10000 optimizer = 3600 upstreamBlockedTTL = 86400 rrtype = "ANY"
[dns.blocking] active = true mode = "NULL" edns = "TEXT"
[dns.specialDomains] mozillaCanary = true iCloudPrivateRelay = true designatedResolver = true
[dns.reply.host] force4 = false IPv4 = "" force6 = false IPv6 = ""
[dns.reply.blocking] force4 = false IPv4 = "" force6 = false IPv6 = ""
[dns.rateLimit] count = 1000 interval = 60
[dhcp] active = false start = "" end = "" router = "" netmask = "" leaseTime = "" ipv6 = false rapidCommit = false multiDNS = false logging = false ignoreUnknownClients = false hosts = []
[ntp] [ntp.ipv4] active = true address = ""
[ntp.ipv6] active = true address = ""
[ntp.sync] active = true server = "pool.ntp.org" interval = 3600 count = 8
[ntp.sync.rtc] set = false device = "" utc = true
[resolver] resolveIPv4 = true resolveIPv6 = true networkNames = true refreshNames = "IPV4_ONLY"
[database] DBimport = true maxDBdays = 91 DBinterval = 60 useWAL = true forceDisk = false
[database.network] parseARPcache = true expire = 91
[webserver] domain = "pi.hole" acl = "" port = "80o,443os,[::]:80o,[::]:443os" threads = 50 headers = [ "X-DNS-Prefetch-Control: off", "Content-Security-Policy: default-src 'none'; connect-src 'self'; font-src 'self'; frame-ancestors 'none'; img-src 'self'; manifest-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'", "X-Frame-Options: DENY", "X-XSS-Protection: 0", "X-Content-Type-Options: nosniff", "Referrer-Policy: strict-origin-when-cross-origin" ] serve_all = false advancedOpts = []
[webserver.session] timeout = 1800 restore = true
[webserver.tls] cert = "/etc/pihole/tls.pem" validity = 47
[webserver.paths] webroot = "/var/www/html" webhome = "/admin/" prefix = ""
[webserver.interface] boxed = true theme = "default-auto"
[webserver.api] max_sessions = 16 prettyJSON = false pwhash = "" ### CHANGED from default (use `sudo pihole setpassword` to set) totp_secret = "" app_pwhash = "" app_sudo = false cli_pw = true excludeClients = [] excludeDomains = [] maxHistory = 86400 maxClients = 10 client_history_global_max = true allow_destructive = true
[webserver.api.temp] limit = 60.000000 unit = "C"
[files] pid = "/run/pihole-FTL.pid" database = "/etc/pihole/pihole-FTL.db" tmp_db = "/etc/pihole/pihole-tmp.db" gravity = "/etc/pihole/gravity.db" gravity_tmp = "/tmp" macvendor = "/etc/pihole/macvendor.db" pcap = ""
[files.log] ftl = "/var/log/pihole/FTL.log" dnsmasq = "/var/log/pihole/pihole.log" webserver = "/var/log/pihole/webserver.log"
[misc] privacylevel = 0 delay_startup = 0 nice = -10 addr2line = true etc_dnsmasq_d = false dnsmasq_lines = [] extraLogging = false readOnly = false normalizeCPU = true hide_dnsmasq_warn = false hide_connection_error = false
[misc.check] load = true shmem = 90 disk = 90
[debug] database = false networking = false locks = false queries = false flags = false shmem = false gc = false arp = false regex = false api = false tls = false overtime = false status = false caps = false dnssec = false vectors = false resolver = false edns0 = false clients = false aliasclients = false events = false helper = false config = false inotify = false webserver = false extra = false reserved = false ntp = false netlink = false timing = false all = falseOffload Logs to a USB Drive
Section titled “Offload Logs to a USB Drive”The Pi-hole FTL database (pihole-FTL.db) grows continuously and can wear out an SD card over months.
Move the database and log file to a USB drive to protect the SD card and extend its life.
What you need
Section titled “What you need”- A USB flash drive
- The Pi running with Pi-hole installed
Mount the USB drive
Section titled “Mount the USB drive”-
Plug in the USB drive and find its device name:
From the Pi lsblkLook for a
/dev/that wasn’t there before, such as/dev/sdawith a partition at/dev/sda1. -
Get the partition’s UUID:
From the Pi sudo blkid /dev/sda1Copy the UUID value from the output.
-
Create a mount point:
From the Pi sudo mkdir -p /mnt/pihole-logs -
Add an entry to
/etc/fstabto auto-mount on boot. Open the file and add this line at the bottom, replacingYOUR-UUIDwith the UUID you copied:/etc/fstab UUID=YOUR-UUID /mnt/pihole-logs ext4 defaults,noatime 0 2Note that this example uses
ext4. If your USB drive is formatted as exFAT or NTFS instead of ext4, change the filesystem type accordingly.If you need to format the drive first
This will delete everything on the drive:
From the Pi sudo mkfs.ext4 /dev/sda1 -
Mount everything in fstab:
From the Pi sudo mount -aIf this returns an error, double-check the UUID and filesystem type in
/etc/fstab. -
Set ownership so Pi-hole’s FTL process can write to the drive:
From the Pi sudo chown pihole:pihole /mnt/pihole-logs
Point Pi-hole to the USB drive
Section titled “Point Pi-hole to the USB drive”-
Back up the current
pihole.toml:From the Pi sudo cp /etc/pihole/pihole.toml /etc/pihole/pihole.toml.bak -
Move the existing database to the USB drive (so you don’t lose query history):
From the Pi sudo systemctl stop pihole-FTLsudo mv /etc/pihole/pihole-FTL.db /mnt/pihole-logs/sudo mv /var/log/pihole/pihole.log /mnt/pihole-logs/ 2>/dev/null || true -
Edit
/etc/pihole/pihole.tomlto update the file paths. Find the[files]section and set:pihole.toml [files]database = "/mnt/pihole-logs/pihole-FTL.db"log = "/mnt/pihole-logs/pihole.log"If there is no
[files]section, add it at the end of the file. -
Start FTL and verify it comes up cleanly:
Terminal window sudo systemctl start pihole-FTLsudo systemctl status pihole-FTL -
Confirm the database is on the USB drive and growing:
From the Pi ls -lh /mnt/pihole-logs/ -
Reboot the Pi:
From the Pi sudo reboot now -
Verify that the USB drive mounts and Pi-hole starts correctly:
From the Pi lsblksystemctl status pihole-FTLThe FTL service won’t start if it can’t find the database file. DNS queries from all network devices will fail until the mount is fixed.
Optional: Set Pi-hole database retention
Section titled “Optional: Set Pi-hole database retention”By default, Pi-hole keeps 91 days of query history.
If you want to change the database size:
-
Set a the number of days to keep the database in
pihole.toml:pihole.toml [database]maxDBdays = 180 -
Restart FTL after changing this:
From the Pi sudo systemctl restart pihole-FTL