44 KiB
name, description
| name | description |
|---|---|
| ops-tools | DevOps 运维工具。用于 SSH 连接服务器、部署应用、健康检查、日志查看、服务重启和系统监控。当用户提到服务器操作、部署、运维、Jenkins、Gitea、ai-proj 相关任务时自动激活。 |
DevOps Skill
子文档索引
| 文档 | 说明 |
|---|---|
| ai-proj-deploy.md | AI-Proj 部署流程 |
| coolbuy-deploy.md | Coolbuy-PaaS 部署流程 |
| db-backup.md | ⚠️ 数据库备份与恢复(迁移前必读) |
| mcp-config.md | Claude Code MCP 配置 |
| incidents.md | 重大事件记录 |
⚠️ 重要提醒:执行任何数据库 UPDATE/DELETE/ALTER 或数据迁移操作前,必须先备份! 详见 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 快捷连接
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 密钥:
# 查看可用密钥
ssh adelaide-dev-mini "ls ~/.ssh/*.pem"
# 可用密钥列表:
# - singpore.pem → Singapore staging 服务器
# - tools_ai_proj.pem → 生产服务器
# - tools.pem → Jenkins/Gitea 服务器
# - coolbuy3.pem → Coolbuy 相关服务器
密钥同步到本机:
# 下载缺失的密钥
ssh adelaide-dev-mini "cat ~/.ssh/singpore.pem" > ~/.ssh/singpore.pem
chmod 600 ~/.ssh/singpore.pem
凭据配置
凭据存储在 ~/.config/devops/credentials.env(权限 600):
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 操作统一使用
teaCLI,详见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 |
常用命令
系统状态
# 服务器概况
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 操作
# 健康检查
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
思源笔记操作
# 查看容器状态
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
数据库操作(迁移前必备份)
# ⚠️ 迁移前备份(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
Gitea 操作
# 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 操作
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(离开前)
git add -A
git commit -m "WIP: sync from $(hostname)" || echo "Nothing to commit"
git push origin $(git branch --show-current)
sync-arrive(到达后)
git fetch origin
git pull origin $(git branch --show-current)
sync-merge(合并 WIP 提交)
git reset --soft HEAD~<WIP数量>
git add -A
git commit -m "feat: 实际功能描述"
git push origin $(git branch --show-current) --force-with-lease
故障排查
服务无响应
systemctl status <service>
journalctl -u <service> --since "5 minutes ago"
netstat -tlnp | grep <port>
磁盘空间不足
df -h
docker system prune -af
journalctl --vacuum-size=500M
内存不足
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)
# 在 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 文件
# 将哈希写入 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
# 复制 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: 验证用户创建
# 检查用户是否创建成功
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 | 租户用户 |
重置用户密码
# 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)
前置条件
# 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 环境同步:
# 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 配置
# 创建 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
启动本地服务
# 终端 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
本地服务状态检查
# 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 隧道。
问题诊断
# 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 代理
# 通过成都节点建立隧道 (端口 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 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>
服务管理
# 查看状态
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)
- 安装 Chrome/Edge 扩展 SwitchyOmega
- 新建情景模式 → 代理服务器 → SOCKS5 →
127.0.0.1:1080 - 自动切换规则:
*.pipexerp.com→ 国内代理*.cn→ 国内代理- 其他 → 直连
SSH 跳板与反向隧道
当 Tailscale 直连不稳定或反向连接失败时,可通过公网服务器建立 SSH 跳板解决。
问题场景
典型问题:
- 本机可以 ping 通远程机器(如 cn-bj-lazycat)
- 本机可以 SSH 到远程机器
- 但远程机器无法 SSH 回本机(连接超时)
原因分析:
- Tailscale 使用 DERP 中继,连接不稳定
- NAT 穿透失败,反向连接无法建立
- 网络延迟高(200-700ms+),TCP 连接容易超时
解决方案架构
远程机器 (cn-bj-lazycat)
↓ SSH
公网跳板 (Singapore)
↓ 反向隧道 localhost:2222
本机 (au-melbourne-coolbuy-dev)
优势:
- ✅ 利用稳定的公网服务器作为中继
- ✅ 绕过 Tailscale DERP 不稳定问题
- ✅ 自动重连,无需手动维护
- ✅ 安全:隧道只监听 localhost,需通过跳板访问
配置步骤
步骤 1: 本机建立反向隧道
手动启动(测试用):
ssh -fN -R 2222:localhost:22 singapore
配置自动重连服务(推荐):
创建 ~/Library/LaunchAgents/com.ssh.singapore-tunnel.plist:
<?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>
启动服务:
launchctl load ~/Library/LaunchAgents/com.ssh.singapore-tunnel.plist
launchctl list | grep singapore-tunnel
步骤 2: 配置 SSH 密钥认证
在跳板服务器上生成密钥(如果还没有):
ssh singapore "ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N '' -C 'singapore-jump'"
将跳板公钥添加到本机:
ssh singapore "cat ~/.ssh/id_ed25519.pub" >> ~/.ssh/authorized_keys
测试反向隧道:
ssh singapore "ssh -p 2222 -o StrictHostKeyChecking=no <本机用户>@localhost 'hostname'"
步骤 3: 远程机器配置
传输跳板 SSH 密钥到远程机器:
# 在远程机器上创建 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(在远程机器上):
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 密钥认证:
# 在远程机器上生成密钥
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: 测试连接
从远程机器测试:
# 连接到跳板
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
- 用途: 澳洲开发电脑
配置详情:
# 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)"'
连接测试结果:
# 所有别名测试通过
ssh au-melbourne # ✅ 成功
ssh melbourne # ✅ 成功
ssh au-dev # ✅ 成功
管理命令
本机管理反向隧道:
# 查看状态
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"
远程机器管理:
# 测试连接质量
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
{
"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
OpenClaw 配置(懒猫算力仓)
OpenClaw 运行在懒猫算力仓的容器环境中,需要特殊配置才能访问 skills。
问题与解决方案
问题:OpenClaw 运行在容器内,无法访问宿主机的 ~/.claude/skills/ 目录
原因:容器和宿主机文件系统隔离,skills 目录未挂载到容器内
解决方案:将 skills 复制到容器内的标准路径
配置步骤
1. 连接到懒猫算力仓
# 添加 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 容器
# 查看运行的容器
ssh lazycat "/lzcsys/bin/lzc-docker ps --format 'table {{.ID}}\t{{.Names}}'"
# 找到 OpenClaw 容器 ID(通常是固定的)
CONTAINER_ID="5f3bf33e090b" # 懒猫算力仓的 OpenClaw 容器
3. 复制 skills 到容器内
# 在容器内创建目录
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
# 重启容器使配置生效
ssh lazycat "/lzcsys/bin/lzc-docker restart $CONTAINER_ID"
# 检查容器状态
ssh lazycat "/lzcsys/bin/lzc-docker ps | grep $CONTAINER_ID"
更新 Skills
当本地更新了 skills 后,需要重新同步到懒猫算力仓:
# 步骤 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"
验证配置
# 检查容器内的 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:
#!/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 已重启"
使用方法:
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 容器 |
快速部署
从本地部署到懒猫算力仓:
# 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 使用以下命令:
# 查看所有 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:
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: 新功能开发
/swarm start "为 AI-Proj 实现需求批量导出为 Excel 功能,支持自定义字段和筛选条件"
自动执行:Architect 设计 → Coder 实现 → Tester 测试 → Reviewer 审查 → Deployer 部署
场景 2: Bug 修复 + 性能优化
/swarm coder "优化任务详情页加载性能,从 3s 降到 300ms 以内"
自动执行:Coder 优化 → Tester 验证 → Deployer 灰度发布
场景 3: 代码审查
/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
# 从本地传输 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 配置文件
# 创建配置文件
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
ssh lazycat "/lzcsys/bin/lzc-docker restart 5f3bf33e090b"
测试 MCP 连接
# 测试 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 更新时:
# 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(容器内)
工作原理:
- Skill 文件提供 API 调用示例(curl 命令)
- OpenClaw AI 根据 skill 指导执行 bash 命令
- 直接调用 ai-proj REST API,无需 MCP bridge
示例操作:
# 在 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)
前置条件:
- 本机反向隧道服务运行中:
launchctl list | grep singapore-tunnel - 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 用户执行):
# 连接宿主机(通过 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/
重新配置(容器重建后):
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