I’ve had and posted about working with Raspberry Pi’s before and recently bought the new Raspberry Pi 5. I picked mine up from CanaKit, and it’s almost complete silent! Woohoo! So I’m going to run this one running all the time and have it act like a server basically.

This post is about setting this up and tying it into Grafana Cloud for monitoring.


A couple basic ones:

  1. You’ve already put your Raspberry Pi, it’s connected to your network, you’re ready to rock.
  2. You’ve setup your Pi to have a static IP on your network. Most routers allow you to do this
  3. You’ve setup the grafana-agent on your Pi. Follow the docs in the instructions and it’ll give you a one-liner that’ll setup the apt repo.

Setting up the pihole and grafana monitoring

Get Docker, or whatever you want to use to run your containers up and running. As of the writing on this document, the package name is

$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION="12 (bookworm)"

Package names may change, but I’m just using Docker with docker-compose to get this up and running quickly:

sudo apt install docker-compose

(Optional) Personally, I like using the docker command from an unprivieged user to limit the need to run it as root. To do this, you’ll need to change your na

sudo usermod -aG docker pi # substitute pi with your user
newgrp docker pi # substitute pi with your user


For the configuration, I do a couple non-default things:

  1. I allow the Apple Private Relays to work and not be blocked. FTLCONF_BLOCK_ICLOUD_PR is how you pass that to the FTL config with pihole. Removing that line will block the relays.
  2. I use the Cloudflare malware blocking name servers instead of Google name servers.
  3. I use Farenheit for temperatures because I’m American.
  4. I use a dark theme for the pihole interface. Don’t most people prefer dark at this point?

This is what your docker-compose.yml could look like:

version: "3"

# More info at and
    container_name: pihole
    image: pihole/pihole:latest
    # For DHCP it is recommended to remove these ports and instead add: network_mode: "host"
      - "53:53/tcp"
      - "53:53/udp"
      - "80:80/tcp"
      PIHOLE_DNS_: ';;2606:4700:4700::1112;2606:4700:4700::1002' # Cloudflare
      DNSSEC: 'true'
      QUERY_LOGGING: 'false'
      WEBTHEME: 'default-dark'
      TZ: 'America/Chicago'
      WEBPASSWORD: 'Amaz1ngP4sswordF0rB1og' # This password is used in PIHOLE_PASSWORD, too
    # Volumes store your data between container upgrades
      - './etc-pihole:/etc/pihole'
      - './etc-dnsmasq.d:/etc/dnsmasq.d'
    # cap_add:
    #  - NET_ADMIN # Required if you are using Pi-hole as your DHCP server, else not needed
    restart: unless-stopped
  # See:
    container_name: 'pihole-exporter'
    image: 'ekofr/pihole-exporter:latest'
    # Agent is running in VM, so moved this config to ports
    # expose:
    #  - 9617
      - "" # So agent on VM can poll this service on localhost
      PIHOLE_HOSTNAME: ''  # UPDATE with the static IP of your Pi
      PIHOLE_PORT: 80
      PIHOLE_PASSWORD: 'Amaz1ngP4sswordF0rB1og' # Same as the password used on the pihold
      INTERVAL: 30s
      PORT: 9617
    restart: always

It’s in the file as comments, you need to copy the password for the pihole for the pihole_exporter service to be able to login to the pihole to get stats.

Now, bring it up!

docker-compose up -d

Validate the services are up and running and haven’t prematurely exited:

$ docker ps -a
CONTAINER ID   IMAGE                          COMMAND               CREATED         STATUS                   PORTS                                                                                                             NAMES
88f378db2b37   pihole/pihole:latest           "/s6-init"            4 minutes ago   Up 4 minutes (healthy)>53/tcp, :::53->53/tcp,>80/tcp,>53/udp, :::80->80/tcp, :::53->53/udp, 67/udp   pihole
9ae16022d83f   ekofr/pihole-exporter:latest   "./pihole-exporter"   4 minutes ago   Up 4 minutes   >9617/tcp

Test out your configuration by using tools like dig to query against the IP of you Pi from other machines on your network to make sure things are resolving:

$ dig @

; <<>> DiG 9.10.6 <<>> @
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50127
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1

; EDNS: version: 0, flags:; udp: 1232
;			IN	A

;; ANSWER SECTION:		75	IN	A		75	IN	A		75	IN	A		75	IN	A		75	IN	A		75	IN	A

;; Query time: 82 msec
;; WHEN: Sun Jan 21 11:01:46 CST 2024
;; MSG SIZE  rcvd: 135

Update your router

Now that you’ve verified your that your pihole is responding to DNS requests from another machine on your network, you can update your router to use the pihole! If you need at least two name servers, see the notes in the Google Fiber section on how to add another interface to your Pi.

Example Grafana Agent Config

This configuration is used so I can collect metrics from the Pi for a Linux dashboard as well as the pihole.

  - basic_auth:
      username: YOUR-GRAFANA-CLOUD-ID
    url: https://YOUR-GRAFANA-CLOUD-ENDPOINT/api/prom/push
    enabled: true
    - action: replace
      - agent_hostname
      target_label: instance
    - action: replace
      target_label: job
      replacement: "integrations/agent-check"
    - action: keep
      regex: (prometheus_target_sync_length_seconds_sum|prometheus_target_scrapes_.*|prometheus_target_interval.*|prometheus_sd_discovered_targets|agent_build.*|agent_wal_samples_appended_total|process_start_time_seconds)
      - __name__
  # Add here any snippet that belongs to the `integrations` section.
  # For a correct indentation, paste snippets copied from Grafana Cloud at the beginning of the line.
    enabled: true
    # drop extensive scrape statistics
    - action: drop
      regex: node_scrape_collector_.+
      source_labels: [__name__]
    - replacement: 'pi5'
      target_label: instance
    - replacement: integrations/raspberrypi-node
      target_label: job
  - clients:
    - basic_auth:
        password: YOUR-GRAFANA-CLOUD-TOKEN
        username: YOUR-GRAFANA-CLOUD-ID
      url: https://YOUR-GRAFANA-CLOUD-ENDPOINT/loki/api/v1/push
    name: integrations
      filename: /tmp/positions.yaml
      # Add here any snippet that belongs to the `logs.configs.scrape_configs` section.
      # For a correct indentation, paste snippets copied from Grafana Cloud at the beginning of the line.
  - name: integrations
    - basic_auth:
        password: YOUR-GRAFANA-CLOUD-TOKEN
        username: YOUR-GRAFANA-CLOUD-ID
    url: https://YOUR-GRAFANA-CLOUD-ENDPOINT/api/prom/push
      # Add here any snippet that belongs to the `metrics.configs.scrape_configs` section.
      # For a correct indentation, paste snippets copied from Grafana Cloud at the beginning of the line.
      - job_name: 'pihole'
          - targets: ['localhost:9617']
    scrape_interval: 60s
  wal_directory: /tmp/grafana-agent-wal

Google Fiber

Add Another Interface to your Pi

With the DNS setup as of January 2024, you can specify up to three IPv4 DNS servers, the minimum number of name servers you can set is two. You could run two piholes on two different machines… or you could just add another interface to your pi.

Find an IP that is not used. I use arp to check to see what IPs are used and will run ping against an IP I think is free, then run arp again to see if it shows up in the list.

When you have an IP selected, create a file in /etc/network/interfaces.d. If you have a fresh OS install, that directory is likely empty. I created a file called /etc/network/interfaces.d/eth01 and put the following in (sub out with the appropriate values for your network):

auto eth0:1
iface eth0:1 inet static
        metric 10

THen bring up the interface:

$ ifup eth0:1

You can’t set/override IPv6 name servers

This is flat frustrating. Most reputable routers allow this to be set out of the box.

You will get the Google IPv6 name servers and you can’t override it. I personally prefer to use Cloudflare name servers, specifically the a ones, which blocks malware. You will see some people prefer Cloudflare to reduce the amount of data Google can collect about you and your browsing habits.

I’ve contacted Google Fiber about this and asked them to do this. At this time, I’m not replacing the Google router or running the Raspberry Pi as a DHCP server. I might do this later. I will say, Google Fiber does provide great equipment by default if you do ever consider their services. With previous providers, my first step was to replace the stock modem and wireless router with my own.

Getting around this

  1. You can set devices to only use the pihole and remove the other name servers (not ideal)
  2. Run your own DHCP server, which means your own equipment. There’s not an option to turn off DHCP with Google Fiber.


Apple Private Relay

I didn’t expect for this to get blocked. I just hadn’t really thought about it, I could see for some folks this being an issue. Luckily with some research and digging through the FTL project, being able to set FTLCONF_BLOCK_ICLOUD_PR to false in my docker-compose.yml to resolve that issue to allow iPhones and other Apple devices to use private relay.

Some folks are worried about data going through Apple, I’m okay with it. When it comes to privacy, I do trust Cloudflare and Apple more than the other options available.

If you don’t disable the iCloud block, you’ll see popups that the private relay isn’t available on things like iPhones if you have that feature enabled.

Samsung TVs

I didn’t realize how much data my TV sends back to Samsung! It’s the top ad domain by specific domain.