Files
homelab/services/pihole.nix
T

52 lines
2.1 KiB
Nix

{ pkgs, lib, ... }:
# Pi-hole via the official container (the native nixpkgs pihole-ftl module
# segfaults on aarch64 / Pi 3B+). Host networking so it can serve DHCP and reach
# the host's unbound at 127.0.0.1:5335. Config via FTLCONF_* env vars (pihole v6)
# — these override pihole.toml on every start, so it stays effectively
# declarative. The web admin password is added from sops in the host config.
{
virtualisation.podman = {
enable = true;
dockerCompat = true;
};
virtualisation.oci-containers = {
backend = "podman";
containers.pihole = {
image = "pihole/pihole:2026.07.2"; # validated in mercury-vm
autoStart = true;
extraOptions = [
"--network=host" # DHCP broadcast + host unbound on 127.0.0.1
"--cap-add=NET_ADMIN" # DHCP
"--cap-add=NET_RAW" # DNS engine (dnsmasq) — REQUIRED
"--cap-add=SYS_NICE"
"--cap-add=CHOWN" # entrypoint chowns /etc/pihole
];
volumes = [ "/var/lib/pihole:/etc/pihole" ]; # persist config/state
environment = {
TZ = "Europe/Berlin";
FTLCONF_dns_upstreams = "127.0.0.1#5335"; # host unbound (recursive)
FTLCONF_dns_listeningMode = "all"; # serve the LAN
FTLCONF_dns_domain = "sol";
FTLCONF_dhcp_active = "true";
FTLCONF_dhcp_start = "10.0.0.50";
FTLCONF_dhcp_end = "10.0.0.200";
FTLCONF_dhcp_router = "10.0.0.1";
FTLCONF_dhcp_leaseTime = "1h";
# Arrays (format validated in the VM): static lease + local DNS records.
FTLCONF_dhcp_hosts = "00:e0:4c:3c:a3:1f,10.0.0.20,jupiter";
FTLCONF_dns_hosts = "10.0.0.10 mercury.sol;10.0.0.20 jupiter.sol";
# Wildcard: any <service>.jupiter.sol -> jupiter (caddy routes by hostname).
FTLCONF_misc_dnsmasq_lines = "address=/jupiter.sol/10.0.0.20";
};
};
};
# Bind-mount source must exist (podman won't create it).
systemd.tmpfiles.rules = [ "d /var/lib/pihole 0755 root root -" ];
networking.firewall.allowedTCPPorts = [ 53 80 ];
networking.firewall.allowedUDPPorts = [ 53 67 ];
}