使用 Docker 部署 Pi-hole,关键有两点:一是容器需要用三种特殊的“能力(Capabilities)”来管理网络,二是要提前释放主机上被占用的 53 端口。

ytt 发布于 2026-05-05 162 次阅读


下面是一份操作指南,我会用 docker-compose.yml 文件来部署,这样更方便管理和更新。

✅ 准备工作

  • 一台 Linux 服务器:可以是云服务器、家里的 NAS 或树莓派等。
  • 安装 Docker 与 Docker Compose:这是运行容器的前提。

⚙️ 部署前配置:释放端口53

DNS 服务默认使用 53 端口,它通常被系统自带的 systemd-resolved 服务占用了。为了让 Pi-hole 容器能接管这个端口,需要做一些调整。

  1. 停止并禁用系统DNS服务
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved

配置主机DNS:为你的服务器设置一个临时的上游 DNS 服务器(这里以 Cloudflare 的 1.1.1.1 为例),确保它在重启后也能上网拉取镜像。

echo "nameserver 1.1.1.1" | sudo tee /etc/resolv.conf

如果你想永久修改,可以编辑 /etc/systemd/resolved.conf 文件,但简单起见,上述临时配置已经足够。

🐳 第一步:配置 Docker Compose

创建一个项目目录并进入:

mkdir ~/pihole && cd ~/pihole

~/pihole 目录下,创建一个名为 docker-compose.yml 的文件。注意:下面配置文件中的密码 'your-password-here' 请务必修改成一个你记住的复杂密码!

方案一:基础配置

这是最常用、最稳妥的配置方式:

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    ports:             # 端口映射
      - "53:53/tcp"
      - "53:53/udp"
      - "80:80/tcp"
      - "443:443/tcp"
    environment:       # 环境变量(核心配置)
      TZ: 'Asia/Shanghai'                    # 1. 设置时区
      FTLCONF_webserver_api_password: 'your-password-here' # 2. 设置密码[reference:0]
      FTLCONF_dns_listeningMode: 'all'       # 3. 监听所有网卡[reference:1]
      # FTLCONF_dns_upstreams: '1.1.1.1;9.9.9.9' # 自定义上游DNS (可选)
    volumes:           # 数据持久化
      - './etc-pihole:/etc/pihole'            # 核心数据库和配置
      # - './etc-dnsmasq.d:/etc/dnsmasq.d'   # 高级配置目录(非必须)
    cap_add:
      - NET_ADMIN       # 网络管理权限[reference:2]
      - SYS_TIME        # 系统时间同步权限[reference:3]
      - SYS_NICE        # 提升容器优先级(可选)[reference:4]
    restart: unless-stopped

方案二:进阶配置

如果你想让博客访问更流畅,可以试试直接用国外的公共DNS服务作为上游,这能间接加速部分海外资源的访问。

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "80:80/tcp"
    environment:
      TZ: 'Asia/Shanghai'
      FTLCONF_webserver_api_password: 'your-password-here'
      FTLCONF_dns_listeningMode: 'all'
      FTLCONF_dns_upstreams: '1.1.1.1;9.9.9.9' # 使用 Cloudflare 和 Quad9 的公共DNS
    volumes:
      - './etc-pihole:/etc/pihole'
    cap_add:
      - NET_ADMIN
      - SYS_TIME
    restart: unless-stopped

📝 关键配置说明:环境变量

  • FTLCONF_dns_listeningMode: 'all':允许 Pi-hole 监听所有网络接口,否则 Docker 容器默认的网络模式下,局域网内的其他设备将无法使用它作为 DNS 服务器
  • FTLCONF_dns_upstreams (进阶设置):指定 Pi-hole 上游的 DNS 转发服务器
  • FTLCONF_xxx:所有以 FTLCONF_ 开头的环境变量,一旦设置,在 Pi-hole 网页后台管理界面中会变成只读模式。这样做是为了确保主配置的唯一性和可靠性

🚀 第二步:启动服务

docker-compose.yml 文件所在目录下,运行以下命令拉取镜像并后台启动:

docker compose up -d

🔑 第三步:获取初始随机密码

如果你在配置文件中没有设置上面的密码 (FTLCONF_webserver_api_password),系统会自动生成一个随即密码,通过下面的命令可以获取:

docker logs pihole 2>&1 | grep "random password"

你应该会看到类似下面的输出:

[INFO] Assigning random password: 你的随机密码

🌐 第四步:访问管理后台

现在,你就可以通过 http://你的服务器IP/admin 来访问 Pi-hole 的管理面板了,输入上面设置(或获得)的密码即可登录。

🔗 第五步:配置 DNS 指向 Pi-hole

要让 Pi-hole 生效,你必须把网络中的设备的 DNS 指向它。

  • 为Linux服务器配置推荐方案。在防火墙或路由器上添加规则,将所有对外部DNS(如 8.8.8.8)的请求转发到你的Pi-hole。如果不想搞那么复杂,可以直接在 /etc/resolv.conf 里指定DNS为 127.0.0.1,但重启配置会丢失。
  • 为整个局域网(路由器)配置:效果最好。登录你的路由器后台,将“首选DNS”或“DNS服务器”设置为运行 Pi-hole 的服务器 IP 地址。这样家里所有用Wi-Fi的设备都能自动拦截广告。
  • 为单个设备配置:适合测试。修改你电脑或手机的网络连接设置,将 DNS 服务器手动指定为 Pi-hole 的 IP 地址。这是最快能体验效果的方式。

💡 使用容器的几个要点

  • 数据持久化:项目目录下的 ./etc-pihole 文件夹至关重要,它存储了Pi-hole的配置、数据库和日志。千万不要删除这个文件夹,否则所有配置和统计数据都会丢失
  • 如何更新:用 Docker 的方式更新非常简单。
docker compose pull    # 1. 拉取最新镜像
docker compose down    # 2. 停止并移除当前容器
docker compose up -d   # 3. 使用新镜像重新创建并启动

请注意:Pi-hole 容器内禁用了 pihole -up 命令,必须使用上述标准的 Docker 方式升级

  • 安全提示:如果只是为了改善家庭网络体验,不要将 Pi-hole 的 80 或 443 等管理端口直接暴露到公共互联网。如果确实有远程管理需求,建议使用 VPN(如 WireGuard)接入家庭网络后再访问。
  • 解决可能的问题:如果你的网络设备众多,Pi-hole 的默认容器 IP 与局域网不在同一网段可能导致设备无法连接。你可以在 docker-compose.yml 中为容器指定一个你局域网内的静态 IP(例如 192.168.1.100)来解决。

此作者没有提供个人介绍。
最后更新于 2026-07-13