Documentation Index
Fetch the complete documentation index at: https://mintlify.com/damianiglesias/pihole-ubuntu-deploy/llms.txt
Use this file to discover all available pages before exploring further.
deploy.sh is the main installer script for Pi-hole Ubuntu Deploy (version 4.1, authored by Damian Iglesias). It must be run as root (sudo ./deploy.sh) and performs a fully interactive, sequential installation with [y/n] prompts for each optional component.
Usage
Requirements
- Must be run as root (
EUIDcheck — exits with error if not root) - Internet connection required — the script pings
8.8.8.8before proceeding; if no response, the installer exits with a fatal error - OS: Ubuntu Server 20.04, 22.04, or 24.04 (LTS recommended)
- Minimum resources: 512 MB RAM, 1 CPU core
Installation Steps Reference
Every numbered step indeploy.sh is listed below in execution order.
| Step | Label | What it does |
|---|---|---|
| 1 | Network Prep | Stops and disables systemd-resolved, overwrites /etc/resolv.conf with 8.8.8.8 and 1.1.1.1, then pings 8.8.8.8 to verify internet connectivity |
| 2 | Dependencies | Runs apt-get update then installs: curl, net-tools, ufw, sqlite3, wget, python3, python3-venv, python3-pip, git |
| 3 | Pi-hole Install | Runs the official Pi-hole installer via curl -sSL https://install.pi-hole.net | bash; verifies success with a command -v pihole check |
| 3.5 | Blocklists (opt) | Injects 3 blocklists directly into gravity.db via sqlite3, then runs pihole -g to rebuild gravity |
| 4 | Password | Prompts for a web admin password with confirmation loop; applies it via pihole setpassword, then restarts pihole-FTL |
| 4.5 | Unbound (opt) | Installs unbound, downloads root.hints from internic.net to /var/lib/unbound/, writes /etc/unbound/unbound.conf.d/pi-hole.conf, restarts unbound |
| 4.8 | PADD (opt) | Downloads padd.sh from GitHub to /usr/local/bin/padd, makes it executable; optionally appends an SSH auto-start line to ~/.bashrc |
| 4.9 | DNS Manager (opt) | Clones pihole_dns from Codeberg to /opt/pihole-dns-manager/, creates a Python venv, installs requests, generates run_dns_sync.sh |
| 4.7 | Log2Ram (opt) | Adds the Azlux APT repository, installs log2ram; activates on next reboot |
| 5 | Firewall | Runs ufw allow 22/tcp, ufw allow 53, ufw allow 80/tcp; enables UFW non-interactively |
| 6 | Static IP | Lists network interfaces, prompts for selection, detects current IP and gateway, writes /etc/netplan/99-pihole-static.yaml, applies with netplan apply |
Network Prep (Step 1)
Before any packages are installed, the script frees port 53 by stopping
systemd-resolved and forces DNS to Google’s public resolvers so that apt and curl can reach the internet.Dependencies (Step 2)
Installs all required system packages in a single
apt-get call. Exits with error if apt-get update fails.Pi-hole Core Install (Step 3)
Runs the official Pi-hole installer. The script pauses and asks the user to press After the installer finishes, the script verifies Pi-hole is available with:
[ENTER] before launching, instructing them to accept defaults in the blue TUI screens.Password Setup (Step 4)
Prompts for a new admin password with a masked input loop that re-prompts on mismatch or empty input. The password is passed directly to
pihole setpassword and pihole-FTL is restarted.Firewall (Step 5)
Configures UFW with the minimum required rules for Pi-hole operation, then enables it:
Optional Component Prompts
Each optional component is gated behind a[y/n] prompt. The table below lists each prompt in the order it appears, the shell variable that stores the answer, and what is installed.
| Prompt | Variable | What it installs |
|---|---|---|
Install Advanced Lists? [y/n] | list_choice | 3 blocklists injected into gravity.db via sqlite3 |
Install Unbound? [y/n] | unbound_choice | unbound package, root.hints, /etc/unbound/unbound.conf.d/pi-hole.conf |
Install PADD dashboard? [y/n] | padd_choice | /usr/local/bin/padd |
Auto-start PADD on SSH login? [y/n] | auto_padd | SSH conditional appended to ~/.bashrc |
Install DNS Manager tool? [y/n] | dns_tool_choice | /opt/pihole-dns-manager/ Python environment |
Install Log2Ram? [y/n] | log2ram_choice | log2ram via Azlux APT repository |
Set this IP as STATIC? [y/n] | static_choice | /etc/netplan/99-pihole-static.yaml |
Blocklist URLs
These three blocklists are injected into Pi-hole’sgravity.db when the Advanced Lists option is selected (Step 3.5).
| URL | Label |
|---|---|
https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts | StevenBlack Unified |
https://v.firebog.net/hosts/AdguardDNS.txt | Adguard Mobile |
https://v.firebog.net/hosts/Easyprivacy.txt | EasyPrivacy Tracking |
INSERT OR IGNORE to avoid duplicates, then pihole -g is run to rebuild the gravity database.
Generated Files
deploy.sh creates or modifies the following files on the system. Files marked (opt) are only created when the corresponding component is selected.
| File | Created by | Notes |
|---|---|---|
/etc/resolv.conf | Step 1 | Overwritten with nameserver 8.8.8.8 and nameserver 1.1.1.1 |
/etc/pihole/gravity.db | Step 3.5 (opt) | Blocklist rows injected via sqlite3 |
/etc/unbound/unbound.conf.d/pi-hole.conf | Step 4.5 (opt) | Unbound configuration listening on 127.0.0.1:5335 |
/var/lib/unbound/root.hints | Step 4.5 (opt) | Root nameserver hints downloaded from internic.net |
/usr/local/bin/padd | Step 4.8 (opt) | PADD terminal dashboard executable |
~/.bashrc | Step 4.8 (opt) | SSH auto-start line appended (only if PADD + auto-start both selected) |
/opt/pihole-dns-manager/ | Step 4.9 (opt) | DNS Manager project directory with Python venv |
/opt/pihole-dns-manager/run_dns_sync.sh | Step 4.9 (opt) | Launcher script with PIHOLE_URL and PIHOLE_PASSWORD pre-filled |
/opt/pihole-dns-manager/entries.txt | Step 4.9 (opt) | Sample DNS entries file (# Format: IP Domain) |
/etc/apt/sources.list.d/azlux.list | Step 4.7 (opt) | Azlux APT repository for Log2Ram |
/etc/netplan/99-pihole-static.yaml | Step 6 (opt) | Static IP Netplan configuration (mode 0600) |
/etc/netplan/backup/ | Step 6 (opt) | Backup of pre-existing Netplan YAML files |
Unbound Configuration (pi-hole.conf)
When Unbound is installed, the following configuration is written to/etc/unbound/unbound.conf.d/pi-hole.conf:
Netplan Static IP Configuration
The generated Netplan file uses the detected interface name, current IP, and gateway. Nameservers are set to8.8.8.8 (fallback) and 127.0.0.1 (Pi-hole itself).
Legacy Scripts
Thelegacy_scripts/ directory contains two standalone scripts that pre-date deploy.sh. They are not called by deploy.sh and are kept for reference.
install_prep.sh
A minimal preparation script. It runs This is the simplest possible Pi-hole install with no automation beyond the Pi-hole TUI wizard.
apt update, installs curl and net-tools, then immediately launches the official Pi-hole installer:firewall_rules.sh
A standalone UFW configuration script. It opens the three ports required for Pi-hole operation and enables the firewall:Use this script if you installed Pi-hole manually and need to configure UFW independently.