praneeth-etta/docksurf
GitHub: praneeth-etta/docksurf
一款键盘驱动的终端 TUI 工具,用于实时可视化和管理 Docker 容器、镜像、卷与网络等全部资源。
Stars: 17 | Forks: 0
# docksurf
一个基于键盘驱动的终端 UI,用于可视化和管理 Docker 资源(如 container、image、volume 和 network)。具备 Compose 感知和实时特性:它会自动响应 Docker 事件并流式传输实时资源使用情况,因此你是在观察,而不是在轮询。无需 GUI,无需浏览器标签页。

**文档:** [快速开始](https://github.com/praneeth-etta/docksurf/blob/main/QUICKSTART.md) · [完整按键参考](https://github.com/praneeth-etta/docksurf/blob/main/KEYBINDINGS.md) · [更新日志](https://github.com/praneeth-etta/docksurf/blob/main/CHANGELOG.md)
## 核心特性
- **默认实时** — 表格会根据 `docker events` 自动刷新(container 启动/停止/死亡,image 拉取/删除等);`r` 用于手动重新加载。
- **本地或远程** — 启动时遵循当前激活的 `docker context`:本地、Docker Desktop、Colima,或通过 SSH/TCP 连接的远程主机。
- **感知 Docker Compose** — container 按项目分组为可折叠的树状结构,支持项目级别的 up/down/stop/start/restart,按服务着色的日志,以及使用 `B` 原地重新构建并重新创建单个服务。
- **实时资源统计** — 将选中运行中的 container 的 CPU 百分比、内存、网络和块 I/O 流式传输到详情面板中。
- **完整的生命周期控制** — pause/unpause 和 kill 与 stop/start/restart 并列,因此当 `stop` 在其 10 秒超时期间卡住时,无需再使用 CLI。
- **多选 + 批量操作** — 在任何标签页上标记行,并批量进行 stop/start/remove;非常适合在测试运行后进行清理。
- **检查与清理** — 在可搜索的模态框中查看任何资源完整的原始 `docker inspect` JSON,外加一键菜单,用于清理已停止的 container、悬空的 image、未使用的 volume/network,或一次性清理所有内容。
- **完整的 image/volume/network CRUD** — 针对 image 的拉取、打标签和层历史记录;针对 volume 的创建及磁盘占用大小查看;针对 network 的创建及连接/断开(详见[标签页](#tabs))。
- **高级用户的 exec 与复制** — 带有指定用户的自定义 exec 命令、向 container 内外执行 `docker cp`,以及按需获取的 `docker top` 进程快照,均通过快捷提示完成。
- **完全可控的日志查看器** — 实时跟随、日志内搜索、时间戳、可配置的 tail/`--since`,以及鼠标拖拽选择文本进行复制 (`Ctrl+C`)。
- **一目了然的运行状态信号** — 带有颜色的健康状态、运行时间和重启次数,以及详情面板中近期的 health-check 探针输出。
- **磁盘使用情况** — 按需提供 `docker system df` 的细分(每种类型的大小及可回收空间)。
- **应用内切换 context** — 直接在 TUI 中列出并切换 Docker context (`D`),并在重启后记住选择。
- **自动重连** — 如果 daemon 在会话期间宕机,DockSurf 会在其恢复的瞬间自动重新连接并刷新。
## 环境要求
- 一个可访问的 Docker daemon(本地,或通过 `docker context` 访问的远程 daemon)
- Python 3.11+ 和 [`uv`](https://github.com/astral-sh/uv) — 如果使用[独立二进制文件](#install)则无需安装
- 位于 `PATH` 中的 `docker` CLI — 仅在执行 exec-shell (`e`/`E`)、Compose 项目操作 (`u`/`k`) 和文件复制 (`C`) 时需要;其他所有操作均使用 SDK。如果缺失,DockSurf 会优雅降级。
## 安装
请参阅 [QUICKSTART.md](https://github.com/praneeth-etta/docksurf/blob/main/QUICKSTART.md),了解如何在 2 分钟内完成安装和初步操作。
**通过 [PyPI](https://pypi.org/project/docksurf/) 安装:**
```
pip install docksurf
docksurf
```
或者通过 [`uvx`](https://docs.astral.sh/uv/guides/tools/) 免安装运行:
```
uvx docksurf
```
**独立二进制文件**(无需 Python/pip/uv)— 从[最新发布版本](https://github.com/praneeth-etta/docksurf/releases/latest)下载适合你操作系统的文件:
- Linux: `docksurf-linux-x86_64`
- macOS (Apple Silicon): `docksurf-macos-arm64`
- Windows: `docksurf-windows-x86_64.exe`
```
chmod +x docksurf-linux-x86_64 # or the macOS binary you downloaded
sudo mv docksurf-linux-x86_64 /usr/local/bin/docksurf
docksurf
```
在 Windows 上,直接运行 `.exe` 文件即可 — 无需 `chmod`/`mv` 步骤。
**从源码安装**(用于开发,或运行尚未发布的更改):
```
git clone
cd docksurf
uv venv && source .venv/bin/activate
uv pip install -e .
docksurf
```
或者免安装运行:
```
uv run python -m docksurf_py.app
```
## 发布版本
通过由标签触发的 GitHub Actions 工作流 (`.github/workflows/publish.yml`) 发布到 PyPI:推送 `vX.Y.Z` 标签会构建包,并使用 [PyPI Trusted Publishing](https://docs.pypi.org/trusted-publishers/)(OIDC — 无需存储凭证)进行发布,该过程受手动批准步骤控制。有关每个版本的内容,请参阅 [CHANGELOG.md](https://github.com/praneeth-etta/docksurf/blob/main/CHANGELOG.md)。
## 按键绑定
基础操作 — 完整参考(各标签页按键、日志面板、Compose 标题行为)请参见 [KEYBINDINGS.md](https://github.com/praneeth-etta/docksurf/blob/main/KEYBINDINGS.md)。
| 按键 | 操作 |
|--------------|----------------------------------------------------------|
| `?` | 帮助界面 — 应用内展示所有按键绑定 |
| `r` | 刷新所有 Docker 数据 |
| `/` | 搜索 / 过滤当前标签页 |
| `↑/↓`, `Tab` | 导航行 / 切换标签页 |
| `1`-`4` | 直接跳转至 Containers / Images / Volumes / Networks |
| `s`/`S`/`x` | 停止 / 启动 / 重启 (Containers 标签页) |
| `e` | 在聚焦的 container 中执行 exec shell |
| `l` | 切换日志查看器 |
| `space` | 标记以进行批量操作 |
| `d` | 删除选中 — 或已标记的 — 资源 |
| `i` | 检查 (原始 `docker inspect` JSON) |
| `P` | 清理菜单 |
| `D` | 切换 Docker context |
| `q` | 退出 |
## 标签页
每个标签页都有一个前置的标记列(使用 `space` 切换),用于多选和批量操作 — 详见[按键绑定](#keybindings)。
**Containers** — 包含所有 container(运行中和已停止的),**按 Compose 项目分组**为可折叠的树状结构,下方显示独立的 container。列:名称(带有颜色编码的状态点)和 image。详情面板增加了状态、健康状况、运行时间、重启次数、端口、网络、环境变量、健康探针历史记录、实时 CPU/内存/网络/块 I/O 统计信息,以及按需获取的 `docker top` 快照 (`t`)。对于 Compose 服务,`B` 会仅重新构建并重新创建该 container,并进行实时流式传输。
**Images** — 包含所有 image,标记为 *In Use*(使用中)、*Unused*(未使用)或 *Dangling*(悬空)。详情面板显示大小、创建日期、架构以及引用该 image 的 container。支持带有实时进度地拉取新 image (`+`)、查看每层历史记录 (`h`)、重新打标签 (`y`),以及一键标记所有悬空 image 以进行批量清理 (`a`)。
**Volumes** — 包含所有 volume,标记为 *In Use*(使用中)或 *Orphaned*(孤立)。详情面板显示挂载点、驱动程序、标签以及已挂载的 container。支持创建 volume (`+`) 并按需获取该 volume 在磁盘上的占用大小 (`b`)。
**Networks** — 包含所有 network 及其驱动程序和作用域。详情面板显示驱动程序、作用域、子网、网关,以及网络内每个已连接 container 的 IP/MAC 地址。支持创建 network (`+`) 以及连接/断开 container (`v`/`m`)。
## 架构
严格的分层结构:`models.py` 和 `constants.py` 是叶节点模块,没有任何内容导入它们。所有 Docker I/O 都位于 `docker/` 中(通过[适用于 Python 的 Docker SDK](https://docker-py.readthedocs.io/)),隐藏在 `DockerService` 协议之后,因此在测试中可以替换。`widgets/` 仅负责展示,不包含任何 Docker 知识。`renderer/`、`actions/`、`search.py` 和 `observability.py` 组成了应用程序本身 — 表格渲染、资源操作、搜索以及实时统计/`docker top` — 由每个标签页统一的资源注册表驱动,而不是在整个过程中根据资源类型进行分支判断。
## 数据获取方式
DockSurf 通过 SDK (`docker-py`) 而不是 CLI 与 Docker 通信 — 有三个特许例外,并且都受到必须存在 `docker` CLI 的限制:交互式 **exec-shell**(需要真实的 TTY)、**Compose 项目操作**(docker-py 不支持 Compose)和**文件复制**(在 SDK 的原始 tar 归档上重现 `docker cp` 语义并不值得)。
每次刷新时都会并行获取资源列表,并通过 `docker events` 保持实时状态(经过防抖处理,保留当前选择);统计信息和日志直接从 SDK 流式传输,其中 Compose 项目的日志会被合并并按服务进行着色。
## Docker context — 本地和远程
DockSurf 会连接到你激活的 Docker context 所指向的任何 daemon(与 `docker` CLI 的优先级匹配:`DOCKER_HOST` → 激活的 context → 默认 socket)。这并不一定非要是你的本地机器,而且 — 既然现在可以在应用内切换 context — 它也不需要重启 DockSurf。
**创建 context** 仍然是一个 `docker` CLI 步骤(DockSurf 只负责列出和切换 context,并不创建它们):
```
# 一个通过 SSH 指向远程 Linux host 的 context — 任何具有
# 可访问的 Docker daemon 和 SSH 访问权限的 host 都可以:cloud VM、bare-metal
# box、Raspberry Pi、home server。
docker context create prod --docker "host=ssh://user@prod.example.com"
# 或者通过普通 TCP,如果 daemon 的 API 是以这种方式暴露的
docker context create staging --docker "host=tcp://staging.example.com:2375"
```
**从 DockSurf 内部切换 context** — 按 `D` 列出 `docker context ls` 所知的所有 context 并选择一个。这仅在应用内生效:它从不运行 `docker context use`,因此不会修改 `~/.docker/config.json`,也不会重新指向任何其他终端的 `docker`/`docker compose` — DockSurf 只是为所选 context 的 daemon 开启自己的连接。此选择会在重启后保留 (`~/.local/share/docksurf/state.json`)。
**自动重连** — 如果你激活的 context 指向的 daemon 在会话期间宕机(虚拟机重启、daemon 重启、网络闪断),状态栏会立即标记它 (`● `),并且 DockSurf 每隔几秒会自动重试,一旦恢复就会立即重新连接并刷新 — 无需重启,也无需手动 `r`。
支持任何兼容 **Docker Engine API** 的端点 — 普通的 Linux daemon、Docker Desktop、Colima、Rancher Desktop,或通过 SSH/TCP 连接的远程主机。如果没有该 API,即使是使用自定义 context,也无法通过这种方式访问受管的云平台。
## 日志
应用程序日志会写入 `~/.local/share/docksurf/docksurf.log` — 绝不会输出到 stdout(因为 stdout 属于 TUI)。这对于调试刷新错误、失败的 Docker API 调用、container/Compose 操作结果以及流生命周期事件非常有用。
## 更新日志
有关发布历史,请参阅 [CHANGELOG.md](https://github.com/praneeth-etta/docksurf/blob/main/CHANGELOG.md)。
标签:Docker, Docker Compose, TUI, 安全防御评估, 容器管理, 版权保护, 终端UI, 请求拦截, 运维工具, 逆向工具