Debian 13 宝塔面板 Docker 管理无法显示容器 — 修复方案
问题描述
在 Debian 13 (Trixie) 下安装 Docker 后,宝塔面板的 Docker 管理页面无法显示正在运行的容器,容器列表为空。但通过命令行执行 docker ps 可以正常查看容器。
根本原因
Debian 13 默认启用了 AppArmor 安全策略,该策略阻止了 curl 命令通过 Unix Socket 访问 /var/run/docker.sock。
而宝塔面板的 Docker 模块在获取容器列表、容器详情等数据时,底层代码依赖 curl 命令通过 Unix Socket 调用 Docker API:
# 宝塔原始代码(container.py)
curl -s --unix-socket /var/run/docker.sock http:/127.0.0.1/containers/json?all=1
由于 AppArmor 阻止了 curl 对 Unix Socket 的访问,该命令返回空数据,导致面板无法显示任何容器信息。
验证方法:
# curl 访问 Docker Socket — 无输出(被 AppArmor 阻止)
curl -s --unix-socket /var/run/docker.sock http://localhost/containers/json?all=1
# Python 访问 Docker Socket — 正常返回数据(不受 AppArmor 限制)
python3 -c "
import http.client, socket
class UnixConn(http.client.HTTPConnection):
def __init__(self, sock_path):
super().__init__('localhost')
self._sock_path = sock_path
def connect(self):
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.sock.connect(self._sock_path)
conn = UnixConn('/var/run/docker.sock')
conn.request('GET', '/containers/json?all=1')
print(conn.getresponse().read().decode()[:200])
"
修复方案
将宝塔 Docker 模块中依赖 curl 的 API 调用改为 Python 原生 Socket 方式,绕过 AppArmor 限制。
需要修改的文件:
/www/server/panel/class/btdockerModel/dockerSock/container.py
第一步:备份原文件
cp /www/server/panel/class/btdockerModel/dockerSock/container.py \
/www/server/panel/class/btdockerModel/dockerSock/container.py.bak
第二步:执行修复脚本
将以下内容保存为 /tmp/fix_docker.py 并执行:
第三步:清理缓存并重启面板
第四步:验证
刷新宝塔面板 Docker 页面,确认容器列表正常显示。
注意事项
宝塔面板升级可能覆盖修改: 如果后续升级了宝塔面板,
container.py可能被还原,需要重新执行修复脚本。建议保留/tmp/fix_docker.py脚本以备用。其他 Docker 功能如有类似问题: 如果镜像管理、网络管理、存储卷管理等功能也出现异常,可以检查
/www/server/panel/class/btdockerModel/dockerSock/目录下的image.py、network.py、volume.py等文件,查找类似的curl --unix-socket调用,用同样的_request_docker_api()方法替换。回滚方法: 如果需要还原修改:
修复原理
| 项目 | 修复前(原始方式) | 修复后(Python Socket) |
|---|---|---|
| 通信方式 | 调用系统 curl 命令 | Python http.client + socket |
| 连接方式 | curl --unix-socket | socket.AF_UNIX 直连 |
| AppArmor 兼容 | 被阻止,无法连接 | 不受限制,正常通信 |
| 依赖 | 依赖外部 curl 命令 | 仅依赖 Python 标准库 |