Fresh Docker container installation not working

Expected: A working fresh installation of Pi-hole in Docker.

Actual: Container never fails to properly start, showing a permissions error.

Platform: Debian 13.1, Docker 28.4.0, Intel Coffee-Lake refresh, docker image 2025.08.0

Interpretation:

Since I've chosen to run the container under a non-root user/group (1005 for both in this case), I suspect this is somehow relevant, but nothing I can find in any current post leads me to a solution, and from what I can tell this setup should work.

It started as a simple in-place container version update, following a recent Debian version update to (Bookworm->Trixie). The previous container (I forget exactly which version, but v6 definitely) had been working ok on Debian 12. My timelines are a little hazy now, but I also think it was working ok on Debian 13 for a little while (although I may be wrong on this, so this update may be a contributory factor..?).

After a failed update to existing installation, I tried a fresh container, but same behaviour.

Changing permissions of the specified /etc/pihole/versions file seems to make no difference (something I've seen referenced in other posts).


compose.yml

networks:
    pihole:
        name: pihole

services:

    pihole:
        image: pihole/pihole:${PIHOLE_VERSION:-latest}
        container_name: pihole
        hostname: "${PIHOLE_VIRTUAL_HOST?}"
        restart: unless-stopped
        networks:
            - pihole
        ports:
            - 53:53/tcp
            - 53:53/udp
#             - 67:67/udp    # only required if using PiHole for DHCP
#             - 123:123/udp  # only required if using PiHole for NTP
            - ${PIHOLE_UI_PORT:-80}:80/tcp
#            - ${PIHOLE_UI_PORT_SSL:-443}:443/tcp
        volumes:
            - ${PIHOLE_DATA_DIR:-./etc-pihole}:/etc/pihole
            - ${PIHOLE_DNSMASQ_DATA_DIR:-./etc-dnsmasq.d}:/etc/dnsmasq.d
#         cap_add:
#             - NET_ADMIN  # required if using PiHole for DHCP
#             - SYS_TIME   # required if using PiHole for NTP
        environment:
            PIHOLE_UID: ${PIHOLE_UID?}
            PIHOLE_GID: ${PIHOLE_GID?}
            TZ: ${TZ}
            FTLCONF_webserver_api_password: "${PIHOLE_UI_PASSWORD?}"
            FTLCONF_dns_upstreams: 1.1.1.3;1.0.0.3
            FTLCONF_dns_revServers: "true,10.0.0.0/8,10.0.0.1,${PIHOLE_REV_SERVER_DOMAIN?}"

Environment

TZ=Europe/London
PIHOLE_UID=1005
PIHOLE_GID=1005
PIHOLE_UI_PORT=8081
PIHOLE_UI_PASSWORD=supersecretpassword
PIHOLE_VIRTUAL_HOST=pi.hole
PIHOLE_REV_SERVER_DOMAIN=fritz.box

Pi-hole log output

[+] Running 2/2
 ✔ Network pihole    Created                                                                                                                             0.0s
 ✔ Container pihole  Created                                                                                                                             0.0s
Attaching to pihole
pihole  |   [i] Setting up user & group for the pihole user
pihole  |   [i] Changing ID for user: pihole (1000 => 1005)
pihole  |   [i] Changing ID for group: pihole (1000 => 1005)
pihole  |
pihole  |   [i] Starting FTL configuration
pihole  |   [i] Assigning password defined by Environment Variable
pihole  |   [i] Starting crond for scheduled scripts. Randomizing times for gravity and update checker
pihole  |
pihole  |   [i] Ensuring logrotate script exists in /etc/pihole
pihole  |
pihole  |   [i] Gravity migration checks
pihole  |   [i] No adlist file found, creating one with a default blocklist
pihole  |   [i] /etc/pihole/gravity.db does not exist (Likely due to a fresh volume). This is a required file for Pi-hole to operate.
pihole  |   [i] Gravity will now be run to create the database
  [✓] DNS resolution is available
pihole  |
  [✗] Migrating the list's cache directory to new location
pihole  |   [i] Creating new gravity database
pihole  |   [i] Migrating content of /etc/pihole/adlists.list into new database
pihole  |   [i] Neutrino emissions detected...
pihole  |
  [✓] Preparing new gravity database
  [✓] Creating new gravity databases
  [✓] Pulling blocklist source list into range
pihole  |   [i] Using libz compression
pihole  |
pihole  |   [i] Target: https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
  [✗] Status: Connection Refused
pihole  |   [✗] List download failed: no cached list available
pihole  |
  [✓] Building tree
pihole  |   [i] Number of gravity domains: 0 (0 unique domains)
pihole  |   [i] Number of exact denied domains: 0
pihole  |   [i] Number of regex denied filters: 0
pihole  |   [i] Number of exact allowed domains: 0
pihole  |   [i] Number of regex allowed filters: 0
  [✓] Optimizing database
  [✓] Swapping databases
pihole  |   [✓] The old database remains available
  [✓] Cleaning up stray matter
pihole  |
pihole  |   [✓] Done.
pihole  |
pihole  |   [i] pihole-FTL pre-start checks
pihole  |   [i] Setting capabilities on pihole-FTL where possible
pihole  |   [i] Applying the following caps to pihole-FTL:
pihole  |         * CAP_CHOWN
pihole  |         * CAP_NET_BIND_SERVICE
pihole  |         * CAP_NET_RAW
pihole  |
pihole  | chmod: cannot access '/etc/pihole/versions': No such file or directory
pihole  |   [i] Starting pihole-FTL (no-daemon) as pihole
pihole  |
pihole  | Unable to get group list for user: Permission denied

Please, as a test, try to start the container without volumes and report if this works or fails.

I'm a little unclear what you mean, as surely it needs the volumes to operate.

However...assuming you mean with the local volume directories not present, this is exactly what I did for the problem runs, which presumably leaves Docker to create the directories when mapped, and the container to fill them with the relevant data.

I meant to comment the volumes on your compose file, like this:

        #volumes:
        #    - ${PIHOLE_DATA_DIR:-./etc-pihole}:/etc/pihole
        #    - ${PIHOLE_DNSMASQ_DATA_DIR:-./etc-dnsmasq.d}:/etc/dnsmasq.d

Docker containers don't need volumes to operate. Please try without them to test what happens. If it works, the issue is probably related to the permissions you are using on the directories used by the volumes (./etc-pihole).

Sadly the same result with them commented out. I'm also surprised this hasn't occurred for others, unless everyone runs this as root, which I prefer not to. Even running without setting UID/GID for the container produces the same result.

Also getting the same error on Debian 13 Trixie:

[✓] Building tree
pihole | [i] Number of gravity domains: 97124 (97124 unique domains)
pihole | [i] Number of exact denied domains: 0
pihole | [i] Number of regex denied filters: 0
pihole | [i] Number of exact allowed domains: 0
pihole | [i] Number of regex allowed filters: 0
[✓] Optimizing database
[✓] Swapping databases
pihole | [✓] The old database remains available
[✓] Cleaning up stray matter
pihole |
pihole | [✓] Done.
pihole |
pihole | [i] pihole-FTL pre-start checks
pihole | [i] Setting capabilities on pihole-FTL where possible
pihole | [i] Applying the following caps to pihole-FTL:
pihole | * CAP_CHOWN
pihole | * CAP_NET_BIND_SERVICE
pihole | * CAP_NET_RAW
pihole | * CAP_NET_ADMIN
pihole | * CAP_SYS_NICE
pihole |
pihole | [i] Starting pihole-FTL (no-daemon) as pihole
pihole |
pihole | Unable to get group list for user: Permission denied

Even running it as root gives the same errors.

Docker version 29.0.3, build 511dad6
Docker Compose version v2.40.3

In my original post I made the mistake of not including the fact that my "Debian" install is actually a Proxmox VE 9 installation, which additionally uses AppArmor as an additional security layer. It turns out that for this use-case it gets in the way. Unsurprisingly there is a way to disable it for the Docker installation, but I chose to go the more "official" way and create a VM in which to run Docker instead. Hope this helps get things working for you.

Thanks mate. That did the trick. I’m also running Proxmox 9.