# docker-center **Repository Path**: jinghui111/docker-center ## Basic Information - **Project Name**: docker-center - **Description**: 飞牛docker容器管理增强版 — 面向多应用用户的 Docker 管理与监控面板 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-26 - **Last Updated**: 2026-10-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 飞牛docker容器管理增强版(docker-center) ![概览](screenshots/01-overview.png) 👉 **想一次看完 7 张截图**:[Wiki · 界面截图](https://gitea.88531.cn/jinghui/docker-center/wiki/%E7%95%8C%E9%9D%A2%E6%88%AA%E5%9B%BE) 面向**多应用用户**的 Docker 管理与监控面板。核心不是「一堆容器」,而是把容器按 **应用(Compose 项目 / 单容器)** 聚合:一眼看哪个应用坏了、占用多少、怎么一键恢复。 > 所有截图都是在 **61 个容器真实运行** 的机器上直接截的(1440×900,无示意图),往下滚可看全部 7 张。 ![运行的容器列表](screenshots/02-containers.png) ## 界面截图 | | | |---|---| | **单容器详情抽屉**:资源曲线 / 日志 / 配置 / 挂载网络四个 tab,一键停止·重启·暂停·删
![容器详情](screenshots/03-app-detail.png) | **本地镜像**:占用、导出、批量启停删
![本地镜像](screenshots/04-images.png) | | **网络**:列表 + 新建网络
![网络](screenshots/05-networks.png) | **备份与恢复**:面板数据 + Compose 配置打包下载
![备份](screenshots/06-backup.png) | ![告警设置](screenshots/07-alerts.png) ## 它解决什么问题 Docker 自带面板和 Portainer 都是按「容器」管理:六十多个容器翻半天,一个应用里某个容器挂了根本看不出来。 本面板按**应用**(Compose 项目)聚合:一个应用 = 一组容器。打开就是「哪个应用坏了、吃多少资源、该优化什么」,坏的应用永远排在最前面。 ## 功能一览 **概览(仪表盘)** - 统计条:应用总数 / 异常 / 注意 / 资源占用 / 运行容器 - **性能趋势三图并列**:流量、CPU、内存;支持今天 / 昨天 / 近 30 天 / 近 12 个月,也能查任意一天(3 秒采样、按小时落盘,重启不丢) - **四个 Top 5 榜并列**:CPU、内存、网络、运行时长,点任意一行进详情 - **优化建议**:10 类规则自动扫描(特权容器、挂 docker.sock、无内存上限、无健康检查、latest 镜像、悬空镜像、构建缓存、磁盘不足、反复重启、未纳入 Compose),可一键清理 - 需要关注的应用(只列异常/注意,最多 6 个)+ 最近事件时间线 **应用管理** - 健康判定:部分容器未运行 → 红;健康检查失败 → 红;整体停止/资源超阈值 → 黄 - 每张卡片:CPU(占整机)、内存、网络、端口(点开直达)、**已运行时长**、24h 可用率、重启次数、问题摘要,卡片内直接启停重启 - 应用详情:全部容器表格 + 聚合日志(多容器合并)+ 事件,支持整应用启停 **容器与项目** - 运行的容器:只列运行中,默认按**最新安装**排序,也可按 CPU/内存/网络/磁盘IO/进程数/名称排序,显示已运行时长 - 本地镜像(可清理悬空镜像)、镜像仓库拉取、**批量 Compose 部署**(多段用 `---` 分隔,可指定安装目录/项目名/ENV 参数)、网络 **备份与恢复** - 一键备份面板数据(设置/事件/流量·CPU·内存历史)与 Compose 应用配置文件(不含数据卷),生成 tar.gz 可直接下载;附 `manifest.json` **性能限制** - 在容器抽屉或应用详情页给应用设 CPU(核)与内存(MB)上限,走 Docker cgroup 硬限制;应用级一次对全部容器生效,行内显示 `限 0.3核/96M` 角标;限制值持久化在 `data/limits.json` **顶栏外链** - 右上角、页面底部常驻横条、**每个页面内容末尾的推广卡片**三处都有「开源地址 / 导航站」入口,默认指向本机 Gitea 仓库与 BestNav;可在告警设置页改成自己的地址 **告警** - CPU/内存阈值、Webhook 推送、同应用去重间隔、测试推送 ## 和常见方案比 | 能力 | Portainer | Netdata / Beszel | 飞牛自带 | 本项目 | |---|---|---|---|---| | 按「应用」聚合管理 | ✗ | ✗ | ✗ | **✓** | | 异常优先排序(打开就知道哪坏了) | ✗ | ✗ | ✗ | **✓** | | 流量 / CPU / 内存 历史曲线(天·月·年 + 查某天) | ✗ | 有,但按容器 | ✗ | **✓ 按应用 + 整机** | | 优化建议 + 一键清理空间 | ✗ | 仅告警 | ✗ | **✓ 10 类规则** | | 一键启动「有镜像没起容器」的项目 | ✗ | ✗ | 部分 | **✓** | | 资源占用 | ~50MB+ | 200MB+ / 需装 agent | — | **约 40MB,无 agent、无数据库** | | 中文界面 | 部分 | ✗ | ✓ | **✓** | ## 优势 1. **按应用而不是容器** —— 多应用用户最痛的点,60 个容器变 50 个应用,一眼看清整体 2. **坏的应用永远排第一** —— 异常优先排序 + 菜单角标,不用再逐个点开找 3. **能直接省磁盘** —— 优化建议里悬空镜像、构建缓存可一键清理(本机实测约 55GB) 4. **趋势一眼可见** —— 三图并列 + 四榜并列,谁在偷偷吃 CPU/内存/带宽立刻现形 5. **够轻** —— 单容器约 40MB,无 agent、无 Prometheus、无数据库,数据以小时账本存本地 JSON 6. **零配置安装** —— 一条 `install.sh` 自动探测 docker 目录、生成配置、等待健康检查 7. **纯本地** —— 不依赖任何云服务,数据不出内网 > 安全提示:面板挂载 `/var/run/docker.sock`(等同宿主 root),**不要直接暴露公网**。 ## 安装(新用户) 前置:Linux/飞牛 NAS 上已装 Docker 与 compose 插件(`docker compose version` 能跑)、有 `git`。 ```bash curl -fsSL https://gitee.com/jinghui111/docker-center/raw/main/install.sh | bash ``` 脚本做的事:检查环境 → 自动探测 docker 目录 → 拉源码到安装目录 → 写 `.env` → `docker compose up -d --build` → 等健康检查通过 → 打印访问地址。 可覆盖参数(写在 `curl` 前面): ```bash PORT=8080 \ COMPOSE_ROOT=/你的/docker目录 \ INSTALL_DIR=/opt/docker-center \ bash install.sh ``` | 变量 | 默认值 | 说明 | |---|---|---| | `PORT` | `7030` | 面板访问端口 | | `COMPOSE_ROOT` | 自动探测(飞牛 `/vol1/1000/HD1/docker`,其次 `~/docker`) | 扫描 compose 文件、判断「未启动应用」的根目录 | | `INSTALL_DIR` | `/vol1/1000/HD1/docker/docker-center` | 源码与数据目录 | | `CONTAINER_NAME` | `docker-center` | 容器名 | | `REPO_URL` | `https://gitee.com/jinghui111/docker-center` | 换源时用(内网可指向自建 Gitea) | 升级:再跑一次同一条命令即可(检测到已有仓库会 `fetch` + `reset --hard` 后重建)。 卸载:`cd <安装目录> && docker compose down -v && cd .. && rm -rf <安装目录>`。 ### 用预构建镜像安装(不编译源码) 镜像已发布到公开仓库,**无需登录直接拉取**(两个地址内容完全一致,digest `sha256:37022ce4...`): ```bash # 腾讯云 TCR(东京节点,海外/国内都稳,推荐) docker pull jpccr.ccs.tencentyun.com/jinghui/docker-center:1.0.1 # 自建 Gitea(国内备用) docker pull gitea.88531.cn/jinghui/docker-center:1.0.1 ``` ```yaml services: docker-center: image: jpccr.ccs.tencentyun.com/jinghui/docker-center:1.0.1 container_name: docker-center ports: ["7030:7030"] volumes: - /var/run/docker.sock:/var/run/docker.sock - /:/host:ro - ./data:/app/data environment: - TZ=Asia/Shanghai restart: always ``` 用到外部仓库时,把 `image` 换成对应地址即可。完整发布/推送流程(阿里云 ACR、腾讯云 TCR、Docker Hub、自建 Gitea、多架构)见 **[docs/publish-image.md](docs/publish-image.md)**: ```bash docker login -u <用户名> NAMESPACE=<命名空间> ./scripts/push-image.sh aliyun 1.0.0 # 或 tencent / dockerhub / gitea-lan ``` > 安全提示:面板挂载了 `/var/run/docker.sock`(等同宿主 root),**不要直接暴露公网**,放在内网或前面套一层带鉴权的反代。 ## 版本与公告 面板右上角常驻版本号。有新版本时变成 `v1.0.2 → v1.0.3` 的高亮样式,点开能看到更新说明和发布页;公告走同一个铃铛入口,未读有红点,重要公告会弹一次窗(看过不再弹)。 数据来自授权中心(本项目的自建实例)。**上报内容只有三项**:随机生成的机器码、当前版本号、运行平台(linux/amd64 之类),不含容器名、镜像名、日志或任何业务数据。 不想上报就加一个环境变量 `HUB_DISABLED=1`(或在 `data/settings.json` 里把 `telemetry` 设为 `false`),关掉后不再上报,只保留公告拉取;授权中心挂掉时面板功能完全不受影响(失败开放)。面板界面不展示机器码、安装编号这些内部信息。 如果要指向自己的授权中心,改这三个环境变量即可: ```yaml environment: - HUB_URL=https://auth.example.com - HUB_API_KEY=ak_xxxxxxxx - HUB_PROJECT_ID=7 ``` ## 为什么按「应用」而不是「容器」管 61 个容器里其实只有 50 个应用(app + db + redis 属于同一个项目)。按容器管要逐个点,按应用管只需看: - 这个应用**整体**是否健康(部分容器挂了会标红,而不是淹没在列表里) - 它总共吃多少 CPU/内存、占了哪些端口 - 一键启动/停止/重启**整个应用** - 出问题时有一条事件、一份合并日志 ## 页面 | 页面 | 内容 | |---|---| | 概览(默认) | 纯仪表盘:应用总数/异常/注意/资源/运行容器统计条、**性能趋势三图并列**(流量 / CPU / 内存,今天·昨天·近30天·近12个月 + 查某一天,按小时记账落盘)、**CPU 与内存占用 Top 5**、优化建议、**需要关注的应用**(仅异常/注意,最多 6 个,卡片可直接启停)、最近事件;右上「查看全部应用」进入完整列表 | | 全部应用 | 完整应用卡片列表(50 个):筛选(全部·有问题·已停止·高占用)、排序、状态胶囊、CPU/内存/网络、端口、已运行时长、可用率、重启次数、卡片内启停与详情;顶部可返回概览 | | 应用详情 | 应用级指标 + 全部容器表格(状态/健康/CPU/内存/网络/重启/运行时长/单容器操作)+ 三个标签页:容器、聚合日志(多容器合并、按容器名加前缀)、事件;顶部可整应用启停重启 | | 运行的容器 | 只列运行中容器;**默认按最新安装排序**(可选 CPU/内存/网络/磁盘IO/进程数/名称,按页面记忆)、搜索;行内显示**安装时间**、启停/重启/删除/详情/打开端口;有限制的容器显示 `限 0.3核/96M` 角标 | | (停止的容器) | 侧栏已隐藏该入口;页面代码保留,含「有镜像但未启动的应用」批量启动/删除与已停止容器批量删除 | | 本地镜像 | 使用情况(运行中/已停止引用/未使用)、**单个/批量导出 tar.gz**(保留 tag)、**导入 tar/tar.gz**、**批量删除**(被占用自动跳过)、**批量启动运行**(弹窗设重启策略/网络/端口/环境变量)、清理悬空镜像 | | 镜像仓库 | 拉取镜像(流式进度);**批量 Compose 部署**:`# 目录:` / `# 项目:` / `# ENV: KEY=VALUE` + `---` 分隔多项目,可加安装目录前缀 | | 网络 | **新建**(驱动/子网/网关/内部)与删除;内置与被占用的网络不可删;列出名称/驱动/子网/网关/容器数 | | 备份与恢复 | 备份面板数据 + Compose 配置为 tar.gz,可下载/删除,附 `manifest.json` | | 告警设置 | CPU/内存阈值、推送间隔、Webhook、开关、测试推送、查看事件 | 顶栏工具条:搜索、排序字段、升/降序切换、**刷新间隔(1/2/3/5/10/30 秒,默认 3 秒,存浏览器本地)**、**暂停/继续自动刷新**、手动刷新、添加容器。后端采样固定 3 秒,所以设成 1~2 秒只是更勤地读缓存,不会更快拿到新数据。 自动刷新是「无感」的:输入框/下拉正在聚焦、容器详情抽屉打开、处于设置或备份页、或刚有鼠标键盘操作(5 秒内)时会跳过重绘,静默刷新还会保留滚动位置——不会把你填到一半的表单或打开的窗口刷没。 ## 首页优化建议 首页统计条下面是一块**优化建议**:服务端根据当前真实状态(容器配置 + 实时占用 + Docker 磁盘)生成,按 高 / 中 / 低 排序,超过 4 条自动折叠。 | 级别 | 规则 | |---|---| | 高 | 特权容器(privileged);容器重启 ≥3 次;磁盘可用 <10% | | 中 | 挂载 docker.sock;内存占用接近上限(>85%);单容器 CPU >60%;容器未设内存上限且合计 >1GB;悬空镜像 >1GB;构建缓存 >5GB;应用整体已停止 | | 低 | 对外容器没有 HEALTHCHECK;使用 latest 镜像;单容器应用未纳入 Compose | - 同类问题会**合并成一条**(例如「31 个应用使用 latest 镜像,涉及 …」),不会一个应用刷一条。 - 可一键处理的直接给按钮:**清理悬空镜像**、**清理构建缓存**(都不影响运行中的容器)、**启动已停止应用**;其余给「查看」跳到应用详情自己改 compose。 - 建议每次刷新(3 秒)重新计算,但 Docker 磁盘统计缓存 60 秒,避免频繁扫描镜像层。 ## 健康判定规则 | 级别 | 触发条件 | |---|---| | 异常(红) | 应用里**部分容器未运行**(其余在跑);任一容器健康检查 `unhealthy` | | 注意(黄) | 应用整体已停止;健康检查 `starting`;CPU 占整机超阈值;容器内存占上限超阈值;容器重启次数增加(单独一条事件) | | 正常(绿) | 以上都不满足 | - 状态从正常→异常/注意、异常→恢复都会写一条事件;「一上线就异常」的应用首次发现也会补记一条。 - 可用率:每分钟记录一次应用是否正常,保留 24 小时,卡片显示窗口内可用率。 - 事件保留最近 400 条(内存),重启服务后清空。 ## 告警推送(Webhook) 在「告警设置」填 Webhook 地址,收到的是 POST JSON: ```json { "title": "[异常] my-app", "level": "critical", "app": "my-app", "detail": "1 个容器未运行(my-app-db)", "time": "2026/10/26 16:43:46", "host": "gzFNos2" } ``` 注意两点: 1. **容器内的 `127.0.0.1` 是容器自己**,要推给宿主机上的服务请用宿主 LAN IP(如 `http://192.168.68.19:端口/hook`)或 `http://host.docker.internal:端口/hook`(compose 已加 `host-gateway`)。 2. 同一应用在 `debounceMinutes`(默认 10 分钟)内只推一条,避免刷屏。 ## 运维 默认部署:端口 `7030`,`restart: always`,内存上限 384MB(实测常驻约 40MB),源码目录 `/vol1/1000/HD1/docker/docker-center`。 ```bash cd /vol1/1000/HD1/docker/docker-center docker compose up -d --build # 改动后重建 docker compose logs -f # 看日志 docker compose restart # 重启 ``` - 配置持久化:`data/settings.json`(阈值、webhook、开关) - 环境变量:`PORT`、`SAMPLE_MS`(3000)、`INSPECT_MS`(15000)、`DISK_PATH`、`SETTINGS_PATH` ## 实现要点 / 坑 - 采样:每 3 秒并行拉一次所有运行中容器的 `stats`;CPU% 用 `cpu_stats`/`precpu_stats` 差值 × 核数;内存扣 `inactive_file`;网络与块设备速率靠相邻采样差分。 - 重启次数/健康状态来自 `inspect`,每 15 秒才刷一遍(每 3 秒 inspect 61 个容器太重)。 - 日志是 Docker 的 8 字节头多路复用流,用 `demuxLogs` 手动解帧;`modem.demuxStream` 在 follow=false 时会挂住请求。 - 排序比较器统一按「降序」写,`order=asc` 时取反,否则会出现 desc 变升序。 - 详情页是独立视图状态(`app-detail`),轮询刷新时必须保住它,否则每 4 秒会被看板覆盖。 ## 已知限制 - 曲线与可用率都在内存里,重启服务后重新累积(可用率保留 24 小时窗口)。 - 不提供在线改容器配置,改配置请用 Compose 或重建容器。 - 应用归属依赖 `com.docker.compose.project` 标签;手工 `docker run` 的容器各自算一个「单容器应用」。