← Back to list

Easily install Pi-Hole on a Synology NAS

I wanted to test Pi-Hole on my LAN, and the best option was to use my NAS (Synology DS223J), but simply using the default container didn’t…

Andrea Dalseno · 2025-12-25 23:05 · 0 claps · 3.3 min read
#pihole #nas #synology #dns
Open on Medium ↗
Wiki topics: ☁️ · DevOps & Cloud

Easily install Pi-Hole on a Synology NAS

I wanted to test Pi-Hole on my LAN, and the best option was to use my NAS (Synology DS223J), but simply using the default container didn’t work.

The best solution was to use some shell commands (via SSH) to set up a macvlan for the container using Docker. This way, the container has its own IP address and does not interfere with any other ports or services on the NAS.

So log into the NAS via SSH (the port 22 must be open) and create the macvlan for the container (Docker and Container Manager must be installed on the NAS):

sudo docker network create -d macvlan \
 - subnet=192.168.1.0/24 \
 - gateway=192.168.1.1 \
 -o parent=eth0 \
 pihole_macvlan

Where the subnet matches your actual subnet and the gateway points to your gateway (usually the router), pay attention to the interface: it may be something different than *eth0*, such as *ovs_eth0*. Check it with *ip addr*.

Then go into the folder used by Docker, usually under /volume1/docker, and create the following folders:

mkdir -p /volume1/docker/pihole/etc-pihole
mkdir -p /volume1/docker/pihole/etc-dnsmasq.d

Open your Container Manager and create a new project named pihole (or whatever you like) with the path to the created folder, and create a new YAML file like this:

version: "3.9"

services:
  pihole:
    image: pihole/pihole:latest
    container_name: pihole
    hostname: pihole
    networks:
      pihole_macvlan:
        ipv4_address: 192.168.1.5

    environment:
      TZ: Europe/Berlin
      FTLCONF_webserver_api_password:: set-a-strong-password
      DNSMASQ_LISTENING: all
      FTLCONF_LOCAL_IPV4: 192.168.1.5

    volumes:
      - /volume1/docker/pihole/etc-pihole:/etc/pihole
      - /volume1/docker/pihole/etc-dnsmasq.d:/etc/dnsmasq.d

    restart: unless-stopped

networks:
  pihole_macvlan:
    external: true

The script above is taken from the PiHole GitHub repo. Check it, since new versions may use different naming conventions (ver. 2025.11.1 at the time of writing).

Use the local IP for your DNS (not in the range of your DHCP server, usually on the router), the TZ is your local zone, and the password is a strong password of your choice (keep it on hand since you will need it to log in).

Do not start the container yet. Pi-hole automatically generates a local certificate, but your browsers will not recognize it. It’s not a big issue; you can manually add the file or, better, create a root CA for your system with mkcert (you may also opt for a more complex solution like step-ca, but I guess you won’t be reading this post in that case). For my local LAN, I used the internal domain, suited for this usage. On my laptop (Linux), I installed mkcert using the package manager and then:

mkcert -install
mkcert pihole.internal
cat pihole.internal.pem pihole.internal-key.pem > tls.pem

I created the certificates in a dedicated folder, with a subfolder for each service (they must be manually copied to the correct location; the root CA lasts for 10 years, and the server certificates for 27 months). Now the tricky part. Pi-hole looks into the etc/pihole folder, and if it does not find a tls.pem file, it will create a new certificate. So copy the tls.pem into the pihole/etc-pihole folder, assign it to the pihole user and group (by default 1000:1000), set the permission to 640, and you are ready to start the container.

cd /volume1/docker/pihole/pihole-etc
sudo chown 1000:1000 tls.pem
sudo chmod 640 tls.pem

Now you must set your DHCP server to use the IP address of your new DNS server (in the example above, 192.168.1.5) so that each client automatically receives the correct DNS configuration.

From a client, check that everything is working fine:

nslookup google.com 192.168.1.5

You should receive a reply like this:

Server:         192.168.1.5
Address:        192.168.1.5#53

Non-authoritative answer:
Name:   google.com
Address: 172.217.18.46
Name:   google.com
Address: 2a00:1450:4006:801::200e

Then, in the browser, go to https://192.168.1.5/admin and type the password.

Chrome will complain about the certificate: it’s normal, and you likely will also have a warning in the Pi-hole interface. We must fix the server name and create our local names.

Go to the Settings menu, then choose Local DNS Records, and add your PiHole record: pihole.internal as the domain and 192.168.1.5 as the IP.

Then go to Settings, choose All settings -> Webserver/API, and set the name to pihole.internal

Log out, close the browser, and check that the name resolves fine:

nslookup pihole.internal

You should see a reply like this:

Server:         127.0.0.53
Address:        127.0.0.53#53

Non-authoritative answer:
Name:   pihole.internal
Address: 192.168.1.5

Open the browser and go to https://pihole.internal/admin

You should have a secure connection. Chrome may have cached the certificate, and you may need to clear it if it complains: go to chrome://net-internals/#hsts and, in the last textbox, enter pihole.internal, then press Delete. Close the browser and open it again. It should work fine.

I set a low database value to keep memory usage under control, and the footprint is reasonable: FTL uses less than 2% of the RAM. CPU usage is also tiny, but it may spike suddenly when the DNS is searching.


메타데이터
post_id
cf22bc898d17
slug
easily-install-pi-hole-on-a-synology-nas-cf22bc898d17
url
https://medium.com/@adalseno/easily-install-pi-hole-on-a-synology-nas-cf22bc898d17
canonical_url
https://medium.com/@adalseno/easily-install-pi-hole-on-a-synology-nas-cf22bc898d17
author_url
https://medium.com/@adalseno
status
ok
fetched_at
2026-07-13 22:28:34