services: {{ service_name }}: {% if not swarm_enabled %} container_name: {{ container_name }} {% endif %} image: docker.io/pihole/pihole:2025.10.2 env_file: - .env.pihole {% if network_mode == 'host' %} network_mode: host {% else %} 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 not in ['host', 'macvlan'] %} ports: {% if not traefik_enabled %} {% if swarm_enabled %} - target: 80 published: {{ ports_http }} protocol: tcp mode: host - target: 443 published: {{ ports_https }} protocol: tcp mode: host {% else %} - "{{ ports_http }}:80/tcp" - "{{ ports_https }}:443/tcp" {% endif %} {% endif %} {% if swarm_enabled %} - 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 {% else %} - "{{ ports_dns }}:53/tcp" - "{{ ports_dns }}:53/udp" - "{{ ports_ntp }}:123/udp" {% endif %} {% endif %} volumes: {% if not swarm_enabled %} - config_dnsmasq:/etc/dnsmasq.d - config_pihole:/etc/pihole {% else %} {% if swarm_volume_mode == 'mount' %} - {{ swarm_volume_mount_path }}/dnsmasq:/etc/dnsmasq.d:rw - {{ swarm_volume_mount_path }}/pihole:/etc/pihole:rw {% elif swarm_volume_mode == 'local' %} - config_dnsmasq:/etc/dnsmasq.d - config_pihole:/etc/pihole {% elif swarm_volume_mode == 'nfs' %} - config_dnsmasq:/etc/dnsmasq.d - config_pihole:/etc/pihole {% endif %} {% endif %} cap_add: - NET_ADMIN - SYS_TIME {% if swarm_enabled %} secrets: - {{ webpassword_secret_name }} deploy: mode: replicated replicas: 1 placement: constraints: - node.hostname == {{ swarm_placement_host }} {% if traefik_enabled %} labels: - traefik.enable=true - 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.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.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 %} {% else %} {% if traefik_enabled %} labels: - traefik.enable=true - 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.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.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 %} restart: {{ restart_policy }} {% endif %} {% if swarm_enabled %} {% if swarm_volume_mode in ['local', 'nfs'] %} volumes: config_dnsmasq: {% if swarm_volume_mode == 'nfs' %} driver: local driver_opts: type: nfs o: addr={{ swarm_volume_nfs_server }},{{ swarm_volume_nfs_options }} device: ":{{ swarm_volume_nfs_path }}/dnsmasq" {% endif %} config_pihole: {% if swarm_volume_mode == 'nfs' %} driver: local driver_opts: type: nfs o: addr={{ swarm_volume_nfs_server }},{{ swarm_volume_nfs_options }} device: ":{{ swarm_volume_nfs_path }}/pihole" {% endif %} {% endif %} secrets: {{ webpassword_secret_name }}: file: ./.env.secret {% else %} volumes: config_dnsmasq: driver: local config_pihole: driver: local {% endif %} {% if network_mode != 'host' %} networks: {% if network_mode == 'macvlan' %} {{ network_name }}: driver: macvlan driver_opts: parent: {{ network_macvlan_parent_interface }} ipam: config: - subnet: {{ network_macvlan_subnet }} gateway: {{ network_macvlan_gateway }} {% elif network_mode == 'bridge' and network_external %} {{ network_name }}: external: true {% elif network_mode == 'bridge' and not network_external %} {{ network_name }}: {% if swarm_enabled %} driver: overlay attachable: true {% else %} driver: bridge {% endif %} {% endif %} {% if traefik_enabled %} {{ traefik_network }}: external: true {% endif %} {% endif %}