内容
# 流浪者
[](https://github.com/featurecreep-cron/roustabout/actions/workflows/ci.yml)
[](https://codecov.io/gh/featurecreep-cron/roustabout)
[](https://scorecard.dev/viewer/?uri=github.com/featurecreep-cron/roustabout)
[](https://github.com/featurecreep-cron/roustabout/blob/develop/LICENSE)
[](https://www.python.org/downloads/)
[](https://pypi.org/project/roustabout/)
[](https://github.com/featurecreep-cron/roustabout/pkgs/container/roustabout)
[](https://github.com/astral-sh/ruff)
用于Docker环境的文档、安全性审计和编排生成。
Roustabout 连接到Docker API,检查正在运行的容器,并生成:
- **Markdown快照** — 完整的镜像、端口、卷、网络、环境变量、标签清单
- **安全性审计** — 18项检查,涵盖套接字暴露、环境变量中的秘密、敏感端口、缺少健康检查、根容器等
- **编排生成** — 从正在运行的容器重建`docker-compose.yml`
- **快照差异** — 比较两个JSON快照,查看更改内容
所有输出都经过秘密编辑器的处理。匹配可配置模式的环境变量在显示之前会被替换为 `[REDACTED]`。
## 安装
```bash
pip install roustabout
# 使用MCP服务器支持
pip install "roustabout[mcp]"
```
### Docker
```bash
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-e ROUSTABOUT_API_KEY=changeme \
-p 8077:8077 \
ghcr.io/featurecreep-cron/roustabout:latest
```
然后远程使用CLI:`roustabout --url http://server:8077 --api-key changeme snapshot`
## 快速开始
```bash
roustabout snapshot # 记录您的Docker环境
roustabout audit # 运行安全检查
roustabout generate # 重建编排文件
roustabout diff old.json new.json # 比较快照
```
### 远程模式
连接到正在运行的roustabout服务器,而不是本地Docker套接字:
```bash
# 保存连接(提示输入API密钥)
roustabout connect http://server:8077
# 所有命令现在都使用保存的服务器
roustabout snapshot
roustabout audit
# 或显式传递凭证
roustabout --url http://server:8077 --api-key mykey snapshot
# 删除保存的连接
roustabout disconnect
```
连接详细信息保存到 `~/.config/roustabout/config.toml`。
<details>
<summary><strong>完整的CLI参考</strong></summary>
```bash
# 快照选项
roustabout snapshot --show-env --output snapshot.md
roustabout snapshot --format json --output snapshot.json
roustabout snapshot --project mystack
# 审计选项
roustabout audit --output audit.md --hide-accepted
roustabout audit --format json
roustabout audit --project mystack
# 生成选项
roustabout generate --redact --output docker-compose.yml
# 查找管理
roustabout accept docker-socket-watchtower "Watchtower需要套接字访问"
roustabout false-positive secrets-env-nginx "NGINX_HOST不是秘密"
roustabout resolve stale-image-redis "更新到redis:7.2"
```
</details>
<details>
<summary><strong>示例审计输出</strong></summary>
来自运行48个容器的homelab:
```
$ roustabout audit
# 安全审计
**212个发现:** **5个严重**,**40个警告**,**167个信息**
| 严重程度 | 检查 | 计数 | 容器 |
|----------|-------|-------|------------|
| 严重 | 特权模式 | 1 | cadvisor |
| 严重 | Docker套接字 | 4 | cronbox, homeassistant, portainer, watchtower |
| 警告 | 环境变量中的秘密 | 38 | authentik_server, grafana, mariadb, +14 more |
| 警告 | 主PID命名空间 | 1 | node_exporter |
| 信息 | 没有健康检查 | 35 | adguard, bazarr, freshrss, +30 more |
| 信息 | 以根用户运行 | 29 | adguard, cadvisor, plex, +24 more |
```
发现结果按类别分组 — 每个解释只出现一次,而不是每个容器。
</details>
<details>
<summary><strong>MCP服务器</strong></summary>
五个只读工具,均自动编辑:
| 工具 | 描述 |
|------|-------------|
| `docker_snapshot` | 完整的Markdown库存 |
| `docker_audit` | 安全发现 |
| `docker_container` | 单个容器详细信息 |
| `docker_networks` | 网络拓扑 |
| `docker_generate` | 编排文件生成 |
```bash
roustabout-mcp # 独立运行
```
克劳德代码配置:
```json
{
"mcpServers": {
"roustabout": {
"command": "roustabout-mcp"
}
}
}
```
</details>
<details>
<summary><strong>配置</strong></summary>
在工作目录中创建 `roustabout.toml`:
```toml
show_env = false
show_labels = true
output = "docker-snapshot.md"
docker_host = "tcp://myhost:2375"
redact_patterns = ["my_custom_secret", "internal_token"]
[severity_overrides]
"docker-socket" = "info"
"secrets-env" = "critical"
```
默认编辑模式:`password`,`passwd`,`passphrase`,`secret`,`token`,`api_key`,`apikey`,`credential`,`private_key`,`access_key`,`secret_key`。嵌入凭证的URL会进行部分编辑。已知秘密格式(AWS密钥、GitHub PAT、JWT、Stripe密钥)通过值形状检测,而不限于键名。
</details>
<details>
<summary><strong>安全检查</strong></summary>
| 检查 | 默认严重程度 | 检查内容 |
|-------|-----------------|---------------|
| 特权模式 | 严重 | 使用 `--privileged` 运行的容器 |
| Docker套接字挂载 | 严重 | 包含 `/var/run/docker.sock` 的容器 |
| 环境变量中的秘密 | 警告 | 匹配秘密模式的 env 变量键 + 值格式检测 |
| 危险能力 | 警告 | `SYS_ADMIN`,`NET_ADMIN`,`SYS_PTRACE` 和其他高风险能力 |
| 主PID命名空间 | 警告 | 共享主PID命名空间的容器 |
| 暴露的敏感端口 | 警告 | 0.0.0.0上的数据库、管理和管理端口 |
| 重启循环 | 警告 | 重启次数 > 25 的容器 |
| OOM杀死 | 警告 | 被OOM杀手杀死的容器 |
| 缺少健康检查 | 信息 | 没有健康监控的容器 |
| 以根用户运行 | 信息 | 没有 `user` 指令的容器 |
| 主网络模式 | 信息 | 使用 `network_mode: host` 的容器 |
| 敏感的主机挂载 | 信息 | 从主机挂载 `/etc`、`/root` 或 `/home` |
| 没有日志轮换 | 信息 | json-file/local 日志驱动程序上没有 `max-size` 的容器 |
| 没有资源限制 | 信息 | 没有内存限制的容器 |
| 缺少重启策略 | 信息 | 没有重启策略的容器 |
| 过时的镜像 | 信息 | 未标记或 `:latest` 镜像,没有固定的摘要 |
| 镜像年龄 | 信息 | 容器镜像年龄超过 90 天 |
| 守护进程实时恢复 | 信息 | Docker 守护进程未启用实时恢复 |
| 守护进程日志轮换 | 警告 | Docker 守护进程使用 json-file/local 且没有默认日志轮换 |
发现结果可以使用 `roustabout accept`、`false-positive` 或 `resolve` 进行分类。状态存储在 `roustabout.state.toml` 中。
</details>
## 要求
- Python 3.12+
- 访问Docker套接字(本地或远程)
## 升级
```bash
# CLI
pip install --upgrade roustabout
# 服务器(如果运行Docker镜像)
docker pull ghcr.io/featurecreep-cron/roustabout:latest
docker compose up -d # 或重启容器
```
CLI和服务器应为同一版本。如果服务器已过时,CLI会发出警告。
## 贡献
欢迎提交错误报告和拉取请求。参见 [CONTRIBUTING.md](CONTRIBUTING.md)。
## 支持
如果您觉得roustabout有用,请考虑 [给我们买一杯咖啡](https://buymeacoffee.com/featurecreep)。
## 许可证
MIT