Photonicat 2 Docker 使用指南

来自Photonicat Wiki
C2h2留言 | 贡献2026年7月13日 (一) 00:47的版本 (New topic: Docker on photonicat 2 — dockerman/compose, /opt data-root, wan_mode, and the Docker-27 ip6tables IPv6 pitfall with correct fix)
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳转到导航 跳转到搜索
适用 / Applies to Photonicat 2, photonicatWrt 26.04.x(Docker 27.0.2, docker-compose v2.28, LuCI dockerman) / Photonicat 2, photonicatWrt 26.04.x (Docker 27.0.2, docker-compose v2.28, LuCI dockerman)

photonicatWrt 26.04 出厂即带完整 Docker 环境:Docker Engine 27.0.2 + docker-compose v2 + LuCI 图形管理(dockerman)。本页覆盖日常使用、存储位置、防火墙行为,以及一个影响全网 IPv6 的重要坑及其正确修复方式。1 代用户请参考 Photonicat Openwrt Docker/istore

photonicatWrt 26.04 ships a complete Docker stack: Docker Engine 27.0.2 + docker-compose v2 + the LuCI dockerman GUI. This page covers daily use, storage, firewall behavior, and one important pitfall that breaks IPv6 for the whole LAN plus its correct fix. Gen-1 users see Photonicat Openwrt Docker/istore.

中文说明

使用入口

  • 图形界面:LuCI → Docker(dockerman),可管理镜像、容器、网络、卷。
  • 命令行(SSH):dockerdocker compose 均可直接使用:
docker info | grep -E 'Server Version|Root Dir'
docker run -d --name uptime-kuma -p 3001:3001 louislam/uptime-kuma
docker compose up -d        # 在含 docker-compose.yml 的目录下

存储位置

  • 镜像/容器数据目录(data-root)由出厂的 /etc/docker/daemon.json 指定为 /opt,位于系统 overlay 分区(约 3.7 GB)。
  • 跑多个容器建议把大数据挂到 NVMe/SD 上:优先用 -v /mnt/nvme/...:/data 挂卷,而不是搬移 data-root。
  • 不要随意改 data-root:改了之后已有镜像会"消失"(其实还在旧目录占着空间)。

防火墙行为(wan_mode)

Docker 由 /etc/init.d/docker 启动,行为由 UCI 选项控制:

uci show docker            # docker.@docker[0].wan_mode
  • wan_mode='0'(默认):以 --iptables=false 启动——Docker 不改动 IPv4 防火墙,规则完全由 fw4 掌管,端口发布经用户态代理转发。最干净、推荐。
  • wan_mode='1':允许 Docker 自行管理 iptables(容器间隔离、DNAT 端口映射由 Docker 负责)。需要复杂容器网络时才用。

⚠ 重要坑:Docker 27 默认接管 IPv6 防火墙

即使 wan_mode='0'(IPv4 不接管),Docker 27 起 ip6tables 是独立开关且默认开启:启动时会创建 ip6 filter FORWARD 链并置 policy drop —— 结果是路由器不再转发任何 IPv6,内网设备拿到公网 IPv6 地址却上不了网(fw4 放行也无效,因为两条链是"与"关系)。

检查是否中招:

nft list chain ip6 filter FORWARD
# 看到 "policy drop" 且计数增长 = 中招

正确修复:在出厂 daemon.json 基础上追加一行 "ip6tables": false

cat > /etc/docker/daemon.json <<'EOF'
{
"data-root": "/opt/",
"log-level": "warn",
"ip6tables": false
}
EOF
/etc/init.d/docker restart

三个不要

  1. 不要删除/改动出厂的 data-root(镜像会"消失",见上);
  2. 不要往 daemon.json 添加 "iptables" 键——它与启动参数 --iptables=false 冲突,Docker 会在下次开机拒绝启动(dockerd 对"同一项既是命令行参数又在配置文件"直接报错退出);
  3. 不要用 ip6tables -P FORWARD ACCEPT 之类的手工命令当永久方案——重启后 Docker 会重建 drop 链。

两个启动脚本的说明

系统里同时存在两个 Docker 启动脚本,实际生效的是前者:

  • /etc/init.d/docker(S25,luci-app-docker 提供):开机先启动,读取 UCI docker.wan_mode真正拉起 dockerd。dockerd 会自动读取默认配置文件 /etc/docker/daemon.json——这就是上面修复生效的原因。
  • /etc/init.d/dockerd(S99,OpenWrt 标准包):开机时 dockerd 已在运行,它的实例不会生效;其 UCI 配置(/etc/config/dockerd)对实际运行的 Docker 基本无效。排障时别被它误导。

English

Entry points

  • GUI: LuCI → Docker (dockerman) — images, containers, networks, volumes.
  • CLI (SSH): both docker and docker compose work out of the box (see examples above).

Storage

  • The data-root is set by the factory /etc/docker/daemon.json to /opt on the system overlay (~3.7 GB).
  • For heavy use, keep bulky data on NVMe/SD via bind mounts (-v /mnt/nvme/...:/data) rather than moving the data-root.
  • Don't casually change data-root — existing images "disappear" (while still consuming space in the old location).

Firewall behavior (wan_mode)

Docker is launched by /etc/init.d/docker, controlled by UCI:

  • wan_mode='0' (default): started with --iptables=false — Docker never touches the IPv4 firewall; fw4 owns all rules and published ports go through the userland proxy. Cleanest, recommended.
  • wan_mode='1': Docker manages iptables itself (container isolation, DNAT port mapping). Only for complex container networking.

⚠ The big pitfall: Docker 27 hijacks the IPv6 firewall by default

Even with wan_mode='0', ip6tables is a separate switch, enabled by default since Docker 27: at startup it creates an ip6 filter FORWARD chain with policy drop — the router stops forwarding all IPv6. LAN clients hold global IPv6 addresses but can't reach the internet, and fw4's accepts don't help (the chains AND together).

Check: nft list chain ip6 filter FORWARD — "policy drop" with a growing counter means you're hit.

Correct fix: append "ip6tables": false to the factory daemon.json (full file above), then /etc/init.d/docker restart.

Three don'ts:

  1. Don't remove/alter the factory data-root (images "disappear", see above);
  2. Don't add an "iptables" key — it conflicts with the launch flag --iptables=false and dockerd refuses to start at next boot (it hard-errors when the same directive is both a flag and in the config file);
  3. Don't rely on manual ip6tables -P FORWARD ACCEPT — Docker recreates the drop chain after a reboot.

About the two init scripts

Two Docker init scripts coexist; the first one wins:

  • /etc/init.d/docker (S25, from luci-app-docker): starts first at boot, reads UCI docker.wan_mode, and actually launches dockerd. dockerd reads the default config file /etc/docker/daemon.json — which is why the fix above works.
  • /etc/init.d/dockerd (S99, the standard OpenWrt package): by the time it runs, dockerd is already up, so its instance never takes effect; its UCI config (/etc/config/dockerd) is effectively inert on this firmware. Don't let it mislead you while debugging.

Photoincat 2 IPv6 PPPoEPhotonicat Openwrt Docker/istorePhotonicat 2 管理界面新功能 (2026)