# WorkPod 开发环境容器搭建手册 > 版本:1.1 | 更新日期:2026-04-07 > 用途:运维 AI 按此文档执行,为任意项目快速搭建完整的 Docker 开发环境 --- ## 0. 设计原则 | 原则 | 说明 | |------|------| | **挂载优先** | 代理工具/知识库/配置全部从宿主机挂载,不写入镜像 | | **信息隔离** | 每个容器只挂载该项目相关的配置和文档,禁止无关账号/服务器信息 | | **可复用** | 一套模板适用于 flux/suke/lab/case 等任何项目 | | **声明式** | 配置即环境,改 YAML 即换环境 | | **持久化** | home 目录独立挂载,重建容器不丢配置 | ### 架构总览 ``` ┌─ 宿主机 (Windows) ─────────────────────────────────────────────┐ │ │ │ E:/wk-oth/rust-work/dist-Linux/ │ │ ├── mysql-proxy ───┐ │ │ ├── ssh-proxy ───┤ │ │ ├── redis-proxy ───┼──→ [挂载 ro] → 容器 /usr/local/bin/ │ │ └── mongo-proxy ───┘ │ │ │ │ C:/Users/{user}/.ssh/id_ed25519 ──→ [挂载 ro] → /root/.ssh/ │ │ │ │ E:/wk-flux/ ─────────→ [挂载] → 容器 /workspace │ │ │ │ workpod/dev-envs/{project}/ │ │ ├── servers.yaml ──→ [挂载 ro] → /root/.dev-env/servers.yaml │ │ ├── databases.yaml ──→ [挂载 ro] → /root/.dev-env/databases.yaml │ │ ├── norms.md ──→ [挂载 ro] → /root/.dev-env/norms.md │ │ ├── ssh-proxy.toml ──→ [挂载 ro] → /root/.dev-env/ssh-proxy.toml │ │ ├── mysql-proxy.toml ──→ [挂载 ro] → /root/.dev-env/mysql-proxy.toml│ │ ├── redis-proxy.toml ──→ [挂载 ro] → /root/.dev-env/redis-proxy.toml│ │ ├── docs/ ──→ [挂载 ro] → /root/.dev-env/docs/ │ │ └── claude/ ──→ [挂载 ro] → /root/.dev-env/claude/ │ │ ├── CLAUDE.md │ │ └── settings.local.json │ │ │ │ workpod/data/home/{project}-dev/ ──→ [挂载 rw] → /root │ │ ├── .gitconfig │ │ ├── .bashrc ← claude wrapper + 代理自动启动 │ │ ├── .claude/ ← Claude Code 运行时数据 │ │ └── ... │ │ │ │ instances/{project}/.env ──→ ANTHROPIC_AUTH_TOKEN=xxx │ │ │ └────────────────────────────────────────────────────────────────┘ ``` --- ## 1. 快速搭建(以 Flux 项目为例) ### 1.1 创建项目环境目录 ```bash # 在 workpod 下创建项目级配置目录 mkdir -p E:/wk-lab/workpod/dev-envs/flux/claude mkdir -p E:/wk-lab/workpod/data/home/flux-dev # 复制代理工具(或符号链接) cp E:/wk-oth/rust-work/dist-Linux/* E:/wk-lab/workpod/dev-envs/flux/bin/ # 或(推荐,自动同步最新版): # ln -s E:/wk-oth/rust-work/dist-Linux E:/wk-lab/workpod/dev-envs/flux/bin ``` ### 1.2 编写项目配置文件 以下 4 个文件是每个项目的**必需配置**,按实际修改即可: #### `dev-envs/flux/servers.yaml` — 服务器信息 ```yaml # Flux 项目服务器清单 (仅含 Flux 相关,信息隔离) project: flux description: 贷款撮合平台 last_updated: "2026-04-07" servers: # === 生产环境 === - name: prod_baiyarong display: 百雅融生产服 host: 101.201.107.111 port: 22 user: root deploy_dir: /opt/ jdk_path: /opt/app/ services: - name: flux-api dir: /opt/flux-api restart: "cd /opt/flux-api && bash bin/restart.sh" health_check: "curl -sf http://localhost:6080/partnerapi/ping" - name: flux-admin dir: /opt/flux-admin - name: flux-mock dir: /opt/flux-mock - name: file-server dir: /opt/file-server port: 8071 domains: - api.baiyarong.cn - r.baiyarong.cn # === 测试环境 (flux_dev) === - name: dev_test display: 测试机 (flux_dev) host: 39.99.243.191 port: 22 user: root deploy_dir: /opt/ docker: true jdk_path: /opt/jdk-25 services: - name: mysql port: 3306 image: mysql:8.0 - name: redis port: 6379 image: redis:7.4 password: - name: workpod-1 web_port: 7681 domain: wk.1216.top - name: workpod-alpine web_port: 7683 domain: wk2.1216.top domains: - fluxapi.1216.top - flux.1216.top - wk.1216.top ``` > **注意**: ssh-proxy.toml 中的 server name 用短名(如 `byr_pro`),与 servers.yaml 的显示名不同。 > 这是正常的:ssh-proxy.toml 的 `name` 是内部连接标识符,servers.yaml 的 `name` 是人工可读名称。 #### `dev-envs/flux/databases.yaml` — 数据库连接 ```yaml # Flux 项目数据库连接 (仅含 Flux 相关) project: flux last_updated: "2026-04-07" mysql: # --- 测试环境 --- - name: flux_dev env: test host: 39.99.243.191 port: 3306 database: flux_dev users: - username: root password: role: admin - username: u_flux password: role: app proxy_name: flux_dev # mysql-proxy 连接名 # --- 生产环境 --- - name: flux_prox env: prod host: 101.201.107.111 port: 3306 database: flux_prox users: - username: root password: role: admin proxy_name: flux_prox - name: flux_mp env: prod host: 101.201.107.111 port: 3306 database: flux_mp users: - username: u_mp password: role: app note: 小程序数据库 redis: - name: flux_dev env: test host: 39.99.243.191 port: 6379 password: proxy_name: flux_dev # redis-proxy 连接名 feishu_bot: workspace: flux app_id: app_secret: open_platform: https://open.feishu.cn/app/ # === 代理工具速查 === # mysql-proxy cli -c flux_dev -e "SQL" # 查询 # mysql-proxy cli -c flux_dev -e "SQL" -F json # JSON输出 # mysql-proxy cli -c flux_dev -e "DML" -x # 执行写入 # ssh-proxy exec -n flux_dev -c "command" # 远程执行 # ssh-proxy exec -n flux_dev -c "command" -F json # JSON输出 # redis-proxy get -c flux_dev -k "key" # 取值 # redis-proxy run -c flux_dev -C "KEYS" -a "user:*" # 通用命令 ``` #### `dev-envs/flux/norms.md` — 开发规范摘要 ```markdown # Flux 项目开发规范 ## Git 提交规范 格式:`<类型>: <简述>` 类型:新增 | 修复 | 优化 | 重构 禁止: - 英文提交信息 - Co-Authored-By 尾巴 - 提及工具名称 ## 技术栈 | 模块 | 技术 | 启动命令 | |------|------|---------| | flux-api | Java 17 + Redkale + Maven | cmd /c bin\restart.bat | | flux-admin | Vue 3 + Arco Design + Vite + bun | bun run dev | | flux-uniapp | UniApp + Vite | bun run dev:h5 | | flux-mock | Go | go run *.go | | flux-test | Go | go run test_quick.go {channel} | | file-server | Go | go run *.go | ## 代码审查要点 - Redkale FilterNode 使用规范(见 .kms/Redkale使用易错点.md) - JSON 字段映射 @ConvertColumn 注意事项 - SQL 慢查询优化(见 .kms/MySQL慢查询分析.md) ## 命名规范 前缀: flux-{type}-{name} 类型后缀: -api(后端) | -admin(管理后台) | -web(用户端) | -app(移动端) ## 高危操作提醒 - 改 Docker/系统配置: 先备份,改完验证语法,再重启 - 删数据库/容器: 先确认备份和影响范围 - 生产操作: 必须先在测试环境验证 ``` #### `dev-envs/flux/claude/CLAUDE.md` — Claude Code 项目指令 ```markdown # Flux 开发环境 > 当前在 ws-flux-dev 容器内,工作目录 /workspace = E:/wk-flux ## 项目概述 贷款撮合平台,核心模块: - **flux-api**: 后端 API (Java 17 + Redkale) - **flux-admin**: 管理后台 (Vue 3 + Arco Design) - **flux-uniapp**: H5 前端 (UniApp) - **flux-mock**: 三方模拟服务 (Go) - **flux-test**: 业务链测试 (Go) - **file-server**: 文件服务 (Go) ## 可用工具 ### 代理工具(已挂载到 /usr/local/bin/) ```bash mysql-proxy cli -c flux_dev -e "SQL" # MySQL 查询 ssh-proxy exec -n flux_dev -c "command" # SSH 远程执行 redis-proxy get -c flux_dev -k "key" # Redis 操作 mongo-proxy find -c suke_dev -C collection # MongoDB 查询 fet GET https://api.example.com # HTTP 请求 ``` ### 连接信息速查 详见 `/root/.dev-env/servers.yaml` 和 `/root/.dev-env/databases.yaml` ## 开发命令 ```bash # flux-api (Redkale/Java) cd /workspace/flux-api && mvn clean package cmd /c bin\restart.bat # flux-admin (Vue3/bun) cd /workspace/flux-admin && bun install && bun run dev # flux-uniapp (UniApp) cd /workspace/flux-uniapp && npm install && npm run dev:h5 # Go 服务 cd /workspace/flux-mock && go run *.go cd /workspace/flux-test && go run test_quick.go qulaijie ``` ## 规范 - Git 提交: `<类型>: <简述>` 类型=新增|修复|优化|重构 - 禁止英文提交、禁止 Co-Authored-By 尾巴 - 详见 `/root/.dev-env/norms.md` ## 开发规范 > **唯一事实来源**: `/root/.dev-env/norms.md` > 本文件不重复规范内容,避免维护不一致。 执行任务前先读取 norms.md,关键规则: - Git 提交、代码审查、命名规范、高危操作检查清单 ## 项目知识库 Flux 专属文档位于 `/root/.dev-env/docs/`: | 文件 | 用途 | |------|------| | Redkale使用易错点.md | **flux-api 必读** — 框架踩坑记录 | | MySQL慢查询分析.md | SQL 慢查询优化参考 | ``` #### `dev-envs/flux/claude/settings.local.json` — Claude Code 权限 ```json { "permissions": { "allow": [ "Bash(mysql-proxy *)", "Bash(ssh-proxy *)", "Bash(redis-proxy *)", "Bash(mongo-proxy *)", "Bash(mvn *)", "Bash(java *)", "Bash(javac *)", "Bash(go *)", "Bash(bun *)", "Bash(npm *)", "Bash(node *)", "Bash(cmd *)", "Bash(git *)", "Bash(docker *)", "Bash(curl *)", "Bash(wget *)", "Bash(cat *)", "Bash(ls *)", "Bash(grep *)", "Bash(find *)", "Read", "Write", "Edit" ], "deny": [] } } ``` > **注意**: `fet` 暂未挂载(Linux 版未编译),故不在权限列表中。编译后需添加 `Bash(fet *)`。 ### 1.3 配置持久化 Home 目录 `data/home/flux-dev/.gitconfig`: ```ini [user] name = 绝尘 email = dev@1216.top [core] autocrlf = input quotepath = false [push] default = simple ``` ### 1.4 生成 Compose 文件 从模板生成 `instances/flux/docker-compose.yml`: ```yaml services: ws-flux-dev: build: context: ../../ dockerfile: instances/flux/Dockerfile image: ws-flux-dev:latest container_name: ws-flux-dev hostname: ws-flux-dev restart: unless-stopped ports: - "2201:22" # SSH - "7701:7681" # Web 终端 ttyd volumes: # ===== 项目源码 ===== - E:/wk-flux:/workspace # ===== 开发工具 (JDK/Maven) ===== - D:/Java/jdk-musl-17:/opt/jdk-musl-17:ro - D:/Java/maven-mvnd-3.9.14:/opt/maven-mvnd-3.9.14:ro # ===== 代理工具 (Linux static binaries) ===== - E:/wk-oth/rust-work/dist-Linux/mysql-proxy:/usr/local/bin/mysql-proxy:ro - E:/wk-oth/rust-work/dist-Linux/ssh-proxy:/usr/local/bin/ssh-proxy:ro - E:/wk-oth/rust-work/dist-Linux/redis-proxy:/usr/local/bin/redis-proxy:ro - E:/wk-oth/rust-work/dist-Linux/mongo-proxy:/usr/local/bin/mongo-proxy:ro # ===== SSH 密钥 + 代理配置 (仅该项目相关) ===== - C:/Users/{user}/.ssh/id_ed25519:/root/.ssh/id_ed25519:ro - ../../dev-envs/flux/ssh-proxy.toml:/root/.dev-env/ssh-proxy.toml:ro - ../../dev-envs/flux/mysql-proxy.toml:/root/.dev-env/mysql-proxy.toml:ro - ../../dev-envs/flux/redis-proxy.toml:/root/.dev-env/redis-proxy.toml:ro # ===== 项目级配置 (只读挂载) ===== - ../../dev-envs/flux/servers.yaml:/root/.dev-env/servers.yaml:ro - ../../dev-envs/flux/databases.yaml:/root/.dev-env/databases.yaml:ro - ../../dev-envs/flux/norms.md:/root/.dev-env/norms.md:ro - ../../dev-envs/flux/docs:/root/.dev-env/docs:ro - ../../dev-envs/flux/claude/CLAUDE.md:/root/.dev-env/claude/CLAUDE.md:ro - ../../dev-envs/flux/claude/settings.local.json:/root/.dev-env/claude/settings.local.json:ro # ===== 持久化 Home (读写挂载) ===== - ../../data/home/flux-dev:/root environment: - TZ=Asia/Shanghai - TERM=xterm-256color - ROOT_PASSWORD=${ROOT_PASSWORD:-workpod123} - TTYD_CREDENTIALS=${TTYD_CREDENTIALS:-jc:1234567} - WORKPOD_PROJECT=flux - JAVA_HOME=/opt/jdk-musl-17 - MAVEN_HOME=/opt/maven-mvnd-3.9.14 # === Claude Code (智谱 AI, 从 .env 读取密钥) === - ANTHROPIC_BASE_URL=https://open.bigmodel.cn/api/anthropic - ANTHROPIC_API_KEY=${ANTHROPIC_AUTH_TOKEN} - ANTHROPIC_DEFAULT_SONNET_MODEL=glm-5v-turbo - ANTHROPIC_DEFAULT_OPUS_MODEL=glm-5.1 - ANTHROPIC_DEFAULT_HAIKU_MODEL=glm-4.5-air deploy: resources: limits: memory: 4G reservations: memory: 1G logging: driver: json-file options: max-size: "10m" max-file: "3" healthcheck: test: ["CMD-SHELL", "netstat -tlnp 2>/dev/null | grep -qE ':(22|7681)\\b' || exit 1"] interval: 30s timeout: 5s start_period: 15s retries: 3 working_dir: /workspace tty: true stdin_open: true networks: default: external: true name: workpod-{project}-network ``` > **`.env` 文件**: 在 `instances/{project}/` 下创建 `.env`,存放敏感信息(不进 git): > ```bash > # Claude Code API Key (智谱 AI) > ANTHROPIC_AUTH_TOKEN=your_token_here > ``` ### 1.5 启动与验证 ```bash # 构建并启动 cd E:/wk-lab/workpod docker build -t ws-flux-dev:latest -f instances/flux/Dockerfile . docker compose -f instances/flux/docker-compose.yml up -d # 验证 1: 代理工具 MSYS_NO_PATHCONV=1 docker exec ws-flux-dev bash -lc ' echo "=== 代理工具 ===" mysql-proxy --version && echo " ✓ mysql-proxy" ssh-proxy --version && echo " ✓ ssh-proxy" redis-proxy --version && echo " ✓ redis-proxy" mongo-proxy --version && echo " ✓ mongo-proxy" echo "" echo "=== 项目知识库 (仅该项目相关) ===" ls /root/.dev-env/docs/ echo "" echo "=== 项目配置 ===" cat /root/.dev-env/servers.yaml | head -5 cat /root/.dev-env/databases.yaml | head -5 echo "" echo "=== Git 配置 ===" git config --global --list ' # 验证 2: Web 终端访问 # 打开 http://localhost:7701 用户 jc / 1234567 # 验证 3: SSH 访问 ssh root@localhost -p 2201 # 密码 workpod123 ``` --- ## 2. 为新项目快速搭建(模板流程) 当需要为新项目(如 suke、lab、case)搭建开发环境时,只需 **3 步**: ### Step 1: 复制模板目录 ```bash # 以 suke 项目为例 PROJECT=suke SSH_PORT=2202 WEB_PORT=7702 PROJECT_PATH=E:/wk-suke mkdir -p E:/wk-lab/workpod/dev-envs/$PROJECT/claude mkdir -p E:/wk-lab/workpod/data/home/$PROJECT-dev ``` ### Step 2: 编写 4 个配置文件 复制 flux 的配置文件作为模板,修改以下内容: | 文件 | 需修改项 | |------|---------| | `servers.yaml` | 该项目的服务器列表、部署路径、域名 | | `databases.yaml` | 该项目的数据库连接、Redis、第三方密钥 | | `norms.md` | 该项目的技术栈、启动命令、特殊规范 | | `claude/CLAUDE.md` | 项目描述、模块说明、可用命令 | ### Step 3: 生成并启动 compose 从上面的 compose 模板复制,修改: - `container_name` / `hostname` - `ports` (SSH/Web) - `volumes` 中的项目路径和 dev-envs 路径 - `environment` 中的项目特定变量 - `networks.name` ```bash # 一键启动 docker compose -f instances/$PROJECT/docker-compose.yml up -d ``` --- ## 3. 挂载资源清单 ### 3.1 代理工具(只读挂载) | 工具 | 宿主机源 | 大小 | 容器路径 | 用途 | |------|---------|------|---------|------| | mysql-proxy | `dist-Linux/mysql-proxy` | 8.9MB | `/usr/local/bin/mysql-proxy` | MySQL 查询代理 (:3307) | | ssh-proxy | `dist-Linux/ssh-proxy` | 4.6MB | `/usr/local/bin/ssh-proxy` | SSH 命令代理 (:3308) | | redis-proxy | `dist-Linux/redis-proxy` | 3.4MB | `/usr/local/bin/redis-proxy` | Redis 命令代理 (:3310) | | mongo-proxy | `dist-Linux/mongo-proxy` | 6.4MB | `/usr/local/bin/mongo-proxy` | MongoDB 代理 (:3309) | > 全部为 **static-pie** 链接,无动态依赖,兼容 Alpine musl。 ### 3.1b SSH 密钥 + 代理配置(只读挂载) | 资源 | 宿主机源 | 容器路径 | 用途 | |------|---------|---------|------| | SSH 私钥 | `C:/Users/{user}/.ssh/id_ed25519` | `/root/.ssh/id_ed25519` | ssh-proxy 认证远程服务器 | | ssh-proxy.toml | `dev-envs/{project}/ssh-proxy.toml` | `/root/.dev-env/ssh-proxy.toml` | SSH 代理服务配置 (仅该项目服务器) | | mysql-proxy.toml | `dev-envs/{project}/mysql-proxy.toml` | `/root/.dev-env/mysql-proxy.toml` | MySQL 代理配置 (仅该项目连接) | | redis-proxy.toml | `dev-envs/{project}/redis-proxy.toml` | `/root/.dev-env/redis-proxy.toml` | Redis 代理配置 (仅该项目连接) | > **信息隔离**: 每个 `.toml` 只包含当前项目的连接/服务器,禁止混入其他项目。 > **fet 待补充**: 目前仅有 Windows 版 (`PE32+`),需要交叉编译 Linux 版。编译命令: > ```bash > cd E:/wk-oth/rust-work/fet > rustup target add x86_64-unknown-linux-musl > cargo build --release --target x86_64-unknown-linux-musl > ``` ### 3.2 项目专属知识库(只读挂载) > **重要原则**: 只挂载与当前项目相关的文档,避免无关信息干扰和误操作。 宿主机: `workpod/dev-envs/{project}/docs/` → 容器: `/root/.dev-env/docs/` 从全局 KMS 中**按需筛选**该项目需要的文档复制到此目录: | 文件 | 来源 | 适用项目 | |------|------|---------| | Redkale使用易错点.md | ~/.claude/kms/ | flux (flux-api 用 Redkale) | | MySQL慢查询分析.md | ~/.claude/kms/ | 有 MySQL 的项目 | | 其他框架/业务文档 | ~/.claude/kms/ 或项目自身 | 按需 | **禁止挂载到容器的内容**: - `账号信息.md` — 包含所有项目密码,有泄露和误操作风险 - 其他项目的服务器/数据库信息 — 避免连接错误环境 ### 3.3 项目级配置(只读挂载) 宿主机: `workpod/dev-envs/{project}/` → 容器: `/root/.dev-env/` | 文件 | 用途 | |------|------| | servers.yaml | 该项目涉及的服务器 IP/端口/用途/域名 | | databases.yaml | MySQL/Redis 连接信息 + 第三方密钥 | | norms.md | 开发规范摘要 (Git/代码审查/命名/高危操作) | | claude/CLAUDE.md | Claude Code 项目指令 | | claude/settings.local.json | Claude Code 权限配置 | ### 3.4 持久化 Home(读写挂载) 宿主机: `workpod/data/home/{project}-dev/` → 容器: `/root` > **只存放运行时产生的文件**,不存放项目配置(配置在 `dev-envs/` 中) | 文件 | 来源 | 说明 | |------|------|------| | `.gitconfig` | 手动配置 | Git 用户名/邮箱/Gitea 凭据 | | `.git-credentials-gitea` | 手动配置 | Gitea 密码 (权限 600) | | **`.bashrc`** | **手动编写** | **★ claude wrapper + 代理自动启动 (见第 5 节)** | | `.claude/` | 自动产生 | Claude Code 运行时数据 (sessions/settings/history) | | `.bun/` | 容器内安装 | bun 运行时安装的包 | | `.npm/` | 容器内产生 | npm 缓存 | | `.chelper/` | 容器内产生 | coding-helper 数据 | | `.ash_history` | 自动产生 | 命令历史 | ### 3.4b 自定义技能(读写挂载) > **不同项目容器需要不同的技能内容**,按项目需求选择性同步。 宿主机: `~/.claude/skills/{name}/skill.md` → 容器: `/root/.claude/skills/{name}/skill.md` 技能文件放在 `data/home/{project}-dev/.claude/skills/` 下,随 `/root` 持久化挂载自动同步。 #### 技能清单 | 技能名 | 触发词 | 用途 | 适用项目 | |--------|--------|------|---------| | **commit** | commit / 提交 | Git 提交规范(中文、类型前缀) | 所有项目 | | **review** | review / 审查 | 代码审查(Redkale/Java/Go/SQL 风格偏好) | Java/Go 项目 | | **taskhub** | taskhub / 任务 | 任务管理(ID 规范、todo.md 同步看板) | 所有项目 | #### 技能来源与同步方式 ```bash # 从本机复制到指定项目的容器 home cp ~/.claude/skills/commit/skill.md data/home/flux-dev/.claude/skills/commit/ cp ~/.claude/skills/review/skill.md data/home/flux-dev/.claude/skills/review/ cp ~/.claude/skills/taskhub/skill.md data/home/flux-dev/.claude/skills/taskhub/ # 验证 docker exec {container} ls /root/.claude/skills/*/skill.md ``` #### 项目差异示例 | 项目 | 推荐技能 | 说明 | |------|----------|------| | flux (Java+Redkale) | commit + review + taskhub | review 含 Redkale 易错点 | | suke (Go) | commit + review + taskhub | review 侧重 Go 规范 | | lab (Node) | commit + taskhub | 可不需要 review(或简化版) | > **原则**: 技能内容应匹配项目技术栈。Java 项目的 review 不应包含 Go 规则,反之亦然。 #### 各项目技能差异示例 **review 技能按项目定制**: | 项目 | tech stack | review 应包含 | review 不应包含 | |------|------------|---------------|-----------------| | flux | Java 17 + Redkale | FilterNode 用法、`@ConvertColumn`、Entity 承担逻辑 | Go 惯例、Node 规范 | | suke | Go + Gin | `if err != nil`、`gofmt`、接口设计 | Redkale 注解、Java 命名 | | lab | Node.js + Vue | ESLint 规则、异步模式、TypeScript 类型 | Java/Go 编译规范 | **操作方式**:为每个项目维护独立的 `skill.md`,从通用模板复制后按技术栈裁剪。 ```bash # 示例: 为 suke 项目定制 review 技能 (去除 Java/Redkale 部分) cp ~/.claude/skills/review/skill.md data/home/suke-dev/.claude/skills/review/ # 然后编辑 data/home/suke-dev/.claude/skills/review/skill.md # 删除 Redkale/Java 章节,保留 Go + 通用审查流程 ``` --- ## 4. 容器内工具安装(重建后需重新执行) > 基础镜像只包含最小工具集(curl/git/tmux/ttyd/node)。以下工具需要在容器启动后安装。 > 安装命令写入 `.bashrc` 可实现自动安装,但首次仍需手动执行。 ### 4.1 一键安装脚本 在宿主机执行(或进入容器后执行): ```bash MSYS_NO_PATHCONV=1 docker exec {container_name} bash -c ' # ===== 1. 系统工具 (apk) ===== apk add --no-cache vim jq htop # ===== 2. Bun (JS 包管理器) ===== curl -fsSL https://bun.sh/install | bash # ===== 3. 持久化 bun PATH (所有 shell 生效) ===== echo "export BUN_INSTALL=\"\$HOME/.bun\"" >> /root/.bashrc echo "export PATH=\"\$BUN_INSTALL/bin:\$PATH\"" >> /root/.bashrc cat > /etc/profile.d/bun.sh << "EOF" export BUN_INSTALL="$HOME/.bun" export PATH="$BUN_INSTALL/bin:$PATH" EOF # ===== 4. Go (如项目需要) ===== # 方案 A: apk 安装 (Alpine 仓库版) # apk add go # 方案 B: 从官方下载指定版本 (推荐) # wget -q https://go.dev/dl/go1.24.1.linux-amd64.tar.gz \ # && tar -C /usr/local -xzf go1.24.1.linux-amd64.tar.gz \ # && rm go1.24.1.linux-amd64.tar.gz ' ``` ### 4.2 工具清单与用途 | 工具 | 版本 | 大小 | 安装命令 | 用途 | 适用项目 | |------|------|------|---------|------|---------| | **vim** | 9.2 | **3.2M** (包: 9M) | `apk add vim` | 文件编辑器 | 所有项目 | | **jq** | 1.8.1 | **28K** (包: 9M) | `apk add jq` | JSON 处理/查询 | 所有项目 | | **htop** | 3.4 | **272K** (包: 9M) | `apk add htop` | 系统资源监控 | 所有项目 | | **bun** | 1.3.x | **89.8M** | 官方安装脚本 | JS/TS 包管理器 | flux-admin, flux-uniapp | | **Go** | 1.24+ | ~250M (官方tar) | `apk add go` 或官方下载 | Go 编译运行 | flux-test, flux-mock, file-server | > 注: vim/jq/htop 三者共享 apk 基础依赖 (~9M),一起安装不会额外增加太多空间。 #### 全部工具大小汇总 | 类别 | 工具 | 大小 | 来源 | |------|------|------|------| | **基础镜像内置** | Node.js v24 + npm | **~200MB** | Dockerfile 多阶段构建 | | | ttyd 1.7.7 | ~2MB | Dockerfile | | | git 2.52 | **2.9M** | Dockerfile | | | tmux 3.6 | **808K** | Dockerfile | | | curl / wget / nc / tree / less | <1MB | Dockerfile | | **代理工具 (挂载 ro)** | mysql-proxy | **8.9M** | dist-Linux/ | | | ssh-proxy | **4.6M** | dist-Linux/ | | | redis-proxy | **3.4M** | dist-Linux/ | | | mongo-proxy | **6.3M** | dist-Linux/ | | | 小计 | **23.2M** | | | **开发工具 (挂载 ro)** | JDK 17 musl | **363.2M** | D:/Java/jdk-musl-17 | | | Maven mvnd-3.9.14 | **10.5M** | D:/Java/maven-mvnd-3.9.14 | | | 小计 | **373.7M** | | | **容器内安装 (重建丢失)** | vim 9.2 | **3.2M** | `apk add vim` | | | jq 1.8.1 | **28K** | `apk add jq` | | | htop 3.4 | **272K** | `apk add htop` | | | bun 1.3.x | **89.8M** | 官方安装脚本 | | | Go (如需) | ~250M | `apk add go` 或 tar | | | 小计 (不含 Go) | **~96.5M** | | **容器镜像写层**: 基础 ~45KB + 运行时数据 (~100MB 含 bun/npm 缓存等) ### 4.3 安装验证 ```bash MSYS_NO_PATHCONV=1 docker exec {container_name} bash -lc ' for cmd in vim jq htop bun go; do v=$($cmd --version 2>/dev/null | head -1) [ -n "$v" ] && echo "✓ $cmd: $v" || echo "✗ $cmd: 未安装" done ' ``` ### 4.4 固化到镜像(可选) 如果不想每次重建都重装,可将常用工具加入基础镜像 Dockerfile: ```dockerfile # 在现有 RUN 指令后追加 RUN apk add --no-cache vim jq htop ``` --- ## 5. 容器内 Shell 配置 (.bashrc) > **关键**: 以下两个函数是容器内 Claude Code 和代理工具正常工作的核心。 ### 5.1 claude wrapper(绕过 OAuth) 容器内 Claude Code 默认走 OAuth 登录流程,在无浏览器环境下会卡住。解决方案:用 `--bare` 模式强制走 API Key 认证,并通过 wrapper 函数补回被跳过的功能。 ```bash # data/home/{project}-dev/.bashrc # claude wrapper: use --bare for API key auth, restore CLAUDE.md + settings claude() { local _args=() _args+=(--bare) # CLAUDE.md auto-discovery (bare skips it) [ -f /root/.dev-env/claude/CLAUDE.md ] && _args+=(--add-dir /root/.dev-env/claude) # project settings [ -f /root/.dev-env/claude/settings.local.json ] && _args+=(--settings /root/.dev-env/claude/settings.local.json) # pass through all user args command claude "${_args[@]}" "$@" } ``` **原理**: - `--bare` 模式:只认 `ANTHROPIC_API_KEY`,不走 OAuth/keychain - `--bare` 会跳过 CLAUDE.md 自动发现 → 用 `--add-dir` 手动指定 - `--bare` 不读 settings → 用 `--settings` 手动加载权限配置 ### 5.2 代理服务自动启动 代理工具需要在容器内以 server 模式运行(不是 client 模式),且需要各自的 `.toml` 配置文件。 ```bash # 代理服务 (idempotent: 只在未运行时启动) _start_proxy() { local name=$1 bin=$2 cfgdir=$3 if pgrep -x "$bin" > /dev/null 2>&1; then return; fi if [ -f "$cfgdir/$bin.toml" ]; then (cd "$cfgdir" && "$bin" &>/tmp/$bin.log &) sleep 1 fi } _start_proxy mysql-proxy mysql-proxy /root/.dev-env _start_proxy redis-proxy redis-proxy /root/.dev-env _start_proxy ssh-proxy ssh-proxy /root/.dev-env ``` **原理**: - `pgrep -x` 确保幂等(多次 source 不重复启动) - 从 `/root/.dev-env/` 目录读取对应 `.toml` 启动 - 日志输出到 `/tmp/{proxy}.log` 方便排查 ### 5.3 完整 .bashrc 示例 ```bash # bun (idempotent) if [ -z "$BUN_INSTALL" ]; then export BUN_INSTALL="$HOME/.bun" export PATH="$BUN_INSTALL/bin:$PATH" fi # 代理服务自动启动 (见 5.2) _start_proxy() { ... } # 同上 _start_proxy mysql-proxy mysql-proxy /root/.dev-env _start_proxy redis-proxy redis-proxy /root/.dev-env _start_proxy ssh-proxy ssh-proxy /root/.dev-env # claude wrapper (见 5.1) claude() { ... } # 同上 ``` --- ## 6. 踩坑记录 | # | 问题 | 原因 | 解决方案 | |---|------|------|---------| | 1 | **Claude Code 弹出 OAuth 登录** | 容器内无浏览器,默认交互模式走 OAuth | 用 `--bare` + `ANTHROPIC_API_KEY`(见 5.1) | | 2 | **Auth conflict 警告** | 同时设置 `ANTHROPIC_AUTH_TOKEN` 和 `ANTHROPIC_API_KEY` | compose 中只用 `ANTHROPIC_API_KEY=${ANTHROPIC_AUTH_TOKEN}` | | 3 | **ssh-proxy/mysql-proxy 报 "No such file"** | 代理工具需要 `.toml` 配置文件才能以 server 模式启动 | 挂载项目专属 `.toml` 到 `/root/.dev-env/`(按信息隔离原则) | | 4 | **SSH 连接失败 "Permission denied"** | ssh-proxy 需要私钥文件认证远程服务器 | 挂载宿主机 `~/.ssh/id_ed25519` 到 `/root/.ssh/` | | 5 | **--bare 模式不读 CLAUDE.md** | bare 模式跳过自动发现机制 | wrapper 函数中加 `--add-dir` 手动指定 | | 6 | **容器重建后代理不可用** | 代理进程在容器写层,重建丢失 | 在 `.bashrc` 中用 `_start_proxy()` 自动启动 | | 7 | **BUN_INSTALL/PATH 重复追加** | 安装脚本被多次执行,每次都 append | 加 `[ -z "$BUN_INSTALL" ]` 幂等守卫 | | 8 | **data/home 下出现 .dev-env/ 重复目录** | 旧版 compose 将 dev-envs 挂载到了 home 下 | 删除 `data/home/{project}-dev/.dev-env/`,确认 compose 只挂载 ro 版本 | --- ## 7. 目录结构总览 ``` workpod/ │ ├── instances/{project}/ # 容器编排 │ ├── docker-compose.yml # Compose 定义 │ ├── Dockerfile # (可选) 扩展镜像 │ └── .env # 敏感变量: ANTHROPIC_AUTH_TOKEN (不进 git) │ ├── dev-envs/{project}/ # ★ 项目配置 (只读挂载 → /root/.dev-env) │ ├── servers.yaml # 服务器 IP/端口/用途 │ ├── databases.yaml # 数据库/Redis/第三方密钥 │ ├── norms.md # 开发规范 (唯一事实来源) │ ├── ssh-proxy.toml # SSH 代理配置 (仅该项目服务器) │ ├── mysql-proxy.toml # MySQL 代理配置 (仅该项目连接) │ ├── redis-proxy.toml # Redis 代理配置 (仅该项目连接) │ ├── docs/ # 仅该项目相关文档 (从 KMS 筛选) │ └── claude/ │ ├── CLAUDE.md # Claude Code 项目指令 (引用 norms.md) │ └── settings.local.json # Claude Code 权限 │ ├── data/home/{project}-dev/ # 运行时数据 (读写挂载 → /root) │ ├── .gitconfig # Git 用户 + 凭据配置 │ ├── .git-credentials-gitea # Gitea 密码 (权限 600) │ ├── .bashrc # ★ Shell 配置 (claude wrapper + 代理启动) │ ├── .claude/ # Claude Code 运行时数据 │ │ └── skills/ # ★ 自定义技能 (按项目需求同步,见 §3.4b) │ │ ├── commit/skill.md # Git 提交规范 (通用) │ │ ├── review/skill.md # 代码审查 (按技术栈定制内容) │ │ └── taskhub/skill.md # 任务管理 (通用) │ ├── .bun/ # bun 安装包 │ └── .ash_history # 命令历史 │ ├── docs/03-运维/ │ ├── 部署维护手册.md │ └── 开发环境搭建手册.md # ← 本文档 │ ├── Dockerfile # 基础镜像构建 ├── entrypoint.sh # 容器入口脚本 └── SPECS.md # 技术规格文档 ``` ### 职责划分 | 目录 | 挂载方式 | 内容 | 谁来维护 | |------|---------|------|---------| | `dev-envs/{project}/` | **只读** | 项目配置、规范、知识库 | AI / 开发者编写 | | `data/home/{project}-dev/` | **读写** | 运行时产生的文件 | 容器自动产生 | | `instances/{project}/` | — | Compose 编排定义 | AI 生成 | > **禁止**: 在 `data/home/` 下放置配置文件(会导致与 dev-envs 重复或被覆盖) --- ## 附录 A: 运维 AI 执行 Checklist 新建项目开发环境时,按此清单逐项执行: ``` □ 1. 创建目录 □ mkdir -p dev-envs/{project}/claude □ mkdir -p data/home/{project}-dev □ 2. 编写配置文件 (8 个文件 + 知识库文档) □ dev-envs/{project}/servers.yaml # 服务器信息 (仅该项目) □ dev-envs/{project}/databases.yaml # 数据库连接 (仅该项目) □ dev-envs/{project}/norms.md # 开发规范 □ dev-envs/{project}/ssh-proxy.toml # SSH 代理配置 (仅该项目服务器) □ dev-envs/{project}/mysql-proxy.toml # MySQL 代理配置 (仅该项目连接) □ dev-envs/{project}/redis-proxy.toml # Redis 代理配置 (仅该项目连接) □ dev-envs/{project}/docs/ # 从 KMS 筛选该项目相关文档 □ dev-envs/{project}/claude/CLAUDE.md □ dev-envs/{project}/claude/settings.local.json □ 3. 配置 home □ data/home/{project}-dev/.gitconfig □ data/home/{project}-dev/.bashrc # ★ claude wrapper + _start_proxy (见第 5 节) □ 4. 生成 compose + .env □ 从模板复制 instances/{project}/docker-compose.yml □ 修改: name/ports/volumes(项目路径+dev-envs+SSH密钥+.toml)/env/Claude变量/network □ 创建 instances/{project}/.env # ANTHROPIC_AUTH_TOKEN (不进 git) □ 5. 构建镜像 (如需新 Dockerfile) □ docker build -t ws-{project}-dev:latest -f instances/{project}/Dockerfile . □ 6. 启动容器 □ docker compose -f instances/{project}/docker-compose.yml up -d □ 7. 安装额外工具(重建后需重新执行,见第 4 节完整命令) □ vim + jq + htop: `apk add vim jq htop` □ bun: `curl -fsSL https://bun.sh/install | bash` + 持久化 PATH □ Go (如需): `apk add go` 或官方下载 □ 8. 同步自定义技能(按项目需求选择性复制,见 §3.4b) □ mkdir -p data/home/{project}-dev/.claude/skills/{commit,review,taskhub} □ cp ~/.claude/skills/commit/skill.md data/home/{project}-dev/.claude/skills/commit/ □ cp ~/.claude/skills/review/skill.md data/home/{project}-dev/.claude/skills/review/ □ cp ~/.claude/skills/taskhub/skill.md data/home/{project}-dev/.claude/skills/taskhub/ □ 9. 验证代理工具 □ docker exec {container} bash -c 'source ~/.bashrc && mysql-proxy cli -c flux_dev -e "SELECT 1"' □ docker exec {container} bash -c 'source ~/.bashrc && redis-proxy get -c flux_dev -k "test_key"' □ docker exec {container} bash -c 'source ~/.bashrc && ssh-proxy exec -n flux_dev -c "hostname"' □ 10. 验证 Claude Code □ docker exec {container} bash -c 'source ~/.bashrc && claude -p "say hi"' □ 11. 验证技能 □ docker exec {container} ls /root/.claude/skills/*/skill.md □ 12. 验证其他 □ docker exec {container} ls /root/.dev-env/docs/ □ docker exec {container} cat /root/.dev-env/servers.yaml | head -5 □ docker exec {container} git config --global --list □ docker exec {container} vim --version | head -1 □ 浏览器打开 http://localhost:{WEB_PORT} ``` --- ## 附录 B: fet 交叉编译 ```bash # 1. 添加 musl target rustup target add x86_64-unknown-linux-musl # 2. 交叉编译 cd E:/wk-oth/rust-work/fet cargo build --release --target x86_64-unknown-linux-musl # 3. 复制到 dist-Linux cp target/x86_64-unknown-linux-musl/release/fet ../dist-Linux/ # 4. 验证 file ../dist-Linux/fet # 期望输出: ELF 64-bit LSB pie executable, x86-64, static-pie linked # 5. 在 compose 中添加挂载 # - E:/wk-oth/rust-work/dist-Linux/fet:/usr/local/bin/fet:ro ```