# internet-pi: a Raspberry Pi internet monitor and Pi-hole setup driven by Ansible

> geerlingguy/internet-pi bundles Pi-hole, Prometheus, Grafana and speedtest containers into one Ansible playbook for a Raspberry Pi that watches your connection. The README is honest about the metered-data cost and the hardware floor.

**geerlingguy/internet-pi** — Raspberry Pi config for all things Internet.

- Repository: https://github.com/geerlingguy/internet-pi
- Stars: 4,711 · Forks: 488
- Language: Jinja
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/geerlingguy-internet-pi

## What internet-pi actually assembles, and for whom

The project exists because its author had a couple of Pis doing random Internet-related duties and wanted their DNS, ad-blocking and monitoring configs formalized into one Ansible project. That framing matters: this is not a monitoring agent you install on a fleet, it is a single-node configuration for one machine that sits between your network and your ISP.

The audience is narrow and clear. You need a Raspberry Pi 4 model B or better, because the README states the Pi 4 and later generations include a full gigabit network interface and enough I/O to reliably measure fast connections. Older Pis work but the README calls out slower CPUs and NICs that cap speed tests at 100 Mbps or 300 Mbps on the Pi 3 model B+. If your goal is a truthful number for a 500 Mbps line, a Pi 3 will lie to you.

What you get in one run is Pi-hole for network-wide ad-blocking and local DNS, Prometheus and Grafana for monitoring, and Docker containers that run Speedtest.net speedtests and HTTP tests so uptime, ping stats and speedtest results accumulate over time. Three optional exporters come disabled by default: Shelly Plug power monitoring, AirGradient air quality, and Starlink statistics. Each is switched on through variables in config.yml, which keeps the default footprint small.

## How the Ansible playbook wires Prometheus, Grafana and Pi-hole together

The repository layout tells you most of the architecture. main.yml is the entry point, tasks/ holds the playbook logic, templates/ holds generated configuration, files/ holds static content, and internet-monitoring/ is a self-contained directory for the monitoring stack. requirements.yml declares external Ansible collections that must be installed before the first run.

The data flow is conventional pull-based monitoring. Prometheus scrapes exporters on a schedule; Grafana reads Prometheus and renders the Internet connection dashboard. The README notes that default Prometheus job configurations ship out of the box, and that you extend them with the prometheus_extra_scrape_configs variable, which appends a block of text to the end of scrape_configs. That is a deliberate escape hatch rather than a full templating system, and it means anything you add lives as raw YAML inside a variable.

Targets are handled separately. prometheus_node_exporter_targets is a list whose first entry is nodeexp:9100 for the main Pi, and the README shows adding another host such as another-server.local:9100 to monitor additional machines on the node exporter dashboard. Note the naming: the container is referenced as nodeexp, not localhost, which is the kind of detail that breaks a copy-pasted config.

Pi-hole sits alongside rather than inside that pipeline. It handles DNS and blocking, and the README is explicit that you must update your network router config to direct all DNS queries through the Raspberry Pi for Pi-hole to be effective. Nothing in this project changes your router for you.

## Installing internet-pi and getting the Grafana dashboard up

Setup assumes Ansible is not yet present. The README recommends Pip, with an apt step first on Pi or Debian, and it warns about the externally-managed-environment error that modern Debian derivatives raise.

```bash
sudo apt-get install -y python3-pip
pip3 install ansible
export PATH=$PATH:~/.local/bin
```

After that, clone the repository and install the declared collections. The README notes that if ansible-galaxy is not found, restarting the SSH session or rebooting the Pi usually fixes it.

```bash
git clone https://github.com/geerlingguy/internet-pi.git
cd internet-pi
ansible-galaxy collection install -r requirements.yml
```

Two files must be copied and edited before the playbook runs. example.inventory.ini becomes inventory.ini, where you replace the IP address with your Pi's IP, or comment that line and uncomment the connection=local line if you are running on the Pi itself. example.config.yml becomes config.yml, and that is where pihole_password, monitoring_grafana_admin_password and the optional feature flags live.

```bash
cp example.inventory.ini inventory.ini
cp example.config.yml config.yml
ansible-playbook main.yml
```

When the run finishes, Pi-hole is reachable at the Pi's IP with /admin appended, and Grafana listens on port 3030 with username admin. The dashboard is under Dashboards, then Browse, then the Internet connection dashboard. One detail worth remembering: monitoring_grafana_admin_password is only applied the first time Grafana starts, so later changes must go through Grafana's admin UI.

## The metered-connection warning and other real limits

The README carries a warning in bold: if you use the included internet monitoring, it will download a decently-large amount of data through your Internet connection on a daily basis, and you should not use it, or should tune the internet-monitoring setup to run speedtests less often, on a metered connection. That is the single most consequential limitation here. A speedtest tool that measures your line is, by definition, consuming it.

There is a permissions trap when running locally. The README describes errors like "Error while fetching server API version" or "connect: permission denied", and recommends rebooting or logging out and back in, then running the playbook again. If the Docker socket error persists, the fix is adding your user to the docker group with sudo usermod -aG docker $USER. That grants effective root-equivalent access to the Docker daemon, which is a real security trade-off, not a formality.

Portability is limited by testing, not by design. The README says other computers and VMs may run this configuration but that it is only regularly tested on a Raspberry Pi, tested against Raspberry Pi OS in both 64-bit and 32-bit, and that it should also work with Ubuntu for Pi or Arch Linux without having been tested there. If you are deploying on an x86 mini PC, you are outside the tested path.

The wrong tool case is a network where Pi-hole already runs and you do not want it touched. The README offers a way out: an existing Pi-hole installation can be left unaltered by setting pihole_enable: false in config.yml. Without that flag, the playbook proceeds with this project's installation.

## Updating Pi-hole versus updating the rest of the stack

The README documents the Pi-hole upgrade path and stops there. The commands change into the Pi-hole directory, pull the latest images, and the excerpt ends mid-procedure, so treat the remaining steps as something to confirm in the repository rather than assume.

```bash
cd ~/pi-hole
docker compose pull
```

What is missing is equally informative. The README does not document how to update the Grafana, Prometheus or speedtest containers, nor does it describe rolling back a playbook run that changed a working configuration. Because the project is Ansible-driven, re-running ansible-playbook main.yml is the implied update mechanism for everything the playbook manages, but the README does not state that as a procedure, and it does not describe idempotency guarantees.

Maintenance cost therefore splits in two. Pi-hole has an explicit, documented upgrade path. The monitoring stack has an implicit one. If you need a documented rollback story before you touch a production DNS resolver, this project does not provide it, and you should not pretend otherwise. The last push to the repository was on 2026-08-23, so the codebase has moved recently, but that says nothing about whether a given upgrade will preserve your config.yml customizations.

## Licence, and where internet-pi sits against a hand-built stack

The project is MIT licensed, which is permissive and imposes no copyleft obligation on your own configuration. That matters less than it sounds, because what you are really shipping is a set of Ansible tasks and templates around third-party software. Pi-hole, Prometheus, Grafana and the various exporters carry their own licences, and the playbook pulls them in as containers or packages. The MIT licence on this repository does not extend to those components, and the README does not enumerate their terms. Checking each component's licence is your job, and this is not legal advice.

The honest alternative is to assemble the same stack by hand. A manual build means installing Pi-hole directly, writing your own prometheus.yml, provisioning Grafana dashboards and data sources, and adding a speedtest exporter container yourself. The difference in approach is ownership of the glue: with internet-pi the glue is Ansible tasks and Jinja templates maintained by someone else, and with a hand build the glue is yours and nothing reconfigures it behind your back. The manual route also removes the Pi 4 hardware assumption, since you are no longer bound to what the playbook tests against.

The counter-argument is maintenance. A hand-built Grafana dashboard drifts; the internet-monitoring directory here ships the dashboard and the scrape configuration together, so the panels and the metrics they read move as one unit. That coupling is the actual product.

## Frequently asked questions about internet-pi

The questions below cover the decisions people face before running the playbook: which hardware, whether it is safe on a metered line, and how to keep an existing Pi-hole installation intact.

## Conclusion

Adopt internet-pi if you have a spare Pi 4 or newer, an unmetered connection, and you want Pi-hole plus a Grafana internet dashboard without assembling the stack yourself. Skip it on a metered link, a Pi 3, or a machine where you already run a hand-tuned Pi-hole and Prometheus setup, because the playbook will reconfigure what it finds unless pihole_enable is false. Before the first run, verify the Pi's IP in inventory.ini, copy example.config.yml to config.yml, and confirm the Grafana dashboard appears on port 3030 and the Pi-hole admin page loads at /admin.

## FAQ

### Which Raspberry Pi model does internet-pi require?

The README recommends a Raspberry Pi 4 model B or better, because the Pi 4 and later generations have a full gigabit network interface and enough I/O to measure fast connections reliably. Older Pis work but slower CPUs and NICs limit speed tests to 100 Mbps or 300 Mbps on the Pi 3 model B+.

### Can I run internet-pi on a metered internet connection?

The README warns that the included internet monitoring downloads a decently-large amount of data daily, and advises against using it or tuning the internet-monitoring setup to run speedtests less often on a metered connection.

### How do I keep my existing Pi-hole installation when using internet-pi?

Set pihole_enable: false in config.yml. The README states that an existing Pi-hole installation can be left unaltered by disabling the setup of this project's installation.

### How do I reach the Grafana dashboard after running internet-pi?

Visit the Pi's IP address on port 3030 and log in as admin with the monitoring_grafana_admin_password from config.yml. The Internet connection dashboard is under Dashboards, then Browse.

### How do I add more scrape targets to the Prometheus setup?

Use the prometheus_extra_scrape_configs variable to append a block to scrape_configs, and add hosts to prometheus_node_exporter_targets after the nodeexp:9100 entry for the main Pi.

## Sources

- [geerlingguy/internet-pi on GitHub](https://github.com/geerlingguy/internet-pi)
- [Issues](https://github.com/geerlingguy/internet-pi/issues)
- [License: MIT](https://github.com/geerlingguy/internet-pi/blob/master/LICENSE)
- [README](https://github.com/geerlingguy/internet-pi/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/geerlingguy-internet-pi
