36 KiB
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 创建项目环境目录
# 在 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 — 服务器信息
# 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: <TEST_REDIS_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 — 数据库连接
# 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: <TEST_DB_ROOT_PASSWORD>
role: admin
- username: u_flux
password: <TEST_DB_APP_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: <PROD_DB_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: <PROD_MP_APP_PASSWORD>
role: app
note: 小程序数据库
redis:
- name: flux_dev
env: test
host: 39.99.243.191
port: 6379
password: <TEST_REDIS_PASSWORD>
proxy_name: flux_dev # redis-proxy 连接名
feishu_bot:
workspace: flux
app_id: <FEISHU_APP_ID>
app_secret: <FEISHU_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 — 开发规范摘要
# 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 项目指令
# 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
开发命令
# 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:
[user]
name = 绝尘
email = dev@1216.top
[core]
autocrlf = input
quotepath = false
[push]
default = simple
1.4 生成 Compose 文件
从模板生成 instances/flux/docker-compose.yml:
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):# Claude Code API Key (智谱 AI) ANTHROPIC_AUTH_TOKEN=your_token_here
1.5 启动与验证
# 构建并启动
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: 复制模板目录
# 以 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/hostnameports(SSH/Web)volumes中的项目路径和 dev-envs 路径environment中的项目特定变量networks.name
# 一键启动
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 版。编译命令: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 同步看板) | 所有项目 |
技能来源与同步方式
# 从本机复制到指定项目的容器 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,从通用模板复制后按技术栈裁剪。
# 示例: 为 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 一键安装脚本
在宿主机执行(或进入容器后执行):
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 安装验证
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:
# 在现有 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 函数补回被跳过的功能。
# 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 配置文件。
# 代理服务 (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 示例
# 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 交叉编译
# 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