# 好用斋 Docker 懒人包 —— 多应用合成一个 compose 的规则

> 面向 AI：当用户想“安装好几个程序并合并成一份 `docker-compose.yml`”（与 /lazybag 交互生成一致）时，按本规则操作。用户仍需在自己设备上执行 `docker compose up -d`，AI 只负责产出完整 compose 内容。

## 一、合并结构

以 `services:` 为根，把每个选中应用各自的 yaml 块（以 `  <service-name>:` 开头）依次拼进去。每个应用的 yaml 块已含 image/container_name/restart/ports 等，不要重复写 `services:` 或 `version:`。

## 二、占位符替换

按所选系统替换每个应用 yaml 里的占位符（各系统默认值见本卡引用或 `lazybag-data.json` 的 systems）：
- `{{BASE_PATH}}` → 该系统 BASE_PATH
- `{{TOOLS_PATH}}` → 该系统 TOOLS_PATH
- `{{WEBOS_RSLAVE_MOUNT}}` → rslave 挂载

## 三、restart 规则

飞牛(feiniu)/群晖(dsm) 用 `always`，其余用 `unless-stopped`。若某应用 yaml 中 restart 与该系统规则不符，改为系统规则。

## 四、网络模式与端口

- host 模式：保留 `network_mode: host`，不加 `ports:` 映射；记下它占用的容器端口（见默认端口表）。
- bridge：按用户配置/默认端口写入 `ports:`，格式 `- "HOST:CONTAINER"`。
- WSL 系统下 host 端口使用 WSL 端口表（比 x86 不同，如 music-tag 用 28008）。

## 五、端口冲突检测

合并时若两个应用占用同一 host 端口，或 host 模式应用之间共用容器端口，属冲突——需提示用户手动改某个应用的 host 端口（两个进程不能监听同一端口）。冲突不会被 AI 自动分配，只能提示并建议新端口（可参考下表中未被占用的 host 端口）。

## 六、默认端口表（host:container）

### x86_64 / ARM64

| 应用 id | 端口(host:container) |
| --- | --- |
| `abs-ximalaya` | `7814:7814` |
| `alist-strm` | `18080:5000` |
| `aria2-pro` | `26800:26800` |
| `ariang` | `6880:6880` |
| `audiobookshelf` | `13378:80` |
| `auto_symlink` | `8095:8095` |
| `bili-sync-rs` | `12345:12345` |
| `calibre-web` | `8083:8083` |
| `cloud-saver` | `8010:8008` |
| `cloud189` | `3050:3000` |
| `clouddrive` | `19798:19798` |
| `dpanel` | `8807:8080` |
| `emby` | `8097:8096` |
| `fastnet` | `3200:3200` |
| `gopeed` | `9995:9999` |
| `hd-icons` | `50560:50560` |
| `jellyfin` | `8099:8096` |
| `kkfileview` | `8012:8012` |
| `komga` | `25600:25600` |
| `kspeeder` | `25443:5443`<br>`25003:5003` |
| `librespeed` | `8075:8080` |
| `litepan` | `5211:5211` |
| `mediawarp` | `9010:9000` |
| `music-tag` | `8008:8001` |
| `navidrome` | `4533:4533` |
| `ollama` | `11434:11434` |
| `open-webui` | `3030:8080` |
| `opencode` | `3005:3000` |
| `openlist` | `5544:5244` |
| `panhub` | `3020:3001` |
| `pansou` | `8086:80` |
| `plex` | `32400:32400` |
| `portainer` | `9000:9000` |
| `qbittorrent` | `8088:8088` |
| `quark-auto-save` | `5010:5005` |
| `siyuan` | `6806:6806` |
| `sonovel` | `7765:7765` |
| `sun-panel` | `3002:3002` |
| `syncthing` | `8384:8384` |
| `taosync` | `8023:8023` |
| `tgtodrive` | `12366:12366` |
| `transmission` | `9091:9091` |
| `wallabag` | `3010:80` |
| `webos` | `8089:8088` |
| `xiaomusic` | `8090:8090` |
| `xiaoya-tvbox` | `4567:4567`<br>`5344:80` |
| `xunlei` | `2345:2345` |

### WSL (Windows)

| 应用 id | 端口(host:container) |
| --- | --- |
| `abs-ximalaya` | `27814:7814` |
| `auto_symlink` | `28095:8095` |
| `bili-sync-rs` | `22345:12345` |
| `calibre-web` | `28083:8083` |
| `cloud-saver` | `28010:8008` |
| `cloud189` | `23050:3000` |
| `clouddrive` | `29798:19798` |
| `dpanel` | `28807:8080` |
| `emby` | `28097:8096` |
| `gopeed` | `29995:9999` |
| `jellyfin` | `28099:8096` |
| `kkfileview` | `28012:8012` |
| `librespeed` | `28075:8080` |
| `litepan` | `25211:5211` |
| `mediawarp` | `29010:9000` |
| `music-tag` | `28008:8001` |
| `navidrome` | `24533:4533` |
| `ollama` | `21434:11434` |
| `open-webui` | `23030:8080` |
| `opencode` | `23005:3000` |
| `openlist` | `25544:5244` |
| `panhub` | `23020:3001` |
| `pansou` | `28086:80` |
| `portainer` | `29000:9000` |
| `quark-auto-save` | `25010:5005` |
| `siyuan` | `26806:6806` |
| `sonovel` | `27765:7765` |
| `sun-panel` | `23002:3002` |
| `syncthing` | `28384:8384`<br>`22022:22000`<br>`21021:21027` |
| `taosync` | `28023:8023` |
| `tgtodrive` | `22366:12366` |
| `wallabag` | `23010:80` |
| `webos` | `28089:8088` |
| `xiaomusic` | `28090:8090` |
| `xiaoya-tvbox` | `24567:4567`<br>`25344:80` |

## 七、AI 拼装步骤

1. 确认系统与架构（arm64 时注意 ARM 支持）。
2. 对每个选中应用，取 yaml 块：arm64 且存在 armYaml 用 armYaml，标注 unsupported 则跳过，否则用 x86 yaml。
3. 替换占位符、设置 restart、处理网络模式与端口。
4. 检测端口冲突，若有则提示用户改 host 端口。
5. 将各 yaml 块统一放入 `services:` 根，输出一份完整 compose，供用户 `docker compose up -d`。

