
Je continue de profiter de mon nouveau NAS, et cette fois j’installe Pi-Hole dans un container Docker. Je vais ainsi pouvoir dédié mon Raspberry à Volumio, et éviter de devoir faire des modifications à l’image Volumio pour faire tourner Pi-Hole, ce qui me compliquait (ou même bloquait) les mises à jour (de l’un comme de l’autre). Une bonne chose à faire donc.
De plus, avec Pi-hole en mode Docker, va désormais télécharger automatiquement la dernière version (paramètre « latest ») à chaque démarrage. Les « Ads lists » seront également automatiquement mises à jour une fois par semaine. Ce qui est bien pratique, le serveur restera ainsi à jour en permanence.
Mais comme je l’utilise comme serveur DHCP, cela va poser quelques contraintes car il faudra que le serveur réponde aux messages DHCP qui passent en broadcast sur mon LAN. Or ce n’est pas le cas par défaut d’un container Docker (interface réseau en mode bridge). Il m’a donc fallu faire mon choix entre les solutions proposées pour le « network mode ». J’ai finalement opté pour la méthode macvlan, et j’expliquerai pourquoi et les contraintes de ce choix. J’avoue que je me suis bien pris la tête avec ça ! 😯
Pour le reste, tout a été assez facile à réaliser, une fois le bon fichier compose.yaml
configuré. En effet, pas mal de choses ont changé avec la v6, y compris les paramètres, etc… Et les tutos que l’on trouve concernent souvent la v5. D’ailleurs, cet article fait référence à la version Docker actuelle (2025.07.1) et donc Pi-hole v6.2.3.
C’est parti !
Pi-hole DHCP & Docker
Le principe de base de Docker, c’est d’isoler les containers, et donc par défaut c’est le mode bridge qui est utilisé et recommandé pour l’adaptateur réseau par défaut (le container passe par le host). Or les messages de type ‘broadcast’ utilisés par DHCP ne passeront pas sur le LAN, ce qui est nécessaire si l’on souhaite utiliser Pi-hole comme serveur DHCP.
En utilisant Pi-hole comme serveur DHCP, il va fournir aux clients l’adresse du serveur DNS en même temps que l’adresse IP, et ainsi tous les appareils de mon réseau sont automatiquement configurés comme je le souhaite, et bénéficieront du filtrage de Pi-hole, que ce soit la TV ou l’imprimante comme je peux le constater sur les stats Pi-hole :

Les modes réseau
Puisque je veux utiliser Pi-hole comme serveur DHCP dans un container Docker, je dois choisir un mode réseau. Les différentes possibilités sont décrites sur cette page.
- Le host networking mode est le plus simple à mettre en place, mais le serveur Pi-hole aura la même adresse IP que l’hôte (mon NAS), ce qui peut générer des conflits de ports avec le NAS.
- Le macvlan network mode attribuera sa propre adresse sur votre LAN au serveur Pi-hole. Il n’y a donc aucun problème de conflit de port à craindre. Le container ainsi créé pourra communiquer avec les machines sur mon LAN, mais par contre ne pourra pas communiquer avec les autres containers du NAS en mode bridge.
- Le bridge networking mode nécessite un DHCP relay sur le LAN qui va renvoyer le port 67 (DHCP) à Pi-hole. Cette solution permet de conserver le mode bridge mais nécessite une autre pièce logicielle sur le LAN et me semble donc plus complexe. Je ne l’ai pas essayée, mais cet article fournit un bon exemple sur sa réalisation (attention aux paramètres du fichier compose, ce n’est pas la v6).
J’ai donc choisi le mode macvlan, qui me paraissait le plus adapté à ce que je souhaitais. Par défaut, ce container ne pourra donc pas communiquer avec mes autres containers, puisqu’ils sont en mode bridge. Il est possible de contourner cette limitation, mais cela oblige à revoir pas mal de choses. Vous trouverez en fin d’article plus de détails sur le fonctionnement de cette interface macvlan, du pourquoi et du comment, c’est assez technique. Personnellement, je ne suis pas allé jusque là : finalement, seul mon tableau de bord Homepage était impacté par cette limitation, et franchement la meilleure solution était de s’en passer ! 😎
Création du macvlan network
Il faut donc commencer par créer une interface réseau de type macvlan pour le container Docker Pi-hole que l’on va ensuite créer. On peut utiliser l’interface d’OMV (dans Services-Compose-Networks), mais une commande Docker fera très bien l’affaire :
pascal@NAS-N150:~$ sudo docker network create --driver macvlan --attachable --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=enp1s0 macvlan-ntw
J’indique donc le driver souhaité (mavclan), puis les infos de mon LAN (subnet, gateway), le nom de l’interface réseau du NAS (enp1s0) et enfin je lui donne un nom (macvlan-ntw).
On retrouve l’interface créée dans OMV-Services-Compose-Networks, et on peut cliquer sur ‘Inspect’ pour en voir les détails.

Le container Pi-hole
On peut désormais créer le container pour Pi-hole. J’ai eu un peu de mal à trouver de bons tutos, avec les bons paramètres. Pour trouver les bonnes infos, il faut que le tuto concerne la v6 de Pi-hole, que ce soit une installation en mode Docker, et qu’enfin Pi-hole soit utilisé comme serveur DHCP.
Bref, voilà mon fichier compose.yaml
, à adapter à votre cas (UID, GID, adresse réseau, adresse mail, mot de passe, volumes). NOTE : j’utilise Dockge pour gérer mes containers.
On utilise bien sûr l’interface macvlan créée plus haut, et on définit une adresse statique pour le serveur Pi-hole (dans l’idéal, en dehors du range d’adresse que l’on va attribuer au serveur DHCP). Et on mappe les ports que l’on va utiliser, notamment le 53 (DNS), 80/443 (interface web) et 67 (DHCP).
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
ports:
# DNS Ports
- 53:53/tcp
- 53:53/udp
# Default HTTP Port
- 80:80/tcp
# Default HTTPs Port. FTL will generate a self-signed certificate
- 443:443/tcp
# Uncomment the below if using Pi-hole as your DHCP Server
- 67:67/udp
environment:
# Set the appropriate timezone for your location (https://en.wikipedia.org/wiki/List_of_tz_database_time_zones), e.g:
- TZ=Europe/Paris
- PIHOLE_UID=996
- PIHOLE_GID=100
- ADMIN_EMAIL=user@mail.com
# Set a password to access the web interface. Not setting one will result in a random password being assigned
- FTLCONF_webserver_api_password=xxxxxxxx
# Volumes store your data between container upgrades
volumes:
# For persisting Pi-hole's databases and common configuration file
- /srv/dev-disk-by-uuid-xxxxx-yyyy-zzzz-7697ca5/AppData/Pi-hole/etc-pihole:/etc/pihole
- /srv/dev-disk-by-uuid-xxxxx-yyyy-zzzz-7697ca5/AppData/Pi-hole/etc-dnsmask.d:/etc/dnsmask.d
cap_add:
- NET_ADMIN
restart: unless-stopped
networks:
macvlan-ntw:
ipv4_address: 192.168.x.y
networks:
macvlan-ntw:
external: true
Et voilà, il n’y a plus qu’à démarrer le container, et à se connecter via l’interface web à l’adresse http:pi.hole/admin/login
ou mieux https://<adresse ip pi-hole>/admin/login
.
Post-Installation
DNS
La première chose à faire, c’est de définir les DNS. Je choisis Cloudfare, que j’utilisais déjà avec la version précédente de Pi-hole :

À noter que j’avais dans un premier temps coché également les cases IPv6, mais cela me générait des erreurs dans les logs de Pi-hole :
WARNING: Connection error (2606:4700:4700::1111#53): failed to send UDP request (Network unreachable)
C’était parce que mon LAN est en IPv4 et que l’IPv6 est désactivé. Logique.
DHCP
Ensuite, on active le service DHCP, et on attribue un range d’adresse pour les différents appareils sur mon réseau, et je laisse bien sûr la box comme passerelle par défaut :

Dans l’exemple ci-dessus, je m’arrête donc à l’adresse 192.168.1.100, ce qui me laisse encore pas mal d’adresses de libres que je pourrai utiliser selon les besoins : adresse IP statique pour certains serveurs, nouveau range d’adresses pour d’autres besoins (voir en fin d’article le cas macvlan).
Toujours sur cette page (en mode expert), j’ai d’ailleurs assigné des adresses IP fixes aux élément de mon réseau, avec un bail infinite, histoire de me simplifier la vie :

Box SFR
Concernant la box et le décodeur TV, j’ai procédé de la même manière qu’avec la box orange, même si c’est susceptible de changer. Pour l’instant, ma box a toujours le service DHCP activé, mais seulement pour 2 adresses :

Et je démarre le décodeur TV avec le DHCP de Pi-hole arrêté pour que le décodeur obtienne l’adresse 192.168.1.2. Je l’ai même ajouté en adresse statique :

J’ai bien essayé de mettre la dernière adresse à 192.168.1.2 pour qu’il n’y ait qu’une seule adresse offerte par le serveur DHCP de la box, mais cela ne passe pas, l’adresse de début et de fin doivent être différentes. J’ai donc une adresse 192.168.1.3 disponible et qui peut être attribuée à un autre élément du réseau, ce que je ne souhaite pas, mais pour l’instant je n’ai pas d’autre solution. Ce n’est pas parfait, mais cela fonctionne.
Mais comme je le disais dans l’article sur mon passage à la fibre, j’ai vu que contrairement à Orange, la décodeur TV SFR accepte de recevoir son adresse IP du serveur Pi-hole. Cela me permettait même de regarder le Replay de M6 sans publicités (génial !), mais par contre le Replay de FranceTV ne fonctionnait plus du tout.
J’aimerais donc bien désactiver le serveur DHCP de la box, et de procéder par ajout dans la liste blanche de Pi-hole quand je lance le Replay de FranceTV ou quand j’ai une situation de blocage, et voir si cette solution est viable… Au mieux, j’arrive à faire fonctionner le tout en supprimant un certain nombres de publicités des différents services de Replay (et je n’ai qu’un seul serveur DHCP). Au pire, je reviens à la configuration actuelle.
Ads listes
Par défaut, Pi-hole est fourni avec une liste de sites de pubs ou de trackers à bloquer, et qui est déjà conséquente (~500 000). Il est recommandé de commencer avec cette liste, et de voir si elle convient. J’ai trouvé cet avis qui me paraît pertinent :
Je suggérerais d’utiliser la liste par défaut, et éventuellement d’autres listes qui sont mises à jour régulièrement. Beaucoup de listes se chevauchent, il y a donc probablement un point de rendement décroissant. De plus, vous pourriez commencer à découvrir que vous incorporez une liste qui bloque certains contenus que vous souhaiteriez voir, mais que le créateur de la liste ne veut pas voir.
Sinon, ce ne sont pas les articles qui manquent sur le sujet, et qui proposent tout un tas de listes. Comme dit ci-dessus, il est important qu’elles soient tenues à jour. J’ai tout de même noté qui semble être une bonne référence : https://firebog.net/.
Cerise sur la gâteau : la mise à jour de ces listes est automatisée par une tâche cron
dans le container Docker. Elle se déclenche une fois par semaine.
Problème avec Homepage
Le seul problème que j’ai rencontré est donc celui lié au mode réseau choisi (macvlan). Comme expliqué, avec ce type d’interface, on ne peut plus communiquer avec le host, et donc avec les autres containers en mode bridge. Or j’utilise Homepage comme tableau de bord de mes serveurs, qui tourne dans un autre container. Et donc quand j’ai voulu utiliser les fonctions « widget » de Homepage pour le serveur Pi-hole, qui doivent m’afficher des stats :

J’avais un beau message d’erreur à la place, et le « ping » ne fonctionnait pas non plus :

Comme expliqué plus haut, je préfère m’en passer que de revoir toute la configuration réseau de mes containers. Je garde juste la définition du serveur Pi-hole dans le dashboard, sans widget ou ping, afin de pouvoir y accéder rapidement d’un clic, ce qui est mon utilisation essentielle de ce dashboard.

Tout fonctionne donc concernant le serveur Pi-hole.
L’adaptateur macvlan en détail
De tout ce qui a été dit plus haut, il est intéressant de revenir sur cet adaptateur macvlan, et de l’expliquer en détail, y compris comment on peut contourner sa limitation, à savoir qu’il est impossible de communiquer avec le host (donc le NAS en ce qui me concerne).
Les bases
Par défaut les containers Dockers utilisent donc le mode bridge, c’est-à-dire qu’ils vont utiliser l’interface réseau du host et ce dernier s’occupera de transmettre les messages aux containers. Pour le reste, le réseau est isolé par sécurité, c’est une des caractéristiques de Docker.
En mode macvlan, on assigne une adresse MAC à un container (et aussi une adresse IP). Pour ce faire, il faut que l’adaptateur réseau de l’hôte accepte le « promiscuous mode » (où une interface physique peut se voir attribuer plusieurs adresses MAC). L’hôte Docker accepte dès lors les demandes pour plusieurs adresses MAC, et achemine ces demandes vers le conteneur approprié. Dit autrement : le type de réseau macvlan vous permet de créer des « clones » d’une interface physique sur votre hôte et de l’utiliser pour attacher des conteneurs directement à votre réseau local.

Je peux le vérifier sur mon réseau avec la commande ip n
: je vois bien l’adresse IP de mon NAS (192.168.1.xx) mais aussi celle assigné au serveur Pi-hole (192.168.1.yyy). Et leurs adresse MAC sont différentes :
$ ip n
192.168.1.yyy dev enp9s0 lladdr 4e:3d:e7:f7:1e:96 REACHABLE
...
192.168.1.xx dev enp9s0 lladdr e8:ff:1e:xx:yy:zz REACHABLE
...
La limitation
Si vous créez un tel conteneur et essayez d’envoyer un ping à l’interface réseau de l’hôte Docker, cela ne fonctionnera pas. Ce trafic est explicitement filtré par les modules du noyau eux-mêmes afin d’offrir une isolation et une sécurité supplémentaires.
Avec un conteneur attaché à un réseau macvlan, vous constaterez que s’il peut contacter sans problème d’autres systèmes sur votre réseau local, le conteneur ne pourra pas se connecter à votre hôte (et votre hôte ne pourra pas se connecter à votre conteneur). Il s’agit d’une limitation des interfaces macvlan : sans l’aide spéciale d’un commutateur réseau, votre hôte n’est pas en mesure d’envoyer des paquets à ses propres interfaces macvlan.
Donc il n’y a pas de solution ? Et bien si, et elle est décrite dans cet excellent article : Using Docker macvlan networks. Mais ce n’est pas simple, j’ai du relire l’article plusieurs fois avant de comprendre ! 😉
Il s’agit donc de créer une première interface de type macvlan, mais en lui assignant un ‘range’ d’adresse IP qui sera utilisé par tous les containers du NAS dont vous voulez qu’ils communiquent avec le host. Chaque container aura donc sa propre adresse sur le LAN, ce qui implique d’utiliser un range en dehors de celui du serveur DHCP pour éviter des conflits. Dès lors, tous nos containers peuvent communiquer entre eux, mais ne peuvent toujours pas communiquer avec le host. On crée cette interface de cette façon (je reprends l’exemple de la page) :
docker network create -d macvlan -o parent=eno1 \
--subnet 192.168.1.0/24 \
--gateway 192.168.1.1 \
--ip-range 192.168.1.192/27 \
--aux-address 'host=192.168.1.223' \
mynet
ip-range
indique que l’on va utiliser 32 adresses de 92.168.1.192 à 192.168.1.223 qui seront utilisées par les containers Docker.aux-address
réserve l’adresse 192.168.1.223 pour le host.
Puis on va créer sur le NAS un adaptateur macvlan qui sera en charge de communiquer avec les containers. Pour ce faire on lui assigne l’adresse précédemment réservée dans le « range macvlan » ci-dessus, et enfin on l’active :
ip link add mynet-shim link eno1 type macvlan mode bridge
ip addr add 192.168.1.223/32 dev mynet-shim
ip link set mynet-shim up
Il ne reste plus qu’à définir la route pour dire au host d’utiliser cette interface pour communiquer avec les adresses IP utilisées par les containers :
ip route add 192.168.1.192/27 dev mynet-shim
Le cas est d’ailleurs aussi décrit dans la documentation d’OMV : How to Create a VLAN (Pi-hole, Adguard, …).
Comme vous le voyez, cela nécessite quand même un peu de modifications, et mon petit souci cosmétique avec le dashboard de Homepage ne justifie pas de mettre tout cela en œuvre.
Conclusion
Voilà, j’ai désormais un serveur Pi-hole qui tourne en mode Docker, ce qui va lui permettre d’être mis à jour automatiquement, et me simplifier la mise à jour de Volumio sur le Raspberry, désormais dédié à ce dernier.
Et j’ai appris pas mal de choses sur le réseau des containers Docker, ce n’était pas inintéressant, loin de là. Peut-être m’en servirai-je un jour…