--- services: << service_name >>: image: docker.io/pihole/pihole:2026.04.1 <%- if container_hostname %> hostname: << container_hostname >> <%- endif %> environment: - TZ=<< container_timezone >> - PIHOLE_UID=<< user_uid >> - PIHOLE_GID=<< user_gid >> - WEBPASSWORD_FILE=<< service_name >>_webpassword <%- if network_mode == 'bridge' %> - FTLCONF_dns_listeningMode=all <%- endif %> <%- if network_mode == 'host' %> network_mode: host <%- elif network_mode == 'bridge' or network_mode == 'macvlan' or traefik_enabled %> networks: <%- if traefik_enabled %> << traefik_network >>: <%- endif %> <%- if network_mode == 'macvlan' %> << network_name >>: ipv4_address: << network_macvlan_ipv4_address >> <%- elif network_mode == 'bridge' %> << network_name >>: <%- endif %> <%- endif %> <%- if network_mode == '' or network_mode == 'bridge' or traefik_enabled %> ports: <%- if not traefik_enabled %> - target: 80 published: << ports_http >> protocol: tcp mode: host - target: 443 published: << ports_https >> protocol: tcp mode: host <%- endif %> - target: 53 published: << ports_dns >> protocol: tcp mode: host - target: 53 published: << ports_dns >> protocol: udp mode: host - target: 123 published: << ports_ntp >> protocol: udp mode: host <%- endif %> volumes: <%- if volume_mode == 'mount' %> - << volume_mount_path >>/dnsmasq:/etc/dnsmasq.d:rw - << volume_mount_path >>/pihole:/etc/pihole:rw <%- else %> - << service_name >>-dnsmasq:/etc/dnsmasq.d - << service_name >>-pihole:/etc/pihole <%- endif %> cap_add: - NET_ADMIN - SYS_TIME secrets: - << service_name >>_webpassword deploy: mode: replicated replicas: 1 placement: constraints: - node.hostname == << swarm_placement_host >> restart_policy: condition: on-failure <%- if traefik_enabled %> labels: - traefik.enable=true - traefik.docker.network=<< traefik_network >> - traefik.http.services.<< service_name >>-web.loadBalancer.server.port=80 - traefik.http.routers.<< service_name >>-http.service=<< service_name >>-web - traefik.http.routers.<< service_name >>-http.rule=Host(`<< traefik_host >>.<< traefik_domain >>`) - traefik.http.routers.<< service_name >>-http.entrypoints=<< traefik_entrypoint >> <%- if traefik_tls_enabled %> - traefik.http.routers.<< service_name >>-https.service=<< service_name >>-web - traefik.http.routers.<< service_name >>-https.rule=Host(`<< traefik_host >>.<< traefik_domain >>`) - traefik.http.routers.<< service_name >>-https.entrypoints=<< traefik_tls_entrypoint >> - traefik.http.routers.<< service_name >>-https.tls=true - traefik.http.routers.<< service_name >>-https.tls.certresolver=<< traefik_tls_certresolver >> <%- endif %> <%- endif %> secrets: << service_name >>_webpassword: file: ./.env.secret.webpassword <%- if volume_mode == 'local' %> volumes: << service_name >>-dnsmasq: driver: local << service_name >>-pihole: driver: local <%- elif volume_mode == 'nfs' %> volumes: << service_name >>-dnsmasq: driver: local driver_opts: type: nfs o: addr=<< volume_nfs_server >>,<< volume_nfs_options >> device: ":<< volume_nfs_path >>/dnsmasq" << service_name >>-pihole: driver: local driver_opts: type: nfs o: addr=<< volume_nfs_server >>,<< volume_nfs_options >> device: ":<< volume_nfs_path >>/pihole" <%- endif %> <%- if network_mode == 'bridge' or network_mode == 'macvlan' or traefik_enabled %> networks: <%- if network_mode == 'bridge' or network_mode == 'macvlan' %> << network_name >>: <%- if network_external %> external: true <%- else %> <%- if network_mode == 'macvlan' %> driver: macvlan driver_opts: parent: << network_macvlan_parent_interface >> ipam: config: - subnet: << network_macvlan_subnet >> gateway: << network_macvlan_gateway >> name: << network_name >> <%- else %> driver: overlay attachable: true <%- endif %> <%- endif %> <%- endif %> <%- if traefik_enabled %> << traefik_network >>: external: true <%- endif %> <%- endif %>