Files
workpod/docs/03-运维/开发环境搭建手册.md
T

36 KiB
Raw Blame History

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 / hostname
  • ports (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 != nilgofmt、接口设计 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_TOKENANTHROPIC_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