Plan on Create dockers for Pi-hole and Unbound

After a few days wondering here, I decided to start my very first docker project this weekend.

Pi-hole and Unbound (Recursive-mode) in Dockers:

  • They are to be in a Raspberry Pi 4 Model B with 2G RAM.
  • Not trying to build a docker to host them all. I will, but not in this project. Perhaps, it’ll be the next.
  • Rootless Docker since more security and this project doesn’t seem to need overlay network / swarm.
  • Pi-hole will connect to 2 networks: macvlan and bridge. Unbound will connect to Pi-hole thru the bridge network since Unbound doesn’t need to expose itself to the outside.
  • The script will be created as a stack in Portainer.
  • I might do a bit to tweaking on their configurations, like altering the parameters in the config files and setting cron jobs in updating gravity.

I’d like to check with you here if there’re anything I should aware of. Please kindly advise. Thanks in advance.

P.S. Should my post is inappropriate, please act accordingly. Just send me a note on what I should do otherwise. Thank you.

I’ll write down my progress along the way for the other new comers. I bet there should be some learnings in it.

Even though my Raspberry Pi has only 2G of RAM, I’ll use PiOS Lite (64-bit). I might swap to DietPi in a later phase due to its compact use of resources. By then, I’ll reinstall everything from ground up.

Welcome to the forum!

Sounds like a decent plan :slight_smile:

Two observations:

What does “a docker” mean for you? Am image, or a container?
An image is the blueprint for a container, it is typically build using a Dockerfile.
A container is a runtime instance based on an image.
Though, non of both is “a docker”.

Are you referring to running the processes inside the container as unprivileged user? Then this will work.
Though if you are planing to run the docker engine in rootless mode, then at least macvlan won’t work.

1 Like

Thanks, @meyay. Never expect a leader like you giving me the first piece of advice. Overwhelmed and appreciate.

Sorry, my bad for not picking the right term. I guess it’s a container to hold them both. To start, I’ll have them to work as 2 containers.

Haha, I might be running before learning to walk. Pardon me. Yes, I’d like to run the processes inside the containers as unprivileged user. Do the user need to be in sudo group or just the docker group will do? Originally, I thought the user needs both, but your phase unprivileged user made me rethink.
If macvlan isn’t gonna work in rootless docker, what would you suggest?

Sorry for throwing more questions to you. At the same time, I’ll try to google and find a solution. Once again, thanks.

Separate containers are actually the preferred approach: one container per service.
if communication between the services happens over the network, then most likely the services should be run in different containers.

What you describe is not the rootless mode. The “normal” docker engine always runs as a daemon with root privileges. Adding an unprivileged host user to the docker group, just allows this user to access the docker.sock, which is used to send commands to the docker backend - this doesn’t make it a rootless mode - the docker engine still runs as root, you just allow unprivileged users to use the cli client (which btw. adds zero security, it just makes it more convenient to use).

It depends pretty much on the image, if the container runs the process as root user, unprivileged user or even allows user mapping (which start the user as root, do some preparation work, then start the main application as unprivleged user). The dockerhub description should indiciate what is used. macvlan will work with any of those variations, as the docker engine is able to perform the required plumbing to make it work.

None of this is related to running the docker engine in rootless mode.

Running the docker engine in rootless mode is a whole different thing. As it does not run with root permissions, it lacks the permissions to create a macvlan. You can not mix rootfull mode and rootless mode, they would be just different docker engines – thus, you can not create a macvlan in rootfull mode and then use it in rootless mode.

I wouldn’t recommend a beginner to start with the rootless mode.

1 Like

First of all, thanks for your lengthy replies and most of all, patience. Really appreciate for getting me on board.

Haha… Sorry, I think I was wrong in the first place. What a shame! My intention is to run the normal docker while the containers are running as rootless. Perhaps, I’m still wrong/unclear with all the concepts. I’m starting to re-read what I’ve read so far, especially the link you offered.


It is better to phrase it as “running as unprivileged user”. The word rootless is often associated with running the docker engine in rootless mode.

Please ignore the link I shared, it was about the rootless mode. I just shared the link to make sure whether it is what you are talking about. Now we know it is not.

If you want to learn docker in depth, I can highly recommend this free self-paced training: Introduction to Containers

1 Like

Thank you, thank you. Can’t help saying more.

Yes, I’d rather pause and read through the 800+page slides to get a better understanding, at least I can express myself in better words. I’ve caused enough trouble, esp to you.


And don’t worry, even every expert had to start at one point :slight_smile:

1 Like

Just an update after going thru 1/4 of the presentation. Once again, thanks to @meyay. The phrase ‘rootless docker’ is truly confusing since I mixed up with docker in rootless mode. Without @meyay’s help, this’s definitely a nightmare to me.
Anyway, here is an update of my project for this weekend. Rootless docker containers won’t be able to access port < 1024. So, I suppose I can’t get the pi-hole container to run rootlessly given it needs to listen to port 53 externally.
Beyond this, everything went as planned: Pi-hole listens to port 53 and check if the hostname is an ad domain, otherwise pass it over to Unbound, which is in the same bridge network, to proceed to the related IP address.

Here is the compose script:

    container_name: pihole
    image: pihole/pihole:latest
      - "53:53/tcp"
      - "53:53/udp"
      - "64080:64080/tcp"
        ipv4_address: ${PIHOLE_LAN_IP}
        ipv4_address: ${PIHOLE_BRIDGE_IP}
      - pihole:/etc/pihole/
      - dnsmasq.d:/etc/dnsmasq.d/
      - TZ=${TIMEZONE}
      #- VIRTUAL_HOST=pihole-docker
      #- WEBTHEME=default-auto
      #- DNSMASQ_LISTENING=local
      - WEB_PORT=64080
    restart: unless-stopped

    container_name: unbound-rpi
    image: mvance/unbound-rpi:latest

        ipv4_address: ${UNBOUND_BRIDGE_IP}
      - unbound:/opt/unbound/etc/unbound/
    restart: unless-stopped

    driver: macvlan
      parent: eth1@if2
      driver: default
        - subnet: ${LAN_SUBNET}
          gateway: ${LAN_GATEWAY}
    driver: bridge
      driver: default
        - subnet: ${BRIDGE_SUBNET}


Here are the env variables:


Please don’t just take the script and put it into use. I believe there’re some pitfalls. One I notice is the networks>macvlan>driver_opts>parent. You need to dig out the network name Pi-hole use to communicate to the outsiders. It could be sth else than eth1@if2.

Also, I didn’t set password for the admin web. You may go into a console and execute ‘pihole -a -p’ to set it up.

I’m sure if there’re more to put into this project with your enlightenment. Please advise. Of course, any improvements on anything is always welcome. Thanks.