1561 lines
44 KiB
Markdown
1561 lines
44 KiB
Markdown
---
|
||
name: ops-tools
|
||
description: DevOps 运维工具。用于 SSH 连接服务器、部署应用、健康检查、日志查看、服务重启和系统监控。当用户提到服务器操作、部署、运维、Jenkins、Gitea、ai-proj 相关任务时自动激活。
|
||
---
|
||
|
||
# DevOps Skill
|
||
|
||
## 子文档索引
|
||
|
||
| 文档 | 说明 |
|
||
|------|------|
|
||
| [ai-proj-deploy.md](ai-proj-deploy.md) | AI-Proj 部署流程 |
|
||
| [coolbuy-deploy.md](coolbuy-deploy.md) | Coolbuy-PaaS 部署流程 |
|
||
| [db-backup.md](db-backup.md) | ⚠️ **数据库备份与恢复(迁移前必读)** |
|
||
| [mcp-config.md](mcp-config.md) | Claude Code MCP 配置 |
|
||
| [incidents.md](incidents.md) | 重大事件记录 |
|
||
|
||
> ⚠️ **重要提醒**:执行任何数据库 UPDATE/DELETE/ALTER 或数据迁移操作前,**必须先备份**!
|
||
> 详见 [db-backup.md](db-backup.md) 的「迁移前快速备份」章节。
|
||
|
||
---
|
||
|
||
## 服务器清单
|
||
|
||
| 别名 | IP | 用户 | SSH 密钥 | 用途 |
|
||
|------|-----|------|----------|------|
|
||
| tools-jenkins | 101.200.136.200 | root | ~/.ssh/tools.pem | Jenkins CI/CD |
|
||
| tools-gitea | 123.56.89.187 | root | ~/.ssh/tools.pem | Gitea 代码托管 |
|
||
| tools_ai_proj | 152.136.104.251 | root | ~/.ssh/tools_ai_proj.pem | AI项目生产服务器 |
|
||
| singapore | 43.134.28.147 | ubuntu | ~/.ssh/singpore.pem | AI项目测试环境 & 跳板机 |
|
||
| siyuan | 47.93.23.182 | root | ~/Downloads/siyuan.pem | 思源笔记服务器 (阿里云, Ubuntu 24.04) |
|
||
| lvkai | 124.223.196.74 | root | ~/.ssh/lvkai | 通用服务器 (腾讯云, OpenCloudOS) |
|
||
| coolbuy-dev | 100.112.161.79 | coolbuy-dev | ~/.ssh/id_ed25519_coolbuy_dev | Coolbuy 开发服务器 (Tailscale) |
|
||
| melbourne | 100.85.65.39 | coolbuy-dev | ~/.ssh/id_ed25519_coolbuy_dev | Melbourne 开发电脑 (Tailscale) |
|
||
| cn-dev | 100.92.148.46 | johnqiu | ~/.ssh/id_ed25519_cn_dev | 北京 MacBook Pro (Tailscale) |
|
||
| chengdu-mac-mini | 100.105.50.115 | coolbuy | ~/.ssh/id_ed25519 | 成都 Mac Mini (Tailscale, SOCKS5 代理节点) |
|
||
| au-dev | 当前电脑 | coolbuy-dev | - | 澳洲开发电脑 (本机) |
|
||
| adelaide-dev-mini | 100.114.124.68 | donglinlai | ~/.ssh/id_ed25519 | Adelaide Mac Mini (Tailscale, 密钥存储) |
|
||
| cn-bj-lazycat | 100.115.52.119 / haiqing.heiyu.space | root | 密码认证 (zhiyun2026) | 北京算力仓服务器 (Debian 6.5.0, 懒猫微服) |
|
||
|
||
### SSH 快捷连接
|
||
|
||
```bash
|
||
ssh tools-jenkins # Jenkins 服务器
|
||
ssh tools-gitea # Gitea 服务器
|
||
ssh tools_ai_proj # AI项目生产服务器
|
||
ssh singapore # 新加坡测试环境
|
||
ssh siyuan # 思源笔记服务器
|
||
ssh lvkai # LvKai 通用服务器
|
||
ssh coolbuy-dev # Coolbuy 开发服务器 (Tailscale)
|
||
ssh melbourne # Melbourne 开发电脑 (Tailscale)
|
||
ssh cn-dev # 北京 MacBook Pro (Tailscale) - iOS 开发
|
||
ssh adelaide-dev-mini # Adelaide Mac Mini (密钥存储)
|
||
```
|
||
|
||
### 密钥存储机器
|
||
|
||
**adelaide-dev-mini** (100.114.124.68) 存储了所有服务器的 SSH 密钥:
|
||
|
||
```bash
|
||
# 查看可用密钥
|
||
ssh adelaide-dev-mini "ls ~/.ssh/*.pem"
|
||
|
||
# 可用密钥列表:
|
||
# - singpore.pem → Singapore staging 服务器
|
||
# - tools_ai_proj.pem → 生产服务器
|
||
# - tools.pem → Jenkins/Gitea 服务器
|
||
# - coolbuy3.pem → Coolbuy 相关服务器
|
||
```
|
||
|
||
**密钥同步到本机**:
|
||
```bash
|
||
# 下载缺失的密钥
|
||
ssh adelaide-dev-mini "cat ~/.ssh/singpore.pem" > ~/.ssh/singpore.pem
|
||
chmod 600 ~/.ssh/singpore.pem
|
||
```
|
||
|
||
---
|
||
|
||
## 凭据配置
|
||
|
||
凭据存储在 `~/.config/devops/credentials.env`(权限 600):
|
||
|
||
```bash
|
||
source ~/.config/devops/credentials.env
|
||
|
||
# Jenkins API
|
||
curl -s "$JENKINS_URL/api/json" \
|
||
-u "$JENKINS_USER:$JENKINS_TOKEN"
|
||
```
|
||
|
||
| 服务 | 变量 |
|
||
|------|------|
|
||
| Jenkins | `$JENKINS_USER:$JENKINS_TOKEN` |
|
||
| OSS | `$OSS_ACCESS_KEY_ID`, `$OSS_ACCESS_KEY_SECRET` |
|
||
|
||
> Gitea 操作统一使用 `tea` CLI,详见 `pull-request` 技能。
|
||
|
||
---
|
||
|
||
## 服务地址
|
||
|
||
| 服务 | URL | 备注 |
|
||
|------|-----|------|
|
||
| Gitea Web | https://gitea.pipexerp.com | 代码仓库 |
|
||
| Gitea SSH | git@gitea.pipexerp.com:10022 | Git SSH |
|
||
| Jenkins | https://jenkins.pipexerp.com | CI/CD |
|
||
| AI-Proj | https://ai.pipexerp.com | 生产环境 |
|
||
| AI-Proj Staging | http://staging.ai.pipexerp.com | 测试环境 |
|
||
| 思源笔记 | http://47.93.23.182 | 访问码: SiYuan@2026 |
|
||
|
||
---
|
||
|
||
## 常用命令
|
||
|
||
### 系统状态
|
||
|
||
```bash
|
||
# 服务器概况
|
||
ssh <server> "uptime && free -h && df -h && docker ps"
|
||
|
||
# Docker 资源
|
||
ssh <server> "docker stats --no-stream"
|
||
|
||
# CPU/内存 Top 进程
|
||
ssh <server> "ps aux --sort=-%cpu | head -10"
|
||
```
|
||
|
||
### AI-Proj 操作
|
||
|
||
```bash
|
||
# 健康检查
|
||
curl -s https://ai.pipexerp.com/api/v1/health | jq .
|
||
|
||
# 查看日志
|
||
ssh tools_ai_proj "docker logs -f ai_backend_prod --tail 100"
|
||
|
||
# 重启服务
|
||
ssh tools_ai_proj "docker restart ai_backend_prod"
|
||
|
||
# 生产部署(用户手动在终端执行,Claude 不要自动运行)
|
||
# 详见 ai-proj-deploy.md「部署到生产环境」章节
|
||
# docker buildx build --platform linux/amd64 -t saltthing123/ai-proj-frontend:latest -f frontend/Dockerfile.prod --push ./frontend
|
||
# docker buildx build --platform linux/amd64 -t saltthing123/ai-proj-backend:latest --push ./backend
|
||
# ssh tools_ai_proj "cd /opt/ai-project && docker compose -f docker-compose.dockerhub.yml pull && docker compose -f docker-compose.dockerhub.yml up -d"
|
||
|
||
# iOS TestFlight 部署 → 详见 dev-coding 技能「TestFlight 部署」章节
|
||
# 构建机器: cn-dev | Apple ID: 6205365@qq.com | Team: 5NHLK8SPHB
|
||
```
|
||
|
||
### 思源笔记操作
|
||
|
||
```bash
|
||
# 查看容器状态
|
||
ssh siyuan "docker ps | grep siyuan"
|
||
|
||
# 查看日志
|
||
ssh siyuan "docker logs -f siyuan --tail 100"
|
||
|
||
# 重启服务
|
||
ssh siyuan "docker restart siyuan"
|
||
|
||
# 停止服务
|
||
ssh siyuan "docker stop siyuan"
|
||
|
||
# 启动服务
|
||
ssh siyuan "docker start siyuan"
|
||
|
||
# 查看数据目录大小
|
||
ssh siyuan "du -sh /opt/siyuan/workspace"
|
||
|
||
# 备份数据
|
||
ssh siyuan "tar -czf /root/siyuan-backup-\$(date +%Y%m%d).tar.gz /opt/siyuan/workspace"
|
||
|
||
# 下载备份到本地
|
||
scp siyuan:/root/siyuan-backup-*.tar.gz ~/Downloads/
|
||
|
||
# 升级思源笔记(拉取最新镜像)
|
||
ssh siyuan "docker pull b3log/siyuan:latest && docker restart siyuan"
|
||
|
||
# 访问测试
|
||
curl -I http://47.93.23.182
|
||
```
|
||
|
||
### 数据库操作(迁移前必备份)
|
||
|
||
```bash
|
||
# ⚠️ 迁移前备份(AI-Proj 生产)
|
||
ssh tools_ai_proj 'docker exec ai_postgres_prod pg_dump -U ai_prod_user -Fc ai_project_prod \
|
||
> /backup/ai-project/database/ai_project_$(date +%Y%m%d_%H%M%S)_pre_migration.dump'
|
||
|
||
# 查看备份列表
|
||
ssh tools_ai_proj 'ls -lht /backup/ai-project/database/*.dump | head -5'
|
||
|
||
# 快速恢复
|
||
ssh tools_ai_proj 'docker exec ai_postgres_prod pg_restore \
|
||
-U ai_prod_user -d ai_project_prod --clean --if-exists -Fc \
|
||
/backup/ai-project/database/BACKUP_FILE.dump'
|
||
|
||
# 执行 SQL 文件
|
||
scp /tmp/migration.sql tools_ai_proj:/tmp/
|
||
ssh tools_ai_proj 'docker cp /tmp/migration.sql ai_postgres_prod:/tmp/ && \
|
||
docker exec ai_postgres_prod psql -U ai_prod_user -d ai_project_prod -f /tmp/migration.sql'
|
||
```
|
||
|
||
> 详细文档见 [db-backup.md](db-backup.md)
|
||
|
||
### Gitea 操作
|
||
|
||
```bash
|
||
# PR / 代码评审 → 使用 tea CLI(pull-request 技能)
|
||
tea pr list
|
||
tea pr create ...
|
||
|
||
# 查看容器(服务器运维)
|
||
ssh tools-gitea "docker ps | grep gitea"
|
||
ssh tools-gitea "docker logs -f gitea --tail 100"
|
||
```
|
||
|
||
### Jenkins 操作
|
||
|
||
```bash
|
||
source ~/.config/devops/credentials.env
|
||
|
||
# 构建状态
|
||
curl -s "$JENKINS_URL/job/coolbuy-paas/lastBuild/api/json" \
|
||
-u "$JENKINS_USER:$JENKINS_TOKEN" | jq '.result, .building'
|
||
|
||
# 触发部署
|
||
curl -X POST "$JENKINS_URL/job/coolbuy-paas/buildWithParameters" \
|
||
-u "$JENKINS_USER:$JENKINS_TOKEN" \
|
||
--data "ACTION=deploy-prod&IMAGE_TAG=latest"
|
||
```
|
||
|
||
---
|
||
|
||
## 双电脑同步 (au-dev / cn-dev)
|
||
|
||
### 项目目录
|
||
|
||
| 电脑 | new-ai-proj 路径 |
|
||
|------|------------------|
|
||
| au-dev | /Users/coolbuy-dev/coding/new-ai-proj |
|
||
| cn-dev | /Users/johnqiu/workspace/new-ai-proj |
|
||
|
||
### sync-leave(离开前)
|
||
|
||
```bash
|
||
git add -A
|
||
git commit -m "WIP: sync from $(hostname)" || echo "Nothing to commit"
|
||
git push origin $(git branch --show-current)
|
||
```
|
||
|
||
### sync-arrive(到达后)
|
||
|
||
```bash
|
||
git fetch origin
|
||
git pull origin $(git branch --show-current)
|
||
```
|
||
|
||
### sync-merge(合并 WIP 提交)
|
||
|
||
```bash
|
||
git reset --soft HEAD~<WIP数量>
|
||
git add -A
|
||
git commit -m "feat: 实际功能描述"
|
||
git push origin $(git branch --show-current) --force-with-lease
|
||
```
|
||
|
||
---
|
||
|
||
## 故障排查
|
||
|
||
### 服务无响应
|
||
|
||
```bash
|
||
systemctl status <service>
|
||
journalctl -u <service> --since "5 minutes ago"
|
||
netstat -tlnp | grep <port>
|
||
```
|
||
|
||
### 磁盘空间不足
|
||
|
||
```bash
|
||
df -h
|
||
docker system prune -af
|
||
journalctl --vacuum-size=500M
|
||
```
|
||
|
||
### 内存不足
|
||
|
||
```bash
|
||
free -h
|
||
ps aux --sort=-%mem | head -10
|
||
```
|
||
|
||
---
|
||
|
||
## 安全注意事项
|
||
|
||
- SSH 密钥权限必须是 600
|
||
- 不要在命令中明文包含密码
|
||
- 生产环境操作需要二次确认
|
||
- **生产数据库操作必须先备份**
|
||
- **docker compose down 前检查 volumes 配置**
|
||
|
||
---
|
||
|
||
## AI-Proj 用户管理
|
||
|
||
### 创建系统用户
|
||
|
||
> **重要**: AI-Proj 后端使用 bcrypt **cost 12** 进行密码哈希。不要使用 cost 10 或其他值。
|
||
|
||
#### 完整流程
|
||
|
||
由于 bcrypt 哈希包含 `$` 字符,在 shell 中直接执行会导致变量替换问题。正确流程如下:
|
||
|
||
**步骤 1: 生成密码哈希(cost 12)**
|
||
|
||
```bash
|
||
# 在 backend 目录下执行,使用 Go 生成哈希
|
||
cd /path/to/new-ai-proj/backend
|
||
|
||
# 创建临时 Go 脚本
|
||
cat > /tmp/genhash.go << 'EOF'
|
||
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"golang.org/x/crypto/bcrypt"
|
||
)
|
||
|
||
func main() {
|
||
hash, err := bcrypt.GenerateFromPassword([]byte("用户密码"), 12)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
fmt.Println(string(hash))
|
||
}
|
||
EOF
|
||
|
||
# 执行生成哈希
|
||
go run /tmp/genhash.go
|
||
# 输出示例: $2a$12$E5KVmMDiJPi61kThzgDEdeRiIHqTtZ2yB5F0ccIoE3wfRPIH7hHRG
|
||
```
|
||
|
||
**步骤 2: 创建 SQL 文件**
|
||
|
||
```bash
|
||
# 将哈希写入 SQL 文件(避免 shell 转义问题)
|
||
cat > /tmp/create_user.sql << 'EOF'
|
||
INSERT INTO users (
|
||
username,
|
||
email,
|
||
password_hash,
|
||
user_type,
|
||
role,
|
||
status,
|
||
created_at,
|
||
updated_at
|
||
) VALUES (
|
||
'newuser',
|
||
'newuser@example.com',
|
||
'$2a$12$E5KVmMDiJPi61kThzgDEdeRiIHqTtZ2yB5F0ccIoE3wfRPIH7hHRG',
|
||
'system',
|
||
'admin',
|
||
'active',
|
||
NOW(),
|
||
NOW()
|
||
);
|
||
EOF
|
||
```
|
||
|
||
**步骤 3: 传输并执行 SQL**
|
||
|
||
```bash
|
||
# 复制 SQL 文件到服务器
|
||
scp /tmp/create_user.sql tools_ai_proj:/tmp/
|
||
|
||
# 在服务器上执行
|
||
ssh tools_ai_proj "docker cp /tmp/create_user.sql ai_postgres_prod:/tmp/ && \
|
||
docker exec ai_postgres_prod psql -U ai_prod_user -d ai_project_prod -f /tmp/create_user.sql"
|
||
```
|
||
|
||
**步骤 4: 验证用户创建**
|
||
|
||
```bash
|
||
# 检查用户是否创建成功
|
||
ssh tools_ai_proj "docker exec ai_postgres_prod psql -U ai_prod_user -d ai_project_prod \
|
||
-c \"SELECT id, username, email, user_type, role, status, length(password_hash) as hash_len FROM users WHERE username = 'newuser';\""
|
||
|
||
# 测试登录
|
||
curl -s -X POST "https://ai.pipexerp.com/api/v1/auth/login" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"username":"newuser","password":"用户密码"}' | jq '.success'
|
||
```
|
||
|
||
### 用户角色说明
|
||
|
||
| user_type | role | 说明 |
|
||
|-----------|------|------|
|
||
| system | admin | 系统管理员(最高权限) |
|
||
| system | user | 系统用户 |
|
||
| tenant | admin | 租户管理员 |
|
||
| tenant | user | 租户用户 |
|
||
|
||
### 重置用户密码
|
||
|
||
```bash
|
||
# 1. 生成新密码哈希
|
||
cd /path/to/new-ai-proj/backend
|
||
cat > /tmp/genhash.go << 'EOF'
|
||
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"golang.org/x/crypto/bcrypt"
|
||
)
|
||
|
||
func main() {
|
||
hash, _ := bcrypt.GenerateFromPassword([]byte("新密码"), 12)
|
||
fmt.Println(string(hash))
|
||
}
|
||
EOF
|
||
NEW_HASH=$(go run /tmp/genhash.go)
|
||
|
||
# 2. 创建更新 SQL
|
||
cat > /tmp/reset_pwd.sql << EOF
|
||
UPDATE users SET password_hash = '$NEW_HASH' WHERE username = 'targetuser';
|
||
EOF
|
||
|
||
# 3. 执行更新
|
||
scp /tmp/reset_pwd.sql tools_ai_proj:/tmp/
|
||
ssh tools_ai_proj "docker cp /tmp/reset_pwd.sql ai_postgres_prod:/tmp/ && \
|
||
docker exec ai_postgres_prod psql -U ai_prod_user -d ai_project_prod -f /tmp/reset_pwd.sql"
|
||
```
|
||
|
||
### 常见问题
|
||
|
||
| 问题 | 原因 | 解决方案 |
|
||
|------|------|----------|
|
||
| 登录失败,密码错误 | 哈希 cost 不匹配(使用了 cost 10) | 使用 Go 重新生成 cost 12 的哈希 |
|
||
| SQL 执行失败 | `$` 字符被 shell 解释 | 使用 heredoc 或文件传输方式 |
|
||
| 哈希被截断 | 直接在命令行执行 SQL | 使用文件方式避免转义问题 |
|
||
|
||
## 本地开发环境配置 (au-dev)
|
||
|
||
### 前置条件
|
||
|
||
```bash
|
||
# PostgreSQL 16 (Homebrew)
|
||
brew install postgresql@16
|
||
brew services start postgresql@16
|
||
|
||
# Redis
|
||
brew install redis
|
||
brew services start redis
|
||
|
||
# Tailscale (用于访问 cn-dev / au-dev-mini)
|
||
# 从 App Store 安装或 brew install tailscale
|
||
```
|
||
|
||
### 从 Staging 同步数据库
|
||
|
||
当本地需要测试数据时,从 Singapore staging 环境同步:
|
||
|
||
```bash
|
||
# 1. 确保有 singpore.pem 密钥
|
||
ls ~/.ssh/singpore.pem || ssh au-dev-mini "cat ~/.ssh/singpore.pem" > ~/.ssh/singpore.pem
|
||
chmod 600 ~/.ssh/singpore.pem
|
||
|
||
# 2. 导出 staging 数据库
|
||
ssh singapore "docker exec ai_postgres_staging pg_dump -U ai_staging_user ai_project_staging --no-owner --no-acl --clean --if-exists | gzip > /tmp/staging_backup.sql.gz"
|
||
|
||
# 3. 下载到本地
|
||
scp singapore:/tmp/staging_backup.sql.gz /tmp/
|
||
|
||
# 4. 重建本地数据库
|
||
psql postgres -c "DROP DATABASE IF EXISTS ai_project_local;"
|
||
psql postgres -c "DROP USER IF EXISTS ai_local;"
|
||
psql postgres -c "CREATE USER ai_local WITH PASSWORD 'ai_local_pass' SUPERUSER;"
|
||
psql postgres -c "CREATE DATABASE ai_project_local OWNER ai_local;"
|
||
|
||
# 5. 恢复数据
|
||
gunzip -c /tmp/staging_backup.sql.gz | psql -U ai_local ai_project_local
|
||
|
||
# 6. 验证
|
||
psql -U ai_local ai_project_local -c "SELECT COUNT(*) FROM tasks;"
|
||
```
|
||
|
||
### 后端 .env 配置
|
||
|
||
```bash
|
||
# 创建 backend/.env
|
||
cat > /Users/coolbuy-dev/coding/new-ai-proj/backend/.env << 'EOF'
|
||
ENV=development
|
||
APP_ENV=development
|
||
GIN_MODE=debug
|
||
|
||
DB_HOST=localhost
|
||
DB_PORT=5432
|
||
DB_USER=ai_local
|
||
DB_PASSWORD=ai_local_pass
|
||
DB_NAME=ai_project_local
|
||
DB_SSL_MODE=disable
|
||
|
||
REDIS_HOST=localhost
|
||
REDIS_PORT=6379
|
||
REDIS_PASSWORD=
|
||
REDIS_DB=0
|
||
|
||
BACKEND_PORT=8080
|
||
JWT_SECRET=local_dev_jwt_secret_key_32chars
|
||
JWT_EXPIRATION=168h
|
||
CORS_ORIGIN=http://localhost:3000
|
||
|
||
FEATURE_SUPERADMIN_ENABLE=true
|
||
SUPER_ADMIN_USERNAMES=admin
|
||
EOF
|
||
```
|
||
|
||
### 启动本地服务
|
||
|
||
```bash
|
||
# 终端 1: 后端
|
||
cd /Users/coolbuy-dev/coding/new-ai-proj/backend
|
||
go run main.go
|
||
|
||
# 终端 2: 前端
|
||
cd /Users/coolbuy-dev/coding/new-ai-proj/frontend
|
||
npm start
|
||
|
||
# 验证
|
||
curl -s http://localhost:8080/api/v1/health | jq .
|
||
# 访问 http://localhost:3000
|
||
```
|
||
|
||
### 本地服务状态检查
|
||
|
||
```bash
|
||
# PostgreSQL
|
||
pg_isready -h localhost
|
||
|
||
# Redis
|
||
redis-cli ping
|
||
|
||
# 后端健康检查
|
||
curl -s http://localhost:8080/api/v1/health
|
||
|
||
# 前端 (检查端口)
|
||
lsof -i :3000
|
||
```
|
||
|
||
---
|
||
|
||
## 跨境网络代理 (SSH SOCKS5 隧道)
|
||
|
||
当从澳洲访问国内网站(如 ai.pipexerp.com)速度慢时,可通过国内 Tailscale 节点建立 SSH 隧道。
|
||
|
||
### 问题诊断
|
||
|
||
```bash
|
||
# 1. 检查延迟和丢包
|
||
ping -c 3 ai.pipexerp.com
|
||
|
||
# 2. 确认出口 IP 位置
|
||
curl -s ipinfo.io
|
||
|
||
# 3. 测试访问速度
|
||
curl -I --connect-timeout 10 https://ai.pipexerp.com
|
||
```
|
||
|
||
### Tailscale 国内节点
|
||
|
||
| 节点 | IP | 用户 | 用途 |
|
||
|------|-----|------|------|
|
||
| chengdu-mac-mini | 100.105.50.115 | coolbuy | 成都 Mac Mini (推荐) |
|
||
| cn-bj-qiu-macbook-portable | 100.92.148.46 | - | 北京 MacBook |
|
||
| cn-tj-pve-fnos | 100.118.62.18 | - | 天津 Linux |
|
||
|
||
### 手动启动 SOCKS5 代理
|
||
|
||
```bash
|
||
# 通过成都节点建立隧道 (端口 1080)
|
||
ssh -D 1080 -C -N -f coolbuy@100.105.50.115
|
||
|
||
# 测试代理
|
||
curl -x socks5://localhost:1080 -I https://ai.pipexerp.com
|
||
```
|
||
|
||
### 开机自启动配置
|
||
|
||
plist 文件: `~/Library/LaunchAgents/com.socks.chengdu.plist`
|
||
|
||
```xml
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||
<plist version="1.0">
|
||
<dict>
|
||
<key>Label</key>
|
||
<string>com.socks.chengdu</string>
|
||
<key>ProgramArguments</key>
|
||
<array>
|
||
<string>/usr/bin/ssh</string>
|
||
<string>-D</string>
|
||
<string>1080</string>
|
||
<string>-C</string>
|
||
<string>-N</string>
|
||
<string>-o</string>
|
||
<string>ServerAliveInterval=60</string>
|
||
<string>-o</string>
|
||
<string>ServerAliveCountMax=3</string>
|
||
<string>-o</string>
|
||
<string>ExitOnForwardFailure=yes</string>
|
||
<string>coolbuy@100.105.50.115</string>
|
||
</array>
|
||
<key>RunAtLoad</key>
|
||
<true/>
|
||
<key>KeepAlive</key>
|
||
<true/>
|
||
<key>StandardErrorPath</key>
|
||
<string>/tmp/socks-chengdu.err</string>
|
||
<key>StandardOutPath</key>
|
||
<string>/tmp/socks-chengdu.log</string>
|
||
</dict>
|
||
</plist>
|
||
```
|
||
|
||
### 服务管理
|
||
|
||
```bash
|
||
# 查看状态
|
||
launchctl list | grep socks.chengdu
|
||
|
||
# 停止服务
|
||
launchctl unload ~/Library/LaunchAgents/com.socks.chengdu.plist
|
||
|
||
# 启动服务
|
||
launchctl load ~/Library/LaunchAgents/com.socks.chengdu.plist
|
||
|
||
# 查看日志
|
||
cat /tmp/socks-chengdu.err
|
||
|
||
# 验证隧道运行
|
||
lsof -i :1080
|
||
```
|
||
|
||
### 浏览器配置 (SwitchyOmega)
|
||
|
||
1. 安装 Chrome/Edge 扩展 SwitchyOmega
|
||
2. 新建情景模式 → 代理服务器 → SOCKS5 → `127.0.0.1:1080`
|
||
3. 自动切换规则:
|
||
- `*.pipexerp.com` → 国内代理
|
||
- `*.cn` → 国内代理
|
||
- 其他 → 直连
|
||
|
||
---
|
||
|
||
## SSH 跳板与反向隧道
|
||
|
||
当 Tailscale 直连不稳定或反向连接失败时,可通过公网服务器建立 SSH 跳板解决。
|
||
|
||
### 问题场景
|
||
|
||
**典型问题**:
|
||
- 本机可以 ping 通远程机器(如 cn-bj-lazycat)
|
||
- 本机可以 SSH 到远程机器
|
||
- 但远程机器无法 SSH 回本机(连接超时)
|
||
|
||
**原因分析**:
|
||
1. Tailscale 使用 DERP 中继,连接不稳定
|
||
2. NAT 穿透失败,反向连接无法建立
|
||
3. 网络延迟高(200-700ms+),TCP 连接容易超时
|
||
|
||
### 解决方案架构
|
||
|
||
```
|
||
远程机器 (cn-bj-lazycat)
|
||
↓ SSH
|
||
公网跳板 (Singapore)
|
||
↓ 反向隧道 localhost:2222
|
||
本机 (au-melbourne-coolbuy-dev)
|
||
```
|
||
|
||
**优势**:
|
||
- ✅ 利用稳定的公网服务器作为中继
|
||
- ✅ 绕过 Tailscale DERP 不稳定问题
|
||
- ✅ 自动重连,无需手动维护
|
||
- ✅ 安全:隧道只监听 localhost,需通过跳板访问
|
||
|
||
### 配置步骤
|
||
|
||
#### 步骤 1: 本机建立反向隧道
|
||
|
||
**手动启动**(测试用):
|
||
```bash
|
||
ssh -fN -R 2222:localhost:22 singapore
|
||
```
|
||
|
||
**配置自动重连服务**(推荐):
|
||
|
||
创建 `~/Library/LaunchAgents/com.ssh.singapore-tunnel.plist`:
|
||
|
||
```xml
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||
<plist version="1.0">
|
||
<dict>
|
||
<key>Label</key>
|
||
<string>com.ssh.singapore-tunnel</string>
|
||
<key>ProgramArguments</key>
|
||
<array>
|
||
<string>/usr/bin/ssh</string>
|
||
<string>-N</string>
|
||
<string>-R</string>
|
||
<string>2222:localhost:22</string>
|
||
<string>-o</string>
|
||
<string>ServerAliveInterval=60</string>
|
||
<string>-o</string>
|
||
<string>ServerAliveCountMax=3</string>
|
||
<string>-o</string>
|
||
<string>ExitOnForwardFailure=yes</string>
|
||
<string>singapore</string>
|
||
</array>
|
||
<key>RunAtLoad</key>
|
||
<true/>
|
||
<key>KeepAlive</key>
|
||
<true/>
|
||
<key>StandardErrorPath</key>
|
||
<string>/tmp/singapore-tunnel.err</string>
|
||
<key>StandardOutPath</key>
|
||
<string>/tmp/singapore-tunnel.log</string>
|
||
</dict>
|
||
</plist>
|
||
```
|
||
|
||
启动服务:
|
||
```bash
|
||
launchctl load ~/Library/LaunchAgents/com.ssh.singapore-tunnel.plist
|
||
launchctl list | grep singapore-tunnel
|
||
```
|
||
|
||
#### 步骤 2: 配置 SSH 密钥认证
|
||
|
||
**在跳板服务器上生成密钥**(如果还没有):
|
||
```bash
|
||
ssh singapore "ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N '' -C 'singapore-jump'"
|
||
```
|
||
|
||
**将跳板公钥添加到本机**:
|
||
```bash
|
||
ssh singapore "cat ~/.ssh/id_ed25519.pub" >> ~/.ssh/authorized_keys
|
||
```
|
||
|
||
**测试反向隧道**:
|
||
```bash
|
||
ssh singapore "ssh -p 2222 -o StrictHostKeyChecking=no <本机用户>@localhost 'hostname'"
|
||
```
|
||
|
||
#### 步骤 3: 远程机器配置
|
||
|
||
**传输跳板 SSH 密钥到远程机器**:
|
||
```bash
|
||
# 在远程机器上创建 SSH 目录
|
||
ssh <remote-server> "mkdir -p ~/.ssh && chmod 700 ~/.ssh"
|
||
|
||
# 传输密钥(通过管道避免 scp 密码问题)
|
||
cat ~/.ssh/singpore.pem | ssh <remote-server> "cat > ~/.ssh/singpore.pem && chmod 600 ~/.ssh/singpore.pem"
|
||
```
|
||
|
||
**配置 SSH config**(在远程机器上):
|
||
```bash
|
||
ssh <remote-server> "cat > ~/.ssh/config << 'EOFCONFIG'
|
||
# Singapore 跳板服务器
|
||
Host singapore
|
||
HostName 43.134.28.147
|
||
User ubuntu
|
||
IdentityFile ~/.ssh/singpore.pem
|
||
ServerAliveInterval 60
|
||
ServerAliveCountMax 3
|
||
|
||
# 通过 Singapore 访问目标机器
|
||
Host <target-host-alias>
|
||
HostName localhost
|
||
Port 2222
|
||
User <target-user>
|
||
ProxyJump singapore
|
||
ServerAliveInterval 60
|
||
ServerAliveCountMax 3
|
||
EOFCONFIG
|
||
chmod 600 ~/.ssh/config"
|
||
```
|
||
|
||
**配置远程机器的 SSH 密钥认证**:
|
||
```bash
|
||
# 在远程机器上生成密钥
|
||
ssh <remote-server> "ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N '' -C '<remote-name>'"
|
||
|
||
# 将远程机器公钥添加到本机
|
||
ssh <remote-server> "cat ~/.ssh/id_ed25519.pub" >> ~/.ssh/authorized_keys
|
||
```
|
||
|
||
#### 步骤 4: 测试连接
|
||
|
||
**从远程机器测试**:
|
||
```bash
|
||
# 连接到跳板
|
||
ssh <remote-server> "ssh singapore 'hostname'"
|
||
|
||
# 通过跳板连接到本机
|
||
ssh <remote-server> "ssh <target-host-alias> 'hostname && whoami'"
|
||
```
|
||
|
||
### 实际案例:cn-bj-lazycat 配置
|
||
|
||
**场景**:从 cn-bj-lazycat (懒猫算力仓) 稳定访问 Melbourne 开发机
|
||
|
||
**服务器信息**:
|
||
- **cn-bj-lazycat**: 100.115.52.119 / haiqing.heiyu.space
|
||
- 系统: Debian GNU/Linux (Kernel 6.5.0)
|
||
- 用户: root(密码: zhiyun2026)
|
||
- 用途: 北京算力仓服务器(懒猫微服)
|
||
- **Melbourne**: au-melbourne-coolbuy-dev (100.112.161.78)
|
||
- 系统: macOS Darwin 25.2.0
|
||
- 用户: coolbuy-dev
|
||
- 用途: 澳洲开发电脑
|
||
|
||
**配置详情**:
|
||
|
||
```bash
|
||
# 1. Melbourne 本机 - 反向隧道已自动运行
|
||
launchctl list | grep singapore-tunnel
|
||
# 输出: 10349 0 com.ssh.singapore-tunnel
|
||
|
||
# 2. cn-bj-lazycat 上的完整配置
|
||
ssh root@haiqing.heiyu.space # 密码: zhiyun2026
|
||
|
||
# SSH config 已配置:
|
||
Host singapore
|
||
HostName 43.134.28.147
|
||
User ubuntu
|
||
IdentityFile ~/.ssh/singpore.pem
|
||
ServerAliveInterval 60
|
||
ServerAliveCountMax 3
|
||
|
||
Host au-melbourne au-dev melbourne
|
||
HostName localhost
|
||
Port 2222
|
||
User coolbuy-dev
|
||
ProxyJump singapore
|
||
ServerAliveInterval 60
|
||
ServerAliveCountMax 3
|
||
|
||
# 3. 使用方式(支持 3 个别名)
|
||
ssh melbourne "hostname && whoami"
|
||
ssh au-melbourne "ls -la"
|
||
ssh au-dev "uname -a"
|
||
|
||
# 文件传输
|
||
scp file.txt melbourne:/tmp/
|
||
scp melbourne:/path/to/file ./
|
||
|
||
# 4. 验证连接
|
||
ssh melbourne 'echo "✅ 连接成功!当前在 $(hostname)"'
|
||
```
|
||
|
||
**连接测试结果**:
|
||
```bash
|
||
# 所有别名测试通过
|
||
ssh au-melbourne # ✅ 成功
|
||
ssh melbourne # ✅ 成功
|
||
ssh au-dev # ✅ 成功
|
||
```
|
||
|
||
### 管理命令
|
||
|
||
**本机管理反向隧道**:
|
||
```bash
|
||
# 查看状态
|
||
launchctl list | grep singapore-tunnel
|
||
ps aux | grep "ssh.*singapore"
|
||
|
||
# 重启服务
|
||
launchctl unload ~/Library/LaunchAgents/com.ssh.singapore-tunnel.plist
|
||
launchctl load ~/Library/LaunchAgents/com.ssh.singapore-tunnel.plist
|
||
|
||
# 查看日志
|
||
cat /tmp/singapore-tunnel.err
|
||
|
||
# 验证隧道端口
|
||
ssh singapore "netstat -tlnp | grep :2222"
|
||
```
|
||
|
||
**远程机器管理**:
|
||
```bash
|
||
# 测试连接质量
|
||
ssh <target-host> "time echo 'test'"
|
||
|
||
# 查看 SSH 配置
|
||
ssh <remote-server> "cat ~/.ssh/config"
|
||
|
||
# 测试 ProxyJump
|
||
ssh <remote-server> "ssh -v <target-host> 'hostname' 2>&1 | grep -i 'proxy\|jump'"
|
||
```
|
||
|
||
### 故障排查
|
||
|
||
| 问题 | 可能原因 | 解决方案 |
|
||
|------|---------|----------|
|
||
| 反向隧道断开 | 网络波动、服务器重启 | 检查 LaunchAgent 服务是否运行 |
|
||
| 认证失败 | 密钥权限错误、公钥未添加 | 确保密钥权限 600,公钥在 authorized_keys |
|
||
| 连接超时 | 跳板服务器网络问题 | 测试到跳板的连接:`ping singapore` |
|
||
| ProxyJump 失败 | SSH config 语法错误 | 检查 config 文件格式和缩进 |
|
||
|
||
### 安全注意事项
|
||
|
||
- ✅ 反向隧道只监听 localhost,外部无法直接访问
|
||
- ✅ SSH 密钥权限必须是 600
|
||
- ✅ 定期检查 authorized_keys,移除不需要的密钥
|
||
- ✅ 跳板服务器应启用 fail2ban 等安全措施
|
||
- ⚠️ 避免在公共网络下使用密码认证,优先使用密钥
|
||
|
||
---
|
||
|
||
## MCP 配置(快速参考)
|
||
|
||
**配置文件**: `~/.claude/.mcp.json`
|
||
|
||
```json
|
||
{
|
||
"mcpServers": {
|
||
"ai-proj": {
|
||
"type": "stdio",
|
||
"command": "node",
|
||
"args": ["/Users/coolbuy-dev/coding/new-ai-proj/mcp-task-bridge/dist/index.js"],
|
||
"env": {
|
||
"TASK_API_BASE": "https://ai.pipexerp.com/api/v1",
|
||
"TASK_API_TOKEN": "aiproj_pk_2ecf8f8728b70afd4420af3875f4f7505c9fe8231a4771972b0f385aa1c75099",
|
||
"NODE_ENV": "production"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**前置条件**: `cd mcp-task-bridge && npm run build`
|
||
|
||
**详细说明**: 见 [mcp-config.md](mcp-config.md)
|
||
|
||
---
|
||
|
||
## OpenClaw 配置(懒猫算力仓)
|
||
|
||
OpenClaw 运行在懒猫算力仓的容器环境中,需要特殊配置才能访问 skills。
|
||
|
||
### 问题与解决方案
|
||
|
||
**问题**:OpenClaw 运行在容器内,无法访问宿主机的 `~/.claude/skills/` 目录
|
||
|
||
**原因**:容器和宿主机文件系统隔离,skills 目录未挂载到容器内
|
||
|
||
**解决方案**:将 skills 复制到容器内的标准路径
|
||
|
||
### 配置步骤
|
||
|
||
#### 1. 连接到懒猫算力仓
|
||
|
||
```bash
|
||
# 添加 SSH 配置(首次配置)
|
||
cat >> ~/.ssh/config << 'EOF'
|
||
Host cn-bj-lazycat lazycat
|
||
HostName haiqing.heiyu.space
|
||
User root
|
||
IdentityFile ~/.ssh/id_lazycat
|
||
ServerAliveInterval 60
|
||
ServerAliveCountMax 3
|
||
EOF
|
||
|
||
# 生成并配置 SSH 密钥
|
||
ssh-keygen -t ed25519 -f ~/.ssh/id_lazycat -N "" -C "au-dev-to-lazycat"
|
||
ssh-copy-id -i ~/.ssh/id_lazycat root@haiqing.heiyu.space
|
||
# 密码: zhiyun2026
|
||
|
||
# 测试连接
|
||
ssh lazycat "whoami && hostname"
|
||
```
|
||
|
||
#### 2. 查找 OpenClaw 容器
|
||
|
||
```bash
|
||
# 查看运行的容器
|
||
ssh lazycat "/lzcsys/bin/lzc-docker ps --format 'table {{.ID}}\t{{.Names}}'"
|
||
|
||
# 找到 OpenClaw 容器 ID(通常是固定的)
|
||
CONTAINER_ID="5f3bf33e090b" # 懒猫算力仓的 OpenClaw 容器
|
||
```
|
||
|
||
#### 3. 复制 skills 到容器内
|
||
|
||
```bash
|
||
# 在容器内创建目录
|
||
ssh lazycat "/lzcsys/bin/lzc-docker exec $CONTAINER_ID mkdir -p /root/.claude/skills"
|
||
|
||
# 复制 skills(从宿主机到容器)
|
||
ssh lazycat "/lzcsys/bin/lzc-docker cp /root/.claude/skills/. $CONTAINER_ID:/root/.claude/skills/"
|
||
|
||
# 验证复制结果
|
||
ssh lazycat "/lzcsys/bin/lzc-docker exec $CONTAINER_ID ls -la /root/.claude/skills/ | head -20"
|
||
ssh lazycat "/lzcsys/bin/lzc-docker exec $CONTAINER_ID ls /root/.claude/skills/ | wc -l"
|
||
```
|
||
|
||
#### 4. 重启 OpenClaw
|
||
|
||
```bash
|
||
# 重启容器使配置生效
|
||
ssh lazycat "/lzcsys/bin/lzc-docker restart $CONTAINER_ID"
|
||
|
||
# 检查容器状态
|
||
ssh lazycat "/lzcsys/bin/lzc-docker ps | grep $CONTAINER_ID"
|
||
```
|
||
|
||
### 更新 Skills
|
||
|
||
当本地更新了 skills 后,需要重新同步到懒猫算力仓:
|
||
|
||
```bash
|
||
# 步骤 1: 同步 skills 到宿主机
|
||
ssh lazycat "mkdir -p ~/.claude"
|
||
cd ~/.dotfiles
|
||
tar -czf - claude-skills/ | ssh lazycat "cd ~/.claude && rm -rf skills && tar -xzf - && mv claude-skills skills"
|
||
|
||
# 步骤 2: 复制到 OpenClaw 容器
|
||
ssh lazycat "/lzcsys/bin/lzc-docker exec 5f3bf33e090b rm -rf /root/.claude/skills"
|
||
ssh lazycat "/lzcsys/bin/lzc-docker cp /root/.claude/skills/. 5f3bf33e090b:/root/.claude/skills/"
|
||
|
||
# 步骤 3: 重启 OpenClaw
|
||
ssh lazycat "/lzcsys/bin/lzc-docker restart 5f3bf33e090b"
|
||
```
|
||
|
||
### 验证配置
|
||
|
||
```bash
|
||
# 检查容器内的 skills 数量
|
||
ssh lazycat "/lzcsys/bin/lzc-docker exec 5f3bf33e090b ls /root/.claude/skills/ | wc -l"
|
||
# 应该显示: 41
|
||
|
||
# 检查特定 skill 内容
|
||
ssh lazycat "/lzcsys/bin/lzc-docker exec 5f3bf33e090b cat /root/.claude/skills/ai-proj/SKILL.md | head -30"
|
||
|
||
# 检查 OpenClaw 配置
|
||
ssh lazycat "/lzcsys/bin/lzc-docker exec 5f3bf33e090b cat /home/node/.openclaw/openclaw.json | grep -A 3 workspace"
|
||
```
|
||
|
||
### 懒猫算力仓环境信息
|
||
|
||
| 项目 | 信息 |
|
||
|------|------|
|
||
| **宿主机** | Debian GNU/Linux (Kernel 6.5.0) |
|
||
| **容器 ID** | 5f3bf33e090b (固定) |
|
||
| **Docker 命令** | `/lzcsys/bin/lzc-docker` (懒猫专用) |
|
||
| **OpenClaw 配置** | `/home/node/.openclaw/openclaw.json` |
|
||
| **Skills 路径** | `/root/.claude/skills/` (容器内) |
|
||
| **宿主 Skills** | `/root/.claude/skills/` (宿主机) |
|
||
|
||
### 自动化脚本
|
||
|
||
创建 `~/.local/bin/sync-skills-to-lazycat.sh`:
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
# 同步 skills 到懒猫算力仓 OpenClaw
|
||
|
||
set -e
|
||
|
||
echo "=== 同步 skills 到懒猫算力仓 ==="
|
||
|
||
# 1. 同步到宿主机
|
||
echo "步骤 1: 同步到宿主机..."
|
||
cd ~/.dotfiles
|
||
tar -czf - claude-skills/ | ssh lazycat "cd ~/.claude && rm -rf skills && tar -xzf - && mv claude-skills skills"
|
||
|
||
# 2. 复制到容器
|
||
echo "步骤 2: 复制到 OpenClaw 容器..."
|
||
ssh lazycat "/lzcsys/bin/lzc-docker exec 5f3bf33e090b rm -rf /root/.claude/skills || true"
|
||
ssh lazycat "/lzcsys/bin/lzc-docker exec 5f3bf33e090b mkdir -p /root/.claude/skills"
|
||
ssh lazycat "/lzcsys/bin/lzc-docker cp /root/.claude/skills/. 5f3bf33e090b:/root/.claude/skills/"
|
||
|
||
# 3. 验证
|
||
echo "步骤 3: 验证..."
|
||
SKILL_COUNT=$(ssh lazycat "/lzcsys/bin/lzc-docker exec 5f3bf33e090b ls /root/.claude/skills/ | wc -l")
|
||
echo "✅ 同步完成!共 $SKILL_COUNT 个 skills"
|
||
|
||
# 4. 重启 OpenClaw
|
||
echo "步骤 4: 重启 OpenClaw..."
|
||
ssh lazycat "/lzcsys/bin/lzc-docker restart 5f3bf33e090b"
|
||
echo "✅ OpenClaw 已重启"
|
||
```
|
||
|
||
使用方法:
|
||
```bash
|
||
chmod +x ~/.local/bin/sync-skills-to-lazycat.sh
|
||
sync-skills-to-lazycat.sh
|
||
```
|
||
|
||
### Agent-Swarm 多智能体技能部署
|
||
|
||
**agent-swarm** 是基于 OpenAI Swarm 设计模式的多智能体协作系统,用于复杂开发任务的智能分解与协调。
|
||
|
||
#### 技能概述
|
||
|
||
| 项目 | 信息 |
|
||
|------|------|
|
||
| **技能名称** | agent-swarm |
|
||
| **版本** | 1.0.0 |
|
||
| **文档大小** | 9.1KB (450+ 行) |
|
||
| **预定义 Agent** | 5 个 (Architect, Coder, Tester, Reviewer, Deployer) |
|
||
| **部署日期** | 2026-02-16 |
|
||
| **部署位置** | 懒猫算力仓 OpenClaw 容器 |
|
||
|
||
#### 快速部署
|
||
|
||
**从本地部署到懒猫算力仓**:
|
||
|
||
```bash
|
||
# 1. 确保本地有 agent-swarm 技能
|
||
ls ~/.claude/skills/agent-swarm/
|
||
# skill.yaml SKILL.md README.md
|
||
|
||
# 2. 打包技能
|
||
cd /tmp
|
||
tar -czf agent-swarm-skill.tar.gz -C ~/.claude/skills agent-swarm
|
||
|
||
# 3. 上传到懒猫算力仓宿主机
|
||
sshpass -p 'zhiyun2026' scp -o StrictHostKeyChecking=no \
|
||
agent-swarm-skill.tar.gz root@haiqing.heiyu.space:/tmp/
|
||
|
||
# 4. 在宿主机解压并部署到容器
|
||
sshpass -p 'zhiyun2026' ssh -o StrictHostKeyChecking=no root@haiqing.heiyu.space "
|
||
cd /tmp && tar -xzf agent-swarm-skill.tar.gz && \
|
||
cp -r agent-swarm /root/.claude/skills/ && \
|
||
/lzcsys/bin/lzc-docker cp /root/.claude/skills/agent-swarm 5f3bf33e090b:/root/.claude/skills/
|
||
"
|
||
|
||
# 5. 重启 OpenClaw
|
||
sshpass -p 'zhiyun2026' ssh -o StrictHostKeyChecking=no root@haiqing.heiyu.space \
|
||
"/lzcsys/bin/lzc-docker restart 5f3bf33e090b"
|
||
|
||
# 6. 验证安装
|
||
sshpass -p 'zhiyun2026' ssh -o StrictHostKeyChecking=no root@haiqing.heiyu.space \
|
||
"/lzcsys/bin/lzc-docker exec 5f3bf33e090b ls /root/.claude/skills/ | wc -l"
|
||
# 应该显示: 43 (42 + agent-swarm)
|
||
```
|
||
|
||
#### 使用方法
|
||
|
||
在飞书中 @OpenClaw 使用以下命令:
|
||
|
||
```bash
|
||
# 查看所有 Agent
|
||
/swarm agents
|
||
|
||
# 启动完整开发工作流(从架构设计开始)
|
||
/swarm start "在 new-ai-proj 中实现任务批量删除功能"
|
||
|
||
# 从特定 Agent 开始
|
||
/swarm coder "修复 backend/handlers/task_handler.go 的空指针 bug"
|
||
|
||
# 并行执行多个任务
|
||
/swarm parallel "实现后端API" "实现前端UI" "编写测试"
|
||
|
||
# 查看执行轨迹
|
||
/swarm trace
|
||
|
||
# 显示配置
|
||
/swarm config
|
||
```
|
||
|
||
#### Agent 工作流
|
||
|
||
```
|
||
用户请求 → Architect (需求分析、架构设计)
|
||
↓ handoff
|
||
Coder (编写代码、实现功能)
|
||
↓ handoff
|
||
Tester (编写测试、运行测试)
|
||
↓ handoff
|
||
Reviewer (代码审查、安全检查)
|
||
↓ handoff
|
||
Deployer (部署服务、监控上线)
|
||
↓
|
||
完成 ✅
|
||
```
|
||
|
||
#### 5 个预定义 Agent
|
||
|
||
| Agent | 职责 | Tools | Handoff to |
|
||
|-------|------|-------|------------|
|
||
| **Architect** | 需求分析、架构设计、技术选型 | Read, Grep, Glob | Coder, Reviewer |
|
||
| **Coder** | 编写代码、实现功能、Bug 修复 | Edit, Write, Bash | Tester, Architect |
|
||
| **Tester** | 编写测试、运行测试、验证功能 | Bash, Write | Deployer, Coder |
|
||
| **Reviewer** | 代码审查、安全检查、质量把关 | Read, Grep | Coder, Deployer |
|
||
| **Deployer** | 部署服务、监控上线、健康检查 | Bash, SSH | Monitor, Coder |
|
||
|
||
#### 配置自定义 Agent (可选)
|
||
|
||
在项目根目录创建 `swarm.yaml`:
|
||
|
||
```yaml
|
||
agents:
|
||
architect:
|
||
instructions: |
|
||
你是系统架构师,专注于 Go + Vue.js 技术栈。
|
||
遵循 RESTful API 设计原则。
|
||
max_turns: 5
|
||
|
||
coder:
|
||
instructions: |
|
||
你是全栈工程师。
|
||
编写清晰、简洁、高性能的代码。
|
||
max_turns: 10
|
||
|
||
context_variables:
|
||
project_root: /Users/coolbuy-dev/coding/new-ai-proj
|
||
backend_lang: Go 1.21
|
||
frontend_framework: Vue 3
|
||
database: PostgreSQL 15
|
||
```
|
||
|
||
#### 实际应用场景
|
||
|
||
**场景 1: 新功能开发**
|
||
```bash
|
||
/swarm start "为 AI-Proj 实现需求批量导出为 Excel 功能,支持自定义字段和筛选条件"
|
||
```
|
||
自动执行:Architect 设计 → Coder 实现 → Tester 测试 → Reviewer 审查 → Deployer 部署
|
||
|
||
**场景 2: Bug 修复 + 性能优化**
|
||
```bash
|
||
/swarm coder "优化任务详情页加载性能,从 3s 降到 300ms 以内"
|
||
```
|
||
自动执行:Coder 优化 → Tester 验证 → Deployer 灰度发布
|
||
|
||
**场景 3: 代码审查**
|
||
```bash
|
||
/swarm reviewer "审查 PR #123 的代码质量和安全性"
|
||
```
|
||
自动执行:Reviewer 分析 → Coder 修改 → Deployer 部署
|
||
|
||
#### 参考资料
|
||
|
||
- **完整文档**: 容器内 `/root/.claude/skills/agent-swarm/SKILL.md`
|
||
- **OpenAI Swarm**: https://github.com/openai/swarm
|
||
- **部署日期**: 2026-02-16
|
||
- **当前技能总数**: 43 个
|
||
|
||
### MCP 服务器配置
|
||
|
||
OpenClaw 支持 MCP (Model Context Protocol),可以连接 ai-proj 等服务。
|
||
|
||
#### 配置位置
|
||
|
||
容器内配置文件:`/root/.claude/.mcp.json`
|
||
|
||
#### 配置步骤
|
||
|
||
**1. 部署 mcp-task-bridge**
|
||
|
||
```bash
|
||
# 从本地传输 mcp-task-bridge(包含编译产物和依赖)
|
||
cd /Users/coolbuy-dev/coding/new-ai-proj
|
||
tar -czf - mcp-task-bridge/dist mcp-task-bridge/package.json mcp-task-bridge/node_modules | \
|
||
ssh lazycat "cd /root && tar -xzf -"
|
||
|
||
# 复制到容器内
|
||
ssh lazycat "/lzcsys/bin/lzc-docker cp /root/mcp-task-bridge 5f3bf33e090b:/root/"
|
||
|
||
# 验证
|
||
ssh lazycat "/lzcsys/bin/lzc-docker exec 5f3bf33e090b ls -la /root/mcp-task-bridge/"
|
||
ssh lazycat "/lzcsys/bin/lzc-docker exec 5f3bf33e090b node --version"
|
||
```
|
||
|
||
**2. 创建 MCP 配置文件**
|
||
|
||
```bash
|
||
# 创建配置文件
|
||
cat > /tmp/mcp-config.json << 'EOF'
|
||
{
|
||
"mcpServers": {
|
||
"ai-proj-prod": {
|
||
"type": "stdio",
|
||
"command": "node",
|
||
"args": ["/root/mcp-task-bridge/dist/index.js"],
|
||
"env": {
|
||
"NODE_ENV": "production",
|
||
"TASK_API_BASE": "https://ai.pipexerp.com/api/v1",
|
||
"TASK_API_TOKEN": "aiproj_pk_2ecf8f8728b70afd4420af3875f4f7505c9fe8231a4771972b0f385aa1c75099",
|
||
"DEV_LOGIN_USERNAME": "qiudl",
|
||
"MCP_SERVER_NAME": "ai-proj-prod"
|
||
}
|
||
},
|
||
"ai-proj-staging": {
|
||
"type": "stdio",
|
||
"command": "node",
|
||
"args": ["/root/mcp-task-bridge/dist/index.js"],
|
||
"env": {
|
||
"NODE_ENV": "staging",
|
||
"TASK_API_BASE": "https://staging.ai.pipexerp.com/api/v1",
|
||
"TASK_API_TOKEN": "aiproj_pk_ff1ee5478268fd8fe3f9eeb7dd28c8a35f32026b3a3846715f0a40cad542bdd6",
|
||
"DEV_LOGIN_USERNAME": "qiudl",
|
||
"MCP_SERVER_NAME": "ai-proj-staging"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
EOF
|
||
|
||
# 复制到容器内
|
||
scp /tmp/mcp-config.json lazycat:/tmp/
|
||
ssh lazycat "/lzcsys/bin/lzc-docker cp /tmp/mcp-config.json 5f3bf33e090b:/root/.claude/.mcp.json"
|
||
|
||
# 验证配置
|
||
ssh lazycat "/lzcsys/bin/lzc-docker exec 5f3bf33e090b cat /root/.claude/.mcp.json" | jq .
|
||
```
|
||
|
||
**3. 重启 OpenClaw**
|
||
|
||
```bash
|
||
ssh lazycat "/lzcsys/bin/lzc-docker restart 5f3bf33e090b"
|
||
```
|
||
|
||
#### 测试 MCP 连接
|
||
|
||
```bash
|
||
# 测试 mcp-task-bridge 可执行性
|
||
ssh lazycat "/lzcsys/bin/lzc-docker exec 5f3bf33e090b node /root/mcp-task-bridge/dist/index.js --version"
|
||
|
||
# 检查配置文件
|
||
ssh lazycat "/lzcsys/bin/lzc-docker exec 5f3bf33e090b cat /root/.claude/.mcp.json"
|
||
```
|
||
|
||
#### 更新 MCP 配置
|
||
|
||
当 mcp-task-bridge 或 API token 更新时:
|
||
|
||
```bash
|
||
# 1. 更新 mcp-task-bridge
|
||
cd /Users/coolbuy-dev/coding/new-ai-proj/mcp-task-bridge
|
||
npm run build
|
||
cd /Users/coolbuy-dev/coding/new-ai-proj
|
||
tar -czf - mcp-task-bridge/dist | ssh lazycat "cd /root && tar -xzf -"
|
||
ssh lazycat "/lzcsys/bin/lzc-docker cp /root/mcp-task-bridge/dist 5f3bf33e090b:/root/mcp-task-bridge/"
|
||
|
||
# 2. 更新配置文件(重复上面的步骤 2)
|
||
|
||
# 3. 重启 OpenClaw
|
||
ssh lazycat "/lzcsys/bin/lzc-docker restart 5f3bf33e090b"
|
||
```
|
||
|
||
#### 可用的 MCP 服务器
|
||
|
||
| MCP 服务器 | 环境 | API 地址 | 用途 |
|
||
|-----------|------|----------|------|
|
||
| ai-proj-prod | 生产 | https://ai.pipexerp.com/api/v1 | 生产数据管理 |
|
||
| ai-proj-staging | 测试 | https://staging.ai.pipexerp.com/api/v1 | 测试环境验证 |
|
||
|
||
#### 故障排查
|
||
|
||
| 问题 | 可能原因 | 解决方案 |
|
||
|------|---------|----------|
|
||
| MCP 连接失败 | node 命令不存在 | 检查容器内 node: `docker exec ... which node` |
|
||
| Token 认证失败 | API token 过期或错误 | 更新 .mcp.json 中的 TASK_API_TOKEN |
|
||
| 找不到模块 | node_modules 缺失 | 重新传输完整的 mcp-task-bridge |
|
||
| 网络连接超时 | 容器网络问题 | 检查容器网络:`docker exec ... curl -I https://ai.pipexerp.com` |
|
||
|
||
---
|
||
|
||
## OpenClaw 特殊说明
|
||
|
||
### MCP 协议不兼容
|
||
|
||
**重要发现**:OpenClaw **不支持**标准的 MCP (Model Context Protocol) 配置。
|
||
|
||
- ❌ 不识别 `~/.claude/.mcp.json`
|
||
- ❌ 不支持 `openclaw.json` 中的 `mcpServers` 字段
|
||
- ✅ 使用自己的 **Plugins** 和 **Skills** 系统
|
||
|
||
### OpenClaw 工具集成方式
|
||
|
||
| 集成方式 | 说明 | 适用场景 |
|
||
|---------|------|----------|
|
||
| **Plugins(插件)** | TypeScript 模块,在 Gateway 进程内运行 | 复杂工具、需要注册 RPC 方法 |
|
||
| **Skills(技能)** | Markdown + YAML frontmatter,指导 AI 使用工具 | 调用外部 API、CLI 工具 |
|
||
| **Web Tools** | 网络工具集成 | 网页操作、浏览器自动化 |
|
||
|
||
### ai-proj 在 OpenClaw 上的配置
|
||
|
||
由于 OpenClaw 不支持 MCP,ai-proj 功能通过 **Skill + REST API 调用**实现:
|
||
|
||
**Skill 位置**:`/root/.claude/skills/ai-proj/SKILL.md`(容器内)
|
||
|
||
**工作原理**:
|
||
1. Skill 文件提供 API 调用示例(curl 命令)
|
||
2. OpenClaw AI 根据 skill 指导执行 bash 命令
|
||
3. 直接调用 ai-proj REST API,无需 MCP bridge
|
||
|
||
**示例操作**:
|
||
|
||
```bash
|
||
# 在 OpenClaw 容器内执行
|
||
# 列出项目
|
||
curl -s -H "Authorization: Bearer aiproj_pk_2ecf8f8728b70afd4420af3875f4f7505c9fe8231a4771972b0f385aa1c75099" \
|
||
"https://ai.pipexerp.com/api/v1/projects?page=1&page_size=10" | jq ".data.data[] | {id, name}"
|
||
|
||
# 创建任务
|
||
curl -s -X POST \
|
||
-H "Authorization: Bearer aiproj_pk_2ecf8f8728b70afd4420af3875f4f7505c9fe8231a4771972b0f385aa1c75099" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"title":"测试任务","project_id":161}' \
|
||
"https://ai.pipexerp.com/api/v1/tasks" | jq .
|
||
```
|
||
|
||
### OpenClaw 容器 SSH 访问本机(au-dev)
|
||
|
||
OpenClaw 容器可以通过 Singapore 跳板的反向隧道 SSH 到澳洲开发机(au-dev)。
|
||
|
||
**链路架构**:
|
||
```
|
||
OpenClaw容器(node@5f3bf33e090b)
|
||
→ ssh au-dev
|
||
→ ProxyJump singapore(43.134.28.147)
|
||
→ 反向隧道 localhost:2222
|
||
→ 本机(coolbuy-dev@Coolbuy-dev.local)
|
||
```
|
||
|
||
**前置条件**:
|
||
1. 本机反向隧道服务运行中:`launchctl list | grep singapore-tunnel`
|
||
2. Singapore 端口 2222 监听中:`ssh singapore "ss -tlnp | grep :2222"`
|
||
|
||
**容器内 SSH 配置**(已配置,路径 `/home/node/.ssh/`):
|
||
|
||
| 文件 | 说明 | 所有者 |
|
||
|------|------|--------|
|
||
| `id_ed25519` | 容器 SSH 私钥 | node:node |
|
||
| `id_ed25519.pub` | 公钥 (`openclaw@iamxiaoe`) | node:node |
|
||
| `singpore.pem` | Singapore 跳板密钥 | node:node |
|
||
| `config` | SSH 配置(含 ProxyJump) | node:node |
|
||
|
||
**容器内 SSH config 内容**:
|
||
```
|
||
Host lazycat cn-bj-lazycat
|
||
HostName 172.28.3.1
|
||
User root
|
||
StrictHostKeyChecking no
|
||
ServerAliveInterval 60
|
||
ServerAliveCountMax 3
|
||
|
||
Host singapore
|
||
HostName 43.134.28.147
|
||
User ubuntu
|
||
IdentityFile /home/node/.ssh/singpore.pem
|
||
StrictHostKeyChecking no
|
||
ServerAliveInterval 60
|
||
ServerAliveCountMax 3
|
||
|
||
Host au-dev melbourne
|
||
HostName localhost
|
||
Port 2222
|
||
User coolbuy-dev
|
||
ProxyJump singapore
|
||
StrictHostKeyChecking no
|
||
ServerAliveInterval 60
|
||
ServerAliveCountMax 3
|
||
```
|
||
|
||
**authorized_keys 配置**:
|
||
|
||
| 目标机器 | 需包含的公钥 |
|
||
|---------|-------------|
|
||
| au-dev 本机 `~/.ssh/authorized_keys` | `openclaw@iamxiaoe` + `root@cn-bj-lazycat` |
|
||
| 宿主机 `/root/.ssh/authorized_keys` | `openclaw@iamxiaoe` |
|
||
|
||
**使用方式(在容器内以 node 用户执行)**:
|
||
```bash
|
||
# 连接宿主机(通过 Docker 网关 172.28.3.1)
|
||
ssh lazycat 'hostname && whoami'
|
||
ssh cn-bj-lazycat '/lzcsys/bin/lzc-docker ps'
|
||
|
||
# 连接 au-dev(通过 Singapore 反向隧道)
|
||
ssh au-dev 'hostname && whoami'
|
||
ssh melbourne 'cd /Users/coolbuy-dev/coding/new-ai-proj && git log --oneline -5'
|
||
|
||
# 传输文件
|
||
scp au-dev:/path/to/file /tmp/
|
||
scp /tmp/file lazycat:/tmp/
|
||
```
|
||
|
||
**重新配置(容器重建后)**:
|
||
```bash
|
||
LAZYCAT="sshpass -p 'zhiyun2026' ssh -o StrictHostKeyChecking=no -o PubkeyAuthentication=no root@haiqing.heiyu.space"
|
||
|
||
# 1. 复制 Singapore 密钥到容器
|
||
$LAZYCAT "/lzcsys/bin/lzc-docker cp /root/.ssh/singpore.pem 5f3bf33e090b:/home/node/.ssh/singpore.pem"
|
||
|
||
# 2. 将容器公钥加入宿主机 authorized_keys
|
||
$LAZYCAT "grep -q 'openclaw@iamxiaoe' ~/.ssh/authorized_keys || echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJsGNfvdmA4wCs57O9+tgbSJovDSO5esDyefVJHIoBXg openclaw@iamxiaoe' >> ~/.ssh/authorized_keys"
|
||
|
||
# 3. 创建 SSH config(含宿主机 + Singapore + au-dev)
|
||
$LAZYCAT "/lzcsys/bin/lzc-docker exec 5f3bf33e090b sh -c 'cat > /home/node/.ssh/config << EOF
|
||
Host lazycat cn-bj-lazycat
|
||
HostName 172.28.3.1
|
||
User root
|
||
StrictHostKeyChecking no
|
||
ServerAliveInterval 60
|
||
ServerAliveCountMax 3
|
||
|
||
Host singapore
|
||
HostName 43.134.28.147
|
||
User ubuntu
|
||
IdentityFile /home/node/.ssh/singpore.pem
|
||
StrictHostKeyChecking no
|
||
ServerAliveInterval 60
|
||
ServerAliveCountMax 3
|
||
|
||
Host au-dev melbourne
|
||
HostName localhost
|
||
Port 2222
|
||
User coolbuy-dev
|
||
ProxyJump singapore
|
||
StrictHostKeyChecking no
|
||
ServerAliveInterval 60
|
||
ServerAliveCountMax 3
|
||
EOF'"
|
||
|
||
# 4. 修复权限
|
||
$LAZYCAT "/lzcsys/bin/lzc-docker exec 5f3bf33e090b sh -c 'chown -R node:node /home/node/.ssh && chmod 700 /home/node/.ssh && chmod 600 /home/node/.ssh/id_ed25519 /home/node/.ssh/config /home/node/.ssh/singpore.pem'"
|
||
|
||
# 5. 测试宿主机连接
|
||
$LAZYCAT "/lzcsys/bin/lzc-docker exec -u node 5f3bf33e090b ssh -o ConnectTimeout=10 lazycat 'hostname && whoami'"
|
||
|
||
# 6. 测试 au-dev 连接
|
||
$LAZYCAT "/lzcsys/bin/lzc-docker exec -u node 5f3bf33e090b ssh -o ConnectTimeout=15 au-dev 'hostname && whoami'"
|
||
```
|
||
|
||
**故障排查**:
|
||
|
||
| 问题 | 可能原因 | 解决方案 |
|
||
|------|---------|----------|
|
||
| Permission denied (publickey) to au-dev | 公钥未加入本机 authorized_keys | 将 `openclaw@iamxiaoe` 公钥加入本机 `~/.ssh/authorized_keys` |
|
||
| Permission denied (publickey) to lazycat | 公钥未加入宿主机 authorized_keys | 将 `openclaw@iamxiaoe` 公钥加入宿主机 `/root/.ssh/authorized_keys` |
|
||
| Connection timed out (au-dev) | 反向隧道断开 | 检查本机 `launchctl list \| grep singapore-tunnel`,重启服务 |
|
||
| Could not resolve hostname | SSH config 权限错误或缺失 | 检查 `/home/node/.ssh/config` 权限为 600,所有者为 node |
|
||
| ProxyJump 失败 | singpore.pem 缺失或权限错误 | 重新从宿主机复制密钥到容器 |
|
||
| 容器连宿主机失败 | Docker 网关 IP 变化 | 容器内 `ip route \| grep default` 查看网关,更新 SSH config |
|
||
|
||
### 文档参考
|
||
|
||
- **OpenClaw 插件系统**:https://docs.openclaw.ai/tools/plugin.md
|
||
- **OpenClaw Skills**:https://docs.openclaw.ai/tools/skills.md
|
||
- **OpenClaw 配置**:https://docs.openclaw.ai/cli/config
|