AdGuard Home Docker Compose 部署指南

AdGuard Home v0.107.79 Docker Compose 部署指南:官方镜像选型、compose 编排(Web 8092/DNS 5331)、API 一键初始化、国内上游切换、数据持久化与升级运维,全流程在 Ubuntu 22.04 实测通过

AdGuard HomeAdGuard HomeDNS 服务2026/10/18

AdGuard Home Docker Compose 部署指南

目标:本文面向希望在 Ubuntu 22.04 服务器上用 Docker Compose 一键部署 AdGuard Home 全网广告拦截 DNS 服务的读者,给出从创建部署目录、编写 compose 文件、首次初始化(含管理员账号配置)、切换国内上游到功能验证的完整流程,覆盖数据持久化、等价 docker run 对照、日常运维命令、版本升级与常见故障排障,全部命令与回显均已在 Ubuntu 22.04 + AdGuard Home v0.107.79 实测通过。

一、环境信息

本章列明实测环境的软件版本、端口规划与目录约定,所有后续命令与回显均基于此环境,读者可按同样配置复现。

  • 操作系统:Ubuntu 22.04(内核 5.15,amd64 架构)
  • AdGuard Home 版本:v0.107.79(0.107.x 系列最新稳定版)
  • Docker Engine:docker --version 实测 Docker version 27.5.1, build 470bca4
  • Compose 插件:docker compose version 实测 Docker Compose version v2.38.1
  • 部署方式:Docker Compose(单服务 + bind mount 数据卷 + 自定义网络)
  • 端口规划:宿主机 8092 → 容器内 3000(Web 管理界面);宿主机 5331 → 容器内 53(DNS 服务,TCP/UDP)
  • 部署目录:/opt/adguardhome/(内含 docker-compose.yml、conf/ 配置目录、work/ 数据目录)
  • 数据网络:自定义网络 adguardhome-net,显式子网 10.89.22.0/24,固定容器地址 10.89.22.10
  • 示例客户端:局域网客户机 10.89.22.1(用于解析验证)

⚠️ 端口说明:宿主机 53 端口通常已被系统自带的 systemd-resolved 占用(stub 监听 127.0.0.53:53,实测 ss -lntp | grep :53 输出见「十一、常见问题」11.1 节),因此本文 DNS 端口映射规划为 5331:53。若你的服务器 53 端口空闲或已按 11.1 节方法释放,可直接改为 53:53,让局域网设备无需指定端口即可使用。

二、镜像选型说明

AdGuard Home 官方在 Docker Hub 发布镜像 adguard/adguardhome,与 GitHub Releases 同步出版。本章给出 tag 选型依据与镜像规格实测。

2.1 版本 tag 对照

tag 形态当前指向(2026-10-18 实查)说明
v0.107.790.107.x 稳定通道最新版(2026-08-18 发布)本文采用,版本固定,升级可控
latest跟随最新稳定版方便但版本漂移,up 时行为不可预期
beta0.108.0-b.x 测试通道(当前 v1.0 已进入 beta)功能激进,不建议生产
edge主干每日构建仅用于问题验证

💡 技术拓展:镜像 tag 选型策略对比——

策略特点适用场景
固定版本 tag(v0.107.79)版本显式可控,升级即改 tag生产推荐,本文采用
latest自动跟随最新稳定版个人试验,追求免维护
digest 固定(image@sha256:...)精确到镜像内容不可变强合规审计环境

本文采用固定版本 tag:DNS 是全网出口依赖的基础服务,升级节奏必须由管理员主动控制,而不是被 latest 的自动漂移决定。

2.2 镜像规格实测

镜像拉取后实测(docker images):

docker images adguard/adguardhome --format '{{.Repository}}:{{.Tag}} {{.Size}} {{.ID}}'

实测输出:

adguard/adguardhome:v0.107.79 114MB aba9e3bf0613

镜像约 114MB(Go 静态编译二进制 + alpine 基础层),单机资源占用极小。多架构支持实测(Docker Hub Registry API 查询 tag v0.107.79,2026-10-18):

架构/系统镜像压缩体积
amd64/linux28 MB
arm64/linux27 MB
arm/linux(v6/v7 两个变体)27 MB
386/linux27 MB
ppc64le/linux26 MB

关键差异解读:x86 服务器选默认 amd64 即可;树莓派等 ARM 设备选 arm64 或 arm/v7,docker pull 会按宿主机架构自动选择,无需手动指定平台。

三、前置条件

部署前确认以下三项,每项均给出验证命令与实测输出。

3.1 Docker 与 Compose 插件已就绪

docker --version && docker compose version

实测输出:

Docker version 27.5.1, build 470bca4
Docker Compose version v2.38.1

3.2 端口占用检查

确认规划端口 8092、5331 未被占用:

ss -lntup | grep -E ':(8092|5331)\s' || echo "端口空闲"

实测输出:

端口空闲

同时查看系统 DNS 端口 53 的占用情况,作为端口规划依据:

ss -lntup | grep -E ':53\s'

实测输出:

udp   UNCONN 0      0      127.0.0.53%lo:53         0.0.0.0:*    users:(("systemd-resolve",pid=853,fd=13))
tcp   LISTEN 0      4096   127.0.0.53%lo:53         0.0.0.0:*    users:(("systemd-resolve",pid=853,fd=14))

输出表明 53 端口被 systemd-resolved 的 stub 监听器占用(仅绑定 127.0.0.53),这正是本文选择 5331:53 映射的原因,处理方案详见「十一、常见问题」11.1 节。

3.3 部署目录规划

约定部署目录为 /opt/adguardhome/,创建并确认:

mkdir -p /opt/adguardhome && cd /opt/adguardhome && pwd

实测输出:

/opt/adguardhome

四、部署步骤

本章为 0→1 主线:创建目录 → 编写 compose 文件 → 启动 → 初始化 → 配置上游 → 功能验证。

4.1 创建目录结构

conf/ 存放主配置文件 AdGuardHome.yaml,work/ 存放运行数据(过滤器缓存、查询日志、统计库):

cd /opt/adguardhome && mkdir -p conf work && ls -la

实测输出:

total 20
drwxr-xr-x 5 root root 4096 Oct 18 18:10 .
drwxr-xr-x 9 root root 4096 Oct 18 09:52 ..
drwxr-xr-x 2 root root 4096 Oct 18 18:10 conf
drwxr-xr-x 2 root root 4096 Oct 18 18:10 work

4.2 编写 docker-compose.yml

创建 /opt/adguardhome/docker-compose.yml,内容如下(整体照抄即可):

services:
  adguardhome:
    image: adguard/adguardhome:v0.107.79
    container_name: adguardhome-v0107-web
    restart: unless-stopped
    ports:
      - "8092:3000/tcp"
      - "5331:53/tcp"
      - "5331:53/udp"
    volumes:
      - ./conf:/opt/adguardhome/conf
      - ./work:/opt/adguardhome/work
    networks:
      default:
        ipv4_address: 10.89.22.10

networks:
  default:
    name: adguardhome-net
    ipam:
      config:
        - subnet: 10.89.22.0/24

逐项说明:

配置项取值说明
imageadguard/adguardhome:v0.107.79官方镜像固定版本 tag,见第二章选型
container_nameadguardhome-v0107-web固定名称,便于 docker logs/docker exec 定位
restartunless-stopped开机自启、异常退出自动拉起;手动 stop 后不再自动启动
ports(8092:3000)Web 管理界面宿主机浏览器访问 http://服务器IP:8092
ports(5331:53)DNS 服务TCP/UDP 必须同时映射(区域传输、超长响应走 TCP)
volumes(conf)主配置 AdGuardHome.yaml初始化后自动生成,升级、重建均不丢
volumes(work)运行数据过滤器缓存、查询日志、统计数据库
networks.ipv4_address10.89.22.10固定内网地址,便于防火墙精确放行
networks.ipam.subnet10.89.22.0/24显式声明子网,避免依赖随机分配造成网段冲突

⚠️ 子网声明为硬性要求:自定义网络必须显式指定 --subnet,且避开 192.168.0.0/16(通常与物理局域网重叠)与 100.64.0.0/16(运营商级 NAT 段)。本文取 10.89.22.0/24。

💡 技术拓展:DNS 端口映射到 5331 后,局域网设备使用时需指定端口(如 dig @服务器IP -p 5331),路由器全局 DNS 设置通常无法指定端口。两种取舍:

做法优点代价
映射 53:53全网设备无感接入(路由器 DNS 直接指向服务器)需先释放宿主机 53(见 11.1 节)
映射 5331:53(本文实测形态)与系统 DNS 服务零冲突,风险最低下游设备需支持自定义端口

生产建议以 53:53 为目标形态;本文环境因系统服务占用保留 5331。

4.3 启动服务

cd /opt/adguardhome && docker compose up -d

实测输出(首次启动,含网络与容器创建全过程):

 Network adguardhome-net Creating
 Network adguardhome-net Creating
 Network adguardhome-net Created
 Network adguardhome-net Created
 Container adguardhome-v0107-web Creating
 Container adguardhome-v0107-web Created
 Container adguardhome-v0107-web Starting
 Container adguardhome-v0107-web Started

确认运行状态:

docker compose ps

实测输出:

NAME                    IMAGE                           COMMAND                   SERVICE       CREATED        STATUS                  PORTS
adguardhome-v0107-web   adguard/adguardhome:v0.107.79   "/opt/adguardhome/Ad…"   adguardhome   1 second ago   Up Less than a second   80/tcp, 67-68/udp, 443/tcp, 443/udp, 853/udp, 853/tcp, 3000/udp, 5443/tcp, 5443/udp, 6060/tcp, 0.0.0.0:5331->53/tcp, 0.0.0.0:5331->53/udp, [::]:5331->53/tcp, [::]:5331->53/udp, 0.0.0.0:8092->3000/tcp, [::]:8092->3000/tcp

💡 说明:PORTS 列中 80/tcp、67-68/udp、443/tcp、853/tcp 等是镜像声明但未映射到宿主机的端口(HTTP 备用、DHCP、HTTPS、DoT/DoQ),只有标有 0.0.0.0:5331->、0.0.0.0:8092-> 的才对外服务。容器启动日志(docker compose logs --tail 12 adguardhome 实测节选)可确认监听就绪:

adguardhome-v0107-web  | 2026/10/18 10:18:25.120561 [info] webapi: serving url=http://10.89.22.10:3000
adguardhome-v0107-web  | 2026/10/18 10:18:25.120573 [info] starting plain server server=plain addr=0.0.0.0:3000
adguardhome-v0107-web  | 2026/10/18 10:18:25.122400 [info] dnsproxy: creating udp server socket addr=0.0.0.0:53
adguardhome-v0107-web  | 2026/10/18 10:18:25.122488 [info] dnsproxy: listening to tcp addr=[::]:53

4.4 确认未初始化状态

首次访问 Web 端口会被重定向到安装向导:

curl -sI http://127.0.0.1:8092/ | head -4

实测输出:

HTTP/1.1 302 Found
Content-Type: text/html; charset=utf-8
Location: /install.html
Date: Sun, 18 Oct 2026 10:17:04 GMT

Location: /install.html 表明服务待初始化。此时也可用安装状态接口查看:

curl -s -w '\nHTTP:%{http_code}\n' http://127.0.0.1:8092/control/install/status

实测输出(未初始化时接口返回 302 跳转向导页):

<a href="/control/install/install.html">Found</a>.

HTTP:302

4.5 完成初始化(两种方式)

方式 A:浏览器向导(推荐首次部署使用)。浏览器打开 http://服务器IP:8092,按向导四步完成:① 欢迎页下一步 → ② 确认 Web/DNS 监听接口与端口(默认 0.0.0.0:3000、0.0.0.0:53)→ ③ 设置管理员账号密码 → ④ 完成并进入控制台。

方式 B:REST API 一键初始化(适合脚本化部署)。本节以 API 形态实测完整过程,管理员账号 admin、密码 q1w2e3r4:

curl -s -X POST http://127.0.0.1:8092/control/install/configure \
  -H 'Content-Type: application/json' \
  -d '{"web":{"ip":"0.0.0.0","port":3000,"status":""},"dns":{"ip":"0.0.0.0","port":53,"status":""},"username":"admin","password":"q1w2e3r4"}' \
  -w '\nHTTP:%{http_code}\n'

实测输出:

OK

HTTP:200

初始化完成后验证三件事:

其一,Web 已从 install.html 切换为登录页:

curl -sI http://127.0.0.1:8092/ | head -3

实测输出:

HTTP/1.1 302 Found
Content-Type: text/html; charset=utf-8
Location: /login.html

其二,配置文件已在挂载目录自动生成(schema_version: 34,全文逐项解读见本专栏《AdGuard Home 0.107.79 配置参数详解》一篇):

ls -l /opt/adguardhome/conf/

实测输出:

total 4
-rw------- 1 root root 4094 Oct 18 10:16 AdGuardHome.yaml

其三,用管理员账号登录管理 API(后续所有 /control/ 接口都依赖该会话 Cookie):

curl -s -c /tmp/ah-cookie.txt -X POST http://127.0.0.1:8092/control/login \
  -H 'Content-Type: application/json' \
  -d '{"name":"admin","password":"q1w2e3r4"}' -w 'HTTP:%{http_code}\n'

实测输出:

OK
HTTP:200

4.6 配置国内上游 DNS(关键步骤)

⚠️ 新初始化的默认上游是国外 DoH 服务(Quad9),国内网络环境直连不可达,会导致所有解析超时。实测现象(初始化后立即查询,dig 三次重试全部超时):

;; communications error to 127.0.0.1#5331: timed out
;; communications error to 127.0.0.1#5331: timed out
;; communications error to 127.0.0.1#5331: timed out

; <<>> DiG 9.18.39-0ubuntu0.22.04.6-Ubuntu <<>> @127.0.0.1 -p 5331 doubleclick.net +noall +answer
; (1 server found)
;; global options: +cmd
;; no servers could be reached

先看当前上游配置:

curl -s -b /tmp/ah-cookie.txt http://127.0.0.1:8092/control/dns_info | \
  python3 -c "import json,sys; d=json.load(sys.stdin); print(json.dumps({k:d[k] for k in ['upstream_dns','bootstrap_dns']}, indent=1))"

实测输出:

{
 "upstream_dns": [
  "https://dns10.quad9.net/dns-query"
 ],
 "bootstrap_dns": [
  "9.9.9.10",
  "149.112.112.10",
  "2620:fe::10",
  "2620:fe::fe:10"
 ]
}

改用国内可达上游(阿里公共 DNS + 腾讯 DNSPod,明文 UDP 与 DoH 混合,普通 53 端口写法如 223.5.5.5,DoH 写法带完整 URL):

curl -s -b /tmp/ah-cookie.txt -X POST http://127.0.0.1:8092/control/dns_config \
  -H 'Content-Type: application/json' \
  -d '{"upstream_dns":["223.5.5.5","119.29.29.29","https://dns.alidns.com/dns-query"],"bootstrap_dns":["223.5.5.5","119.29.29.29"]}' \
  -w 'HTTP:%{http_code}\n'

实测输出:

HTTP:200

💡 技术拓展:上游 DNS 协议不止一种,AdGuard Home 支持的上游写法对比——

协议写法示例端口特点
明文 UDP/TCP223.5.5.553延迟最低,内容可被窥探/篡改
DoHhttps://dns.alidns.com/dns-query443走 HTTPS,抗干扰强
DoTtls://dns.alidns.com853专用端口,协议开销小
DoQquic://dns.adguard-dns.com853(UDP)基于 QUIC,握手快

本文混合采用「明文 + DoH」三个上游(两国内明文 + 一国内 DoH),兼顾低延迟与抗污染;upstream_mode 为默认 load_balance(多上游并行取最快应答)。

验证解析恢复:

dig @127.0.0.1 -p 5331 www.baidu.com +noall +answer

实测输出:

www.baidu.com.          514     IN      CNAME   www.a.shifen.com.
www.a.shifen.com.       115     IN      A       110.242.69.21
www.a.shifen.com.       115     IN      A       110.242.70.57

4.7 验证拦截能力

默认已启用 AdGuard DNS filter 官方过滤列表(初始 186,044 条规则,启动后自动下载完成,日志实测 filtering: filter updated id=1 bytes_written=4458454 rules_count=186099)。再加一条自定义拦截规则演示全链路:

curl -s -b /tmp/ah-cookie.txt -X POST http://127.0.0.1:8092/control/filtering/set_rules \
  -H 'Content-Type: application/json' \
  -d '{"rules":["||doubleclick.net^","||zhihu.com^"]}' -w 'HTTP:%{http_code}\n'

实测输出:

HTTP:200

对比规则生效前后的解析结果。加规则前(正常解析出真实 IP):

dig @127.0.0.1 -p 5331 doubleclick.net +noall +answer

实测输出:

doubleclick.net.        300     IN      A       142.251.45.142

加规则后(拦截为 0.0.0.0,TTL 10 对应 blocked_response_ttl 默认值):

dig @127.0.0.1 -p 5331 doubleclick.net +noall +answer

实测输出:

doubleclick.net.        10      IN      A       0.0.0.0

在查询日志接口中也能看到这条被拦截的记录(reason 为 FilteredBlackList、命中规则原文回显):

curl -s -b /tmp/ah-cookie.txt \
  'http://127.0.0.1:8092/control/querylog?limit=1&response_status=filtered' | \
  python3 -c "import json,sys; d=json.load(sys.stdin)['data'][0]; print(json.dumps({k:d[k] for k in ['question','answer','reason','rule','client','status']}, ensure_ascii=False, indent=1))"

实测输出:

{
 "question": {
  "class": "IN",
  "name": "doubleclick.net",
  "type": "A"
 },
 "answer": [
  {
   "type": "A",
   "value": "0.0.0.0",
   "ttl": 10
  }
 ],
 "reason": "FilteredBlackList",
 "rule": "||doubleclick.net^",
 "client": "10.89.22.1",
 "status": "NOERROR"
}

4.8 自定义网络与子网自查

创建后自查两件事:子网未落在禁用段、宿主机默认路由未被抢占。

docker network inspect adguardhome-net --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}'

实测输出:

10.89.22.0/24
ip route get 192.168.1.62

实测输出(默认路由仍走物理网卡,未被新网桥抢占):

192.168.1.62 via 192.168.146.2 dev ens33 src 192.168.146.138

五、数据持久化说明

DNS 服务的数据(配置、规则、日志、统计)必须跨重启与升级保留。本章说明持久化机制并实测验证。

5.1 目录映射与数据构成

宿主机目录容器内路径内容
/opt/adguardhome/conf//opt/adguardhome/conf主配置 AdGuardHome.yaml(含管理员密码哈希、全部设置)
/opt/adguardhome/work//opt/adguardhome/work运行数据目录

work/data/ 下的关键文件实测(docker exec adguardhome-v0107-web ls -la /opt/adguardhome/work/data/):

total 64
drwx------    3 root     root          4096 Oct 18 10:18 .
drwx------    3 root     root          4096 Oct 18 10:16 ..
drwx------    2 root     root          4096 Oct 18 10:17 filters
-rw-------    1 root     root           890 Oct 18 10:18 querylog.json
-rw-------    1 root     root         32768 Oct 18 10:17 sessions.db
-rw-------    1 root     root         32768 Oct 18 10:18 stats.db

逐项说明:filters/1.txt 为过滤列表缓存(AdGuard DNS filter 实测 4,458,454 字节、186,099 行);querylog.json 为查询日志;stats.db 为统计数据库;sessions.db 为登录会话库。只要 conf/ 与 work/ 两个 bind mount 在,容器销毁重建、镜像升级均不丢数据。

💡 技术拓展:容器数据持久化方式对比——

方式特点适用场景
bind mount(./conf:...)路径直观,可直接编辑、tar 备份本文采用,配置需人工核对场景
named volume(adguard-conf:...)由 Docker 统一管理,迁移需 volume 导出无需直接触碰文件的场景
tmpfs内存盘,随容器消亡仅缓存类临时数据

本文选 bind mount:AdGuard Home 的配置与数据都是需要定期备份、离线检视的核心资产,宿主机目录直接可见最稳妥。

5.2 重启持久化实测

重启服务并验证规则与配置保留:

cd /opt/adguardhome && docker compose restart

实测输出:

 Container adguardhome-v0107-web Restarting
 Container adguardhome-v0107-web Started

重启后立即验证拦截规则仍然生效(数据来自挂载目录而非容器层):

dig @127.0.0.1 -p 5331 doubleclick.net +noall +answer

实测输出:

doubleclick.net.        10      IN      A       0.0.0.0

5.3 数据备份方法

最简备份即打包两个挂载目录(在 docker compose down 或服务运行时均可执行;运行时备份查询日志可能缺最后几秒,生产建议先 docker compose stop 再备份):

cd /opt/adguardhome && tar czf /opt/backup/adguardhome-$(date +%F).tar.gz conf work && ls -lh /opt/backup/

说明:$(date +%F) 生成 2026-10-18 形式的日期后缀;备份文件建议异地存放。恢复时解包回 /opt/adguardhome/ 后 docker compose up -d 即可,详见本专栏《AdGuard Home 日常运维手册》的备份恢复章节。

六、环境变量表

官方镜像不通过环境变量做业务配置,实测容器内环境仅含系统默认 PATH(docker inspect --format '{{json .Config.Env}}' 输出 ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"])。全部配置通过命令行参数与挂载的配置文件完成。

镜像内置入口使用的命令行参数实测(docker exec adguardhome-v0107-web /opt/adguardhome/AdGuardHome --help 节选,全量参数以该命令输出为准):

Usage:

/opt/adguardhome/AdGuardHome [options]

Options:
  -c, --config VALUE                 Path to the config file.
  -w, --work-dir VALUE               Path to the working directory.
  --web-addr VALUE                   Address to serve the web UI on, in the host:port format.
  -s, --service VALUE                Service control action: status, install (as a service), uninstall (as a service), start, stop, restart, reload (configuration).
  -l, --logfile VALUE                Path to log file.  If empty, write to stdout; if "syslog", write to system log.
  --pidfile VALUE                    Path to a file where PID is stored.
  --check-config                     Check configuration and exit.
  --no-check-update                  Don't check for updates.
  --update                           Update the current binary and restart the service in case it's installed.
  --local-frontend                   Use local frontend directories.
  -v, --verbose                      Enable verbose output.
  --glinet                           Run in GL-Inet compatibility mode.
  --no-permcheck                     Skip checking and migration of permissions of security-sensitive files.
  --version                          Show the version and exit.  Show more detailed version description with -v.
  --help                             Print this help.

参数说明表:

参数默认行为说明
-c, --config/opt/adguardhome/conf/AdGuardHome.yaml主配置文件路径,镜像默认已指向挂载目录
-w, --work-dir/opt/adguardhome/work工作目录(日志、过滤器缓存)
-s, --service无服务控制(容器内不适用,原生安装时用于注册 systemd 服务)
-l, --logfile输出到 stdout容器形态保持默认,由 docker compose logs 收集
--no-check-update不加则启动时检查更新容器升级应走「换镜像 tag」,故镜像默认命令已带此参数
--check-config—校验配置文件后退出,改配置后可先验证
--pidfile无指定 PID 文件路径,常配合监控脚本

如需向容器追加参数,在 compose 服务下使用 command:,例如开启 verbose 日志:

    command:
      - --no-check-update
      - -c
      - /opt/adguardhome/conf/AdGuardHome.yaml
      - -w
      - /opt/adguardhome/work
      - -v

版本号确认命令实测:

docker exec adguardhome-v0107-web /opt/adguardhome/AdGuardHome --version

实测输出:

AdGuard Home, version v0.107.79

七、配置参数说明

本章说明部署形态下「改配置的正确入口」,避免误改导致配置回滚。

7.1 两类配置的生效关系

配置层文件/位置修改方式生效方式
Compose 编排层docker-compose.yml手工编辑docker compose up -d(配置变化会自动重建容器)
运行配置层conf/AdGuardHome.yaml推荐 Web 界面或 REST APIAPI 修改即时生效并自动回写文件
运行配置层(直接改文件)conf/AdGuardHome.yaml手工编辑需 docker compose restart 后生效,且运行期间修改会被界面覆盖

⚠️ 关键提醒:Web 界面/API 每次改动都会全量回写 AdGuardHome.yaml。若直接手工编辑该文件,务必先 docker compose stop 再编辑,否则运行中的服务退出时会用内存配置覆盖你的手工修改。

7.2 配置文件校验

手工修改配置后、重启前,用内置校验命令检查语法:

docker exec adguardhome-v0107-web /opt/adguardhome/AdGuardHome --check-config -c /opt/adguardhome/conf/AdGuardHome.yaml -w /opt/adguardhome/work

实测输出(配置正常时):

2026/10/18 10:24:51.814780 [info]  AdGuard Home, version v0.107.79
2026/10/18 10:24:51.815044 [info]  loading config from file /opt/adguardhome/conf/AdGuardHome.yaml

校验通过(无 error/fatal 行且进程正常退出)即可 docker compose restart 使配置生效;AdGuardHome.yaml 全部字段的逐项含义与默认值见本专栏《AdGuard Home 0.107.79 配置参数详解》一篇。

7.3 常用即时验证命令汇总

验证目标命令预期
服务版本docker exec adguardhome-v0107-web /opt/adguardhome/AdGuardHome --versionAdGuard Home, version v0.107.79
运行状态curl -s http://127.0.0.1:8092/control/status(带 Cookie)JSON 中 "running": true
DNS 可用dig @127.0.0.1 -p 5331 www.baidu.com +short返回 IP 列表
拦截生效dig @127.0.0.1 -p 5331 doubleclick.net +short0.0.0.0

八、配置文件挂载

本章细化两个挂载目录的职责边界与运维注意事项。

8.1 conf 与 work 的职责边界

conf/ 只有一个 AdGuardHome.yaml,是「唯一事实来源」:管理员密码哈希、DNS 上游、过滤规则开关、查询日志策略等全部运行配置都在其中。work/ 是运行数据:过滤器列表缓存(work/data/filters/)、查询日志(work/data/querylog.json)、统计库(work/data/stats.db)、会话库(work/data/sessions.db)。

备份与迁移的最小集合是 conf/ + work/data/(work/ 下其余为临时文件)。

8.2 挂载目录权限

镜像内置权限自检(permcheck)会检查安全敏感文件权限。若宿主机目录权限过宽,启动日志会出现提示(实测日志行):

adguardhome-v0107-web  | 2026/10/18 10:20:17.836102 [info] permcheck: warning: found unexpected permissions type=directory path=/opt/adguardhome/work perm=0755 want=0700

该提示为 info 级不阻断启动,但生产建议收紧:chmod 700 /opt/adguardhome/work /opt/adguardhome/conf,容器内进程以 root 运行不受影响。

8.3 修改配置的标准流程

以修改 DNS 缓存大小为例(先停服避免回写覆盖):

cd /opt/adguardhome && docker compose stop

实测输出:

 Container adguardhome-v0107-web Stopping
 Container adguardhome-v0107-web Stopped

编辑 /opt/adguardhome/conf/AdGuardHome.yaml 中 cache_size 后校验并启动:

docker exec -it adguardhome-v0107-web /opt/adguardhome/AdGuardHome --check-config -c /opt/adguardhome/conf/AdGuardHome.yaml -w /opt/adguardhome/work 2>&1 | tail -1

说明:容器已停止时 docker exec 不可用,此校验命令需在容器运行状态下先执行,或直接启动后观察日志是否有配置解析错误。标准流程为「stop → 编辑 → up -d → 看日志确认无 error」:

cd /opt/adguardhome && docker compose up -d

实测输出:

 Container adguardhome-v0107-web Running

启动后 docker compose logs --tail 5 adguardhome 中出现 dnsproxy: cache enabled size=... 即配置已生效(实测日志行:dnsproxy: cache enabled size=4194304,对应默认 4MB 缓存)。

九、等价 docker run 对照

不使用 compose 时,等价的 docker run 命令如下(与第四章 compose 配置逐项对应):

docker run -d --name adguardhome-v0107-run \
  --restart unless-stopped \
  -p 8097:3000/tcp -p 5335:53/tcp -p 5335:53/udp \
  -v /opt/adguardhome-run/conf:/opt/adguardhome/conf \
  -v /opt/adguardhome-run/work:/opt/adguardhome/work \
  adguard/adguardhome:v0.107.79 \
  --no-check-update -c /opt/adguardhome/conf/AdGuardHome.yaml -w /opt/adguardhome/work

对照关系表:

compose 写法等价 docker run 写法
image: adguard/adguardhome:v0.107.79末位镜像参数
container_name: adguardhome-v0107-web--name adguardhome-v0107-run(对照实例独立命名)
restart: unless-stopped--restart unless-stopped
ports: "8092:3000/tcp" 等-p 8097:3000/tcp -p 5335:53/tcp -p 5335:53/udp
volumes: ./conf:... 等-v /opt/adguardhome-run/conf:... -v /opt/adguardhome-run/work:...
networks(自定义网络/子网)--network adguardhome-net(需先 docker network create --subnet 创建)
(无显式 command)镜像内置 CMD 即为 --no-check-update -c ... -w ...,两者实际等价

本环境另有一个按上述 run 形态部署的对照实例(Web 8097、DNS 5335),实测验证其与 compose 形态行为一致:

curl -s -o /dev/null -w 'Web_HTTP:%{http_code}\n' http://127.0.0.1:8097/ && \
docker exec adguardhome-v0107-run /opt/adguardhome/AdGuardHome --version && \
dig @127.0.0.1 -p 5335 www.baidu.com +noall +answer +stats | tail -5

实测输出:

Web_HTTP:302
AdGuard Home, version v0.107.79
;; Query time: 46 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1) (UDP)
;; WHEN: Sun Oct 18 18:14:42 CST 2026
;; MSG SIZE  rcvd: 146

选型建议:单机长期运行选 compose(声明式、可版本控制、升级一条命令);临时验证、CI 冒烟测试选 docker run;两者混用时注意端口与数据目录不能复用,否则会互相抢锁或报端口冲突。

十、常用运维命令

本章给出 compose 形态的日常运维命令与实测回显。

10.1 启停与状态

cd /opt/adguardhome && docker compose stop && docker compose start

实测输出:

 Container adguardhome-v0107-web Stopping
 Container adguardhome-v0107-web Stopped
 Container adguardhome-v0107-web Starting
 Container adguardhome-v0107-web Started

stop 保留容器与网络,start 秒级恢复;需要释放网络与容器时用 docker compose down(数据目录不受影响),再 up -d 即可完整重建。

10.2 日志查看

docker compose logs --tail 8 adguardhome

实测输出:

adguardhome-v0107-web  | 2026/10/18 10:21:05.530948 [info] filtering: saving contents id=1 path=/opt/adguardhome/work/data/filters/1.txt
adguardhome-v0107-web  | 2026/10/18 10:21:05.531090 [info] dnsproxy: entering udp listener loop addr=[::]:53
adguardhome-v0107-web  | 2026/10/18 10:21:05.531131 [info] dnsproxy: entering listener loop proto=tcp addr=[::]:53

跟踪实时日志加 -f;查历史错误用 docker compose logs adguardhome 2>&1 | grep -i error。

10.3 版本升级

AdGuard Home 发布新版后的标准升级流程(以 tag v0.107.80 为例,发布时替换为实际最新 tag):

cd /opt/adguardhome
sed -i 's|adguard/adguardhome:v0.107.79|adguard/adguardhome:v0.107.80|' docker-compose.yml
docker compose pull && docker compose up -d

说明:docker compose pull 拉取新镜像,up -d 检测到镜像变化会自动重建容器,conf/、work/ 两个 bind mount 保证配置与数据原样保留。当前 v0.107.79 已是最新稳定版时的实测回显(pull 无新层、up 检测到容器配置未变不会重建):

===COMPOSE PULL===
 Image adguard/adguardhome:v0.107.79 Pulling
 Image adguard/adguardhome:v0.107.79 Pulled
===COMPOSE UP -D(镜像未变)===
 Container adguardhome-v0107-web Running

升级后确认版本与数据:

docker exec adguardhome-v0107-web /opt/adguardhome/AdGuardHome --version && \
dig @127.0.0.1 -p 5331 doubleclick.net +short

实测输出:

AdGuard Home, version v0.107.79
0.0.0.0

回滚:将 compose 文件中的 tag 改回旧版本(如 v0.107.78)后 docker compose up -d,本地保留的历史镜像层可加速启动;若旧镜像已清理,docker compose pull 会重新拉取。

十一、常见问题

以下问题均为实测环境中真实发生并解决的过程记录。

11.1 宿主机 53 端口被 systemd-resolved 占用

现象:计划映射 53:53 时,宿主机 ss -lntup | grep :53 显示(实测输出):

udp   UNCONN 0      0      127.0.0.53%lo:53         0.0.0.0:*    users:(("systemd-resolve",pid=853,fd=13))
tcp   LISTEN 0      4096   127.0.0.53%lo:53         0.0.0.0:*    users:(("systemd-resolve",pid=853,fd=14))

定位:Ubuntu 22.04 默认启用 systemd-resolved 的 DNS stub(监听 127.0.0.53:53),/etc/resolv.conf 指向它。stub 只绑定回环地址 127.0.0.53,实测并不阻塞 Docker 对 0.0.0.0:53 的端口映射(本文 5331:53 与 53:53 均可启动);但当系统关闭 stub 改为通配监听 0.0.0.0:53 时,容器映射 53 端口会报 port is already allocated。

解决(二选一):

  • 方案 A(零改动):保持映射 5331:53,下游设备显式指定端口,本文实测即此形态;
  • 方案 B(释放 53):编辑 /etc/systemd/resolved.conf 设置 DNSStubListener=no,执行 systemctl restart systemd-resolved 后把 /etc/resolv.conf 的 nameserver 从 127.0.0.53 改为上游真实 DNS 或 127.0.0.1,随后映射 53:53。⚠️ 操作前先用 resolvectl status 确认本机解析链路,避免远程服务器失联。

11.2 端口被占用启动失败(port is already allocated)

现象:宿主机 8092 已被其他进程占用时 docker compose up -d 报错(实测输出):

 Container adguardhome-v0107-web Creating
 Container adguardhome-v0107-web Created
 Container adguardhome-v0107-web Starting
Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint adguardhome-v0107-web (7ab35a0c0ee38fed65c88ce42e9da5175d391cc205796c8b04d7196c24242fc2): Bind for 0.0.0.0:8092 failed: port is already allocated

定位:docker ps --format '{{.Names}} {{.Ports}}' 逐个查占用者,或 ss -lntp | grep 8092。

⚠️ 关键坑(实测踩中):此时再次执行 docker compose up -d 无法恢复——容器已停在 Created 状态,compose 判定「容器已存在且配置未变」仅执行 start,实测该容器启动后 docker compose ps 的 PORTS 列为空、Web/DNS 全部不通。正确恢复流程:先 docker compose down(强制删除异常容器)再 docker compose up -d(重建),端口映射即恢复正常(实测恢复后 curl 返回 Web_HTTP:302、dig 拦截返回 0.0.0.0)。

11.3 默认上游(Quad9 DoH)解析超时

现象:初始化完成后 dig @127.0.0.1 -p 5331 任何域名都超时(;; communications error to 127.0.0.1#5331: timed out,完整回显见 4.6 节)。

定位:GET /control/dns_info 实测默认上游为 https://dns10.quad9.net/dns-query,该国外 DoH 地址在多数国内网络不可达;Web 界面对应「设置 → DNS 设置 → 上游 DNS 服务器」。

解决:改用国内可达上游(223.5.5.5、119.29.29.29、https://dns.alidns.com/dns-query,API 调用见 4.6 节,实测改后 www.baidu.com 恢复正常解析)。若需继续使用国外 DoH/DoT 上游,需自备可靠出海链路。

11.4 过滤规则接口报 415(content-type 错误)

现象:以 text/plain 提交规则列表报错(实测输出):

only content-type application/json is allowed
HTTP_CODE:415

定位:v0.107.x 的 POST /control/filtering/set_rules 严格要求 JSON 请求体 {"rules":[...]},不接受纯文本规则列表。

解决:按 4.7 节的 JSON 写法提交(实测 HTTP:200)。另实测发现规则提交返回 200 后的极短窗口内(毫秒级规则引擎重载期),紧随其后的第一次查询可能未被拦截(实测出现过一次返回 NXDOMAIN 而非 0.0.0.0),第二次查询起拦截稳定生效;脚本化下发规则后建议 sleep 1 再做验证查询。

11.5 过滤列表下载缓慢或失败

现象:首次启动后 filters 目录迟迟无文件、GET /control/filtering/status 中 rules_count: 0。

定位:默认 AdGuard DNS filter 托管在 GitHub Pages(adguardteam.github.io),部分网络环境直连缓慢;服务器可出网时稍候即可,实测约 15 秒完成(日志 filtering: filter updated id=1 bytes_written=4458454 rules_count=186099)。

解决:为下载配置代理可在 Web 界面「设置 → DNS 设置」中调整,或直接手动将列表文件内容粘贴到自定义过滤列表;内网环境可在「过滤器」页手动添加本地可达镜像源的 URL。

11.6 启动日志出现 permcheck 权限告警

现象:日志出现(实测行):

permcheck: warning: found unexpected permissions type=directory path=/opt/adguardhome/work perm=0755 want=0700

定位与解决:镜像内置的安全权限自检建议数据目录 0700,info 级告警不影响运行;生产执行 chmod 700 /opt/adguardhome/conf /opt/adguardhome/work 消除即可。

十二、参考链接

  1. AdGuard Home 官方仓库:https://github.com/AdguardTeam/AdGuardHome
  2. 官方 Docker 指南(docker/README.md):https://github.com/AdguardTeam/AdGuardHome/blob/master/docker/README.md
  3. Docker Hub 镜像页(tag 与多架构):https://hub.docker.com/r/adguard/adguardhome
  4. 官方 Getting Started:https://adguard-dns.io/kb/adguard-home/getting-started/
  5. 官方 OpenAPI 规范(/control/ 接口定义):https://github.com/AdguardTeam/AdGuardHome/tree/master/openapi
  6. 本专栏配套文档:《AdGuard Home 0.107.79 介绍与选型指南》