{"id":"68e80fc6-f7f0-4f4f-b578-d91c7857061f","shortId":"MjZAYq","kind":"skill","title":"server-deploy","tagline":"通用项目部署到远程服务器。自动识别项目类型（Node.js/Python/Rust/Go/静态站），SSH 配置、环境安装、项目上传、进程管理、Nginx 反向代理、Cloudflare SSL、安全加固。当用户需要部署项目、上线服务、配置域名时使用","description":"# 通用服务器部署\n\n将本地项目一键部署到远程 Linux 服务器。自动识别项目类型，适配对应的构建、运行和进程管理方案。\n\n---\n\n## 第零步：项目识别与信息收集\n\n### 0a. 自动识别项目类型\n\n扫描项目根目录，按以下规则判断类型：\n\n| 标志文件 | 项目类型 | 运行时 | 进程管理 |\n|---------|---------|--------|---------|\n| `package.json` | Node.js | node | PM2 |\n| `Cargo.toml` | Rust | 编译产物 | systemd |\n| `go.mod` | Go | 编译产物 | systemd |\n| `pyproject.toml` / `requirements.txt` / `setup.py` | Python | python3 | systemd / gunicorn |\n| `Dockerfile` / `docker-compose.yml` | Docker | docker | docker compose |\n| `index.html`（无其他标志） | 静态站点 | 无 | Nginx 直接托管 |\n\n如果检测到多个标志文件（如 package.json + Dockerfile），用 AskUserQuestion 让用户选择部署方式。\n\n### 0b. 收集信息\n\n用 AskUserQuestion 收集以下信息（上下文已有的跳过）：\n\n1. **SSH 连接**（header: \"服务器\"）\n   - 根据上下文动态生成选项（如之前用过的服务器 IP）\n   - 兜底选项\"其他服务器\"\n\n2. **项目路径**（header: \"项目\"）\n   - 根据当前工作目录自动推断\n   - 如果不确定，询问用户\n\n3. **域名**（header: \"域名\"）\n   - 已有域名（让用户输入）\n   - 仅用 IP 访问（跳过域名和 SSL 配置）\n\n4. **运行端口**（header: \"端口\"）\n   - 自动检测：\n     - Node.js：从 package.json scripts 或 .env 中提取\n     - Python：从 main.py / app.py / manage.py 中提取\n     - Rust/Go：从 main.rs / main.go 或配置文件中提取\n   - 如检测不到，让用户指定\n   - 禁止使用 3000, 3001, 4000, 5000, 5173, 8000, 8080, 8888\n\n### 0c. 变量定义\n\n| 变量 | 说明 |\n|------|------|\n| `$SSH_TARGET` | SSH 连接串（如 `root@192.168.1.1`） |\n| `$PROJECT_DIR` | 本地项目绝对路径 |\n| `$PROJECT_NAME` | 项目名称 |\n| `$PROJECT_TYPE` | 项目类型：`nodejs` / `python` / `rust` / `go` / `docker` / `static` |\n| `$REMOTE_DIR` | 远程部署目录（默认 `/opt/$PROJECT_NAME`） |\n| `$PORT` | 应用运行端口 |\n| `$DOMAIN` | 域名（可选） |\n\n---\n\n## 第一步：SSH 连接与密钥配置\n\n### 1a. 检查本地 SSH 公钥\n\n```bash\ncat ~/.ssh/id_rsa.pub 2>/dev/null || cat ~/.ssh/id_ed25519.pub 2>/dev/null\n```\n\n如果没有公钥，生成一个：`ssh-keygen -t ed25519 -N \"\" -f ~/.ssh/id_ed25519`\n\n### 1b. 测试免密登录\n\n```bash\nssh -o ConnectTimeout=5 -o BatchMode=yes $SSH_TARGET \"echo ok\" 2>/dev/null\n```\n\n如果失败，用密码登录并添加公钥：\n\n```bash\nsshpass -p '<PASSWORD>' ssh -o StrictHostKeyChecking=no $SSH_TARGET \\\n  \"mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo '<PUBLIC_KEY>' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys\"\n```\n\n### 1c. 验证免密登录\n\n```bash\nssh -o ConnectTimeout=5 $SSH_TARGET \"echo '免密登录成功' && uname -a\"\n```\n\n---\n\n## 第二步：服务器环境检查\n\n**单条命令获取全部信息**：\n\n```bash\nssh $SSH_TARGET \"echo '=== 系统 ===' && cat /etc/os-release | grep PRETTY_NAME && uname -m && echo '=== CPU ===' && nproc && echo '=== 内存 ===' && free -h && echo '=== 磁盘 ===' && df -h / && echo '=== 包管理器 ===' && which apt yum dnf pacman 2>/dev/null && echo '=== Node.js ===' && node -v 2>/dev/null || echo '未安装' && echo '=== Python ===' && python3 --version 2>/dev/null || echo '未安装' && echo '=== Rust ===' && rustc --version 2>/dev/null || echo '未安装' && echo '=== Go ===' && go version 2>/dev/null || echo '未安装' && echo '=== Docker ===' && docker --version 2>/dev/null || echo '未安装' && echo '=== Nginx ===' && nginx -v 2>&1 || echo '未安装'\"\n```\n\n**检查要点**：\n- 磁盘空间是否足够\n- 内存：Node.js ≥ 512MB，Rust 编译 ≥ 1GB（或本地交叉编译）\n- 架构：`x86_64` / `aarch64`（Rust/Go 需匹配编译目标）\n- 记录缺少的组件，后续统一安装\n\n---\n\n## 第三步：安装运行时环境\n\n根据 `$PROJECT_TYPE` 安装对应运行时。仅安装缺少的组件。\n\n### Node.js 项目\n\n```bash\n# 安装 Node.js 20（如未安装）\nssh $SSH_TARGET \"curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs\"\n# 安装 PM2\nssh $SSH_TARGET \"npm install -g pm2\"\n```\n\n### Python 项目\n\n```bash\n# 安装 Python3 + pip + venv（如未安装）\nssh $SSH_TARGET \"apt-get install -y python3 python3-pip python3-venv\"\n```\n\n### Rust 项目\n\n两种方案，根据服务器资源选择：\n\n**方案 A：服务器编译（内存 ≥ 1GB）**\n```bash\nssh $SSH_TARGET \"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && source ~/.cargo/env\"\n```\n\n**方案 B：本地交叉编译（推荐低配服务器）**\n```bash\n# 本地编译（需安装对应 target）\nrustup target add x86_64-unknown-linux-gnu  # 或 aarch64-unknown-linux-gnu\ncargo build --release --target x86_64-unknown-linux-gnu\n# 仅上传编译产物\n```\n\n### Go 项目\n\n同样两种方案：\n\n**方案 A：服务器编译**\n```bash\nssh $SSH_TARGET \"wget -q https://go.dev/dl/go1.22.0.linux-amd64.tar.gz && tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz && echo 'export PATH=\\$PATH:/usr/local/go/bin' >> ~/.bashrc\"\n```\n\n**方案 B：本地交叉编译（推荐）**\n```bash\nGOOS=linux GOARCH=amd64 go build -o $PROJECT_NAME .\n# 仅上传二进制文件\n```\n\n### Docker 项目\n\n```bash\n# 安装 Docker（如未安装）\nssh $SSH_TARGET \"curl -fsSL https://get.docker.com | sh && systemctl enable docker && systemctl start docker\"\n```\n\n### Nginx（有域名时必装）\n\n```bash\nssh $SSH_TARGET \"apt-get install -y nginx && systemctl enable nginx && systemctl start nginx\"\n```\n\n---\n\n## 第四步：上传项目\n\n### 4a. 排除项（按项目类型）\n\n| 项目类型 | 排除目录/文件 |\n|---------|-------------|\n| Node.js | `node_modules/`, `.next/`, `dist/`, `.git/` |\n| Python | `__pycache__/`, `.venv/`, `venv/`, `*.pyc`, `.git/` |\n| Rust | `target/`, `.git/`（方案 B 仅上传 `target/release/$BINARY`） |\n| Go | `vendor/`（如有）, `.git/`（方案 B 仅上传二进制） |\n| Docker | `.git/`（需要上传 Dockerfile） |\n| 静态站 | `.git/`, `node_modules/` |\n\n### 4b. rsync 上传\n\n**注意**：大文件传输时 SSH 可能断连。使用保活参数：\n\n```bash\nrsync -avz --timeout=300 \\\n  -e \"ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=10\" \\\n  --exclude='.git' --exclude='<TYPE_SPECIFIC_EXCLUDES>' \\\n  $PROJECT_DIR/ $SSH_TARGET:$REMOTE_DIR/\n```\n\n**如果文件很大（>500MB）**：先上传代码，再单独上传大文件。\n\n**如果 SSH 频繁断连**：调整服务器 SSH 配置：\n```bash\nssh $SSH_TARGET \"sed -i 's/#ClientAliveInterval.*/ClientAliveInterval 60/' /etc/ssh/sshd_config && sed -i 's/#ClientAliveCountMax.*/ClientAliveCountMax 120/' /etc/ssh/sshd_config && systemctl reload ssh || systemctl reload sshd\"\n```\n\n### 4c. 安装依赖 + 构建\n\n**用 nohup 后台执行**，防止断连中断：\n\n| 项目类型 | 命令 |\n|---------|------|\n| Node.js | `nohup bash -c 'npm install && npm run build' > /tmp/build.log 2>&1 &` |\n| Python | `nohup bash -c 'python3 -m venv .venv && .venv/bin/pip install -r requirements.txt' > /tmp/build.log 2>&1 &` |\n| Rust (方案A) | `nohup bash -c 'source ~/.cargo/env && cargo build --release' > /tmp/build.log 2>&1 &` |\n| Go (方案A) | `nohup bash -c 'go build -o $PROJECT_NAME .' > /tmp/build.log 2>&1 &` |\n| Docker | `nohup bash -c 'docker compose build' > /tmp/build.log 2>&1 &` |\n| 静态站 | 无需构建 |\n\n等待后查看构建结果：`ssh $SSH_TARGET \"tail -20 /tmp/build.log\"`\n\n---\n\n## 第五步：启动应用与进程管理\n\n根据项目类型选择对应的进程管理方案。\n\n### Node.js → PM2\n\n```bash\nssh $SSH_TARGET \"cd $REMOTE_DIR && pm2 start npm --name $PROJECT_NAME -- start && pm2 startup && pm2 save\"\n```\n\n验证：`ssh $SSH_TARGET \"pm2 list && curl -s -o /dev/null -w '%{http_code}' http://localhost:$PORT\"`\n\n### Python → systemd\n\n```bash\nssh $SSH_TARGET \"cat > /etc/systemd/system/$PROJECT_NAME.service << EOF\n[Unit]\nDescription=$PROJECT_NAME\nAfter=network.target\n\n[Service]\nType=simple\nUser=root\nWorkingDirectory=$REMOTE_DIR\nExecStart=$REMOTE_DIR/.venv/bin/python -m uvicorn main:app --host 0.0.0.0 --port $PORT\n# 或 gunicorn: ExecStart=$REMOTE_DIR/.venv/bin/gunicorn -w 4 -b 0.0.0.0:$PORT main:app\nRestart=on-failure\nRestartSec=5\nEnvironment=PYTHONUNBUFFERED=1\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl daemon-reload && systemctl enable $PROJECT_NAME && systemctl start $PROJECT_NAME\"\n```\n\n> **注意**：ExecStart 根据框架调整：\n> - FastAPI/Starlette: `uvicorn main:app`\n> - Flask: `gunicorn -w 4 main:app`\n> - Django: `gunicorn -w 4 project.wsgi:application`\n> - 纯脚本: `python main.py`\n\n验证：`ssh $SSH_TARGET \"systemctl status $PROJECT_NAME && curl -s -o /dev/null -w '%{http_code}' http://localhost:$PORT\"`\n\n### Rust / Go → systemd\n\n```bash\nssh $SSH_TARGET \"cat > /etc/systemd/system/$PROJECT_NAME.service << EOF\n[Unit]\nDescription=$PROJECT_NAME\nAfter=network.target\n\n[Service]\nType=simple\nUser=root\nWorkingDirectory=$REMOTE_DIR\nExecStart=$REMOTE_DIR/$BINARY_NAME\nRestart=on-failure\nRestartSec=5\nEnvironment=PORT=$PORT\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl daemon-reload && systemctl enable $PROJECT_NAME && systemctl start $PROJECT_NAME\"\n```\n\n> Rust 二进制路径：`$REMOTE_DIR/target/release/$PROJECT_NAME`（方案 A）或 `$REMOTE_DIR/$PROJECT_NAME`（方案 B）\n> Go 二进制路径：`$REMOTE_DIR/$PROJECT_NAME`\n\n验证：`ssh $SSH_TARGET \"systemctl status $PROJECT_NAME && curl -s -o /dev/null -w '%{http_code}' http://localhost:$PORT\"`\n\n### Docker → docker compose\n\n```bash\nssh $SSH_TARGET \"cd $REMOTE_DIR && docker compose up -d\"\n```\n\n配置开机自启：Docker 服务默认随 systemd 启动，docker compose 使用 `restart: unless-stopped` 即可。\n\n验证：`ssh $SSH_TARGET \"docker compose ps && curl -s -o /dev/null -w '%{http_code}' http://localhost:$PORT\"`\n\n### 静态站 → Nginx 直接托管\n\n无需进程管理，Nginx 直接指向静态文件目录（见第六步）。\n\n---\n\n## 第六步：Nginx 反向代理\n\n> 如果用户选择\"仅用 IP 访问\"，跳过此步和后续 SSL 步骤。\n\n### 6a. 动态应用（HTTP 反向代理）\n\n```bash\nssh $SSH_TARGET \"cat > /etc/nginx/sites-available/$PROJECT_NAME << 'NGINX'\nserver {\n    listen 80;\n    server_name $DOMAIN www.$DOMAIN;\n\n    client_max_body_size 50M;\n\n    location / {\n        proxy_pass http://127.0.0.1:$PORT;\n        proxy_http_version 1.1;\n        proxy_set_header Host \\$host;\n        proxy_set_header X-Real-IP \\$remote_addr;\n        proxy_set_header X-Forwarded-For \\$proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto \\$scheme;\n        proxy_set_header Upgrade \\$http_upgrade;\n        proxy_set_header Connection \\\"upgrade\\\";\n    }\n}\nNGINX\nln -sf /etc/nginx/sites-available/$PROJECT_NAME /etc/nginx/sites-enabled/$PROJECT_NAME\nrm -f /etc/nginx/sites-enabled/default\nnginx -t && systemctl reload nginx\"\n```\n\n### 6b. 静态站（直接托管）\n\n```bash\nssh $SSH_TARGET \"cat > /etc/nginx/sites-available/$PROJECT_NAME << 'NGINX'\nserver {\n    listen 80;\n    server_name $DOMAIN www.$DOMAIN;\n\n    root $REMOTE_DIR;\n    index index.html;\n\n    location / {\n        try_files \\$uri \\$uri/ /index.html;\n    }\n\n    location ~* \\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {\n        expires 30d;\n        add_header Cache-Control \\\"public, immutable\\\";\n    }\n}\nNGINX\nln -sf /etc/nginx/sites-available/$PROJECT_NAME /etc/nginx/sites-enabled/$PROJECT_NAME\nrm -f /etc/nginx/sites-enabled/default\nnginx -t && systemctl reload nginx\"\n```\n\n### 6c. HTTPS 版本（有 SSL 证书时）\n\n在对应的 server 块基础上：\n- 80 端口 server 加 `return 301 https://$host$request_uri;`\n- 新增 443 端口 server 块，加 ssl_certificate 和安全头\n\n```nginx\nserver {\n    listen 443 ssl;\n    server_name $DOMAIN www.$DOMAIN;\n\n    ssl_certificate /etc/ssl/cloudflare/fullchain.pem;\n    ssl_certificate_key /etc/ssl/cloudflare/key.pem;\n\n    add_header X-Frame-Options \"SAMEORIGIN\" always;\n    add_header X-Content-Type-Options \"nosniff\" always;\n    add_header X-XSS-Protection \"1; mode=block\" always;\n    add_header Referrer-Policy \"strict-origin-when-cross-origin\" always;\n\n    # ... location 块同上 ...\n}\n```\n\n### 6d. Nginx 安全加固\n\n```bash\nssh $SSH_TARGET \"sed -i 's/# server_tokens off;/server_tokens off;/' /etc/nginx/nginx.conf && nginx -t && systemctl reload nginx\"\n```\n\n---\n\n## 第七步：DNS 与 SSL 配置\n\n> 仅当用户有域名时执行。\n\n### 7a. DNS 配置指引\n\n告知用户在域名注册商后台添加 DNS 记录：\n\n| 记录类型 | 名称 | 内容 |\n|---------|------|------|\n| A | `@` | `<服务器IP>` |\n| A | `www` | `<服务器IP>` |\n\n如果使用 Cloudflare，建议开启橙色云朵（代理模式）。\n\n### 7b. SSL 方案选择\n\n用 AskUserQuestion 询问：\n\n1. **Cloudflare Origin Certificate（推荐）** — DNS 托管在 Cloudflare，证书有效期 15 年\n2. **Let's Encrypt** — 免费公共证书，需定期续期\n3. **暂不配置 SSL**\n\n#### Cloudflare Origin Certificate 流程：\n\n1. 告知用户操作：Cloudflare → **SSL/TLS** → **源服务器** → **创建证书**\n   - 主机名确保包含 `$DOMAIN` 和 `*.$DOMAIN`\n   - 私钥类型：RSA，有效期：15 年\n\n2. 用户提供证书和私钥后，写入服务器并拼接证书链：\n\n```bash\nssh $SSH_TARGET \"mkdir -p /etc/ssl/cloudflare\"\n# 写入 cert.pem 和 key.pem（chmod 600）\n# 下载 Origin CA 根证书并拼接\nssh $SSH_TARGET \"curl -s -o /etc/ssl/cloudflare/origin-ca-rsa-root.pem https://developers.cloudflare.com/ssl/static/origin_ca_rsa_root.pem && cat /etc/ssl/cloudflare/cert.pem /etc/ssl/cloudflare/origin-ca-rsa-root.pem > /etc/ssl/cloudflare/fullchain.pem\"\n```\n\n3. **必须验证证书**：\n```bash\nssh $SSH_TARGET \"openssl x509 -in /etc/ssl/cloudflare/cert.pem -noout -text | grep -E 'DNS:|Subject:|Issuer:|Extended'\"\n```\n- `DNS:` 包含域名\n- `Extended Key Usage` 包含 `TLS Web Server Authentication`\n- 如果缺少，告知用户重新创建\n\n4. Cloudflare SSL 模式：先设 **Full (Strict)**，如果 526 错误则降级为 **Full**\n\n#### Let's Encrypt 流程：\n\n```bash\nssh $SSH_TARGET \"apt-get install -y certbot python3-certbot-nginx && certbot --nginx -d $DOMAIN -d www.$DOMAIN --non-interactive --agree-tos --email <EMAIL>\"\n```\n\n> 需要临时关闭 Cloudflare 代理（橙色→灰色），完成后可重新开启。\n\n---\n\n## 第八步：安全加固\n\n部署完成后，调用 `/server-security` skill 进行完整安全审计。\n\n如果用户不想跑完整审计，至少执行**最小安全加固**：\n\n### 8a. 防火墙\n\n```bash\nssh $SSH_TARGET \"ufw allow 22/tcp && ufw allow 80/tcp && ufw allow 443/tcp && ufw default deny incoming && ufw default allow outgoing && echo 'y' | ufw enable\"\n```\n\n**关键**：先放通 22 端口再 enable。启用后立即验证 SSH 连通性。\n\n### 8b. fail2ban\n\n```bash\nssh $SSH_TARGET \"apt-get install -y -qq fail2ban && cat > /etc/fail2ban/jail.local << 'EOF'\n[sshd]\nenabled = true\nport = ssh\nmaxretry = 3\nbantime = 86400\nEOF\nsystemctl enable fail2ban && systemctl restart fail2ban\"\n```\n\n### 8c. 文件权限\n\n```bash\nssh $SSH_TARGET \"find $REMOTE_DIR -name '.env*' -exec chmod 600 {} \\; 2>/dev/null\"\nssh $SSH_TARGET \"find $REMOTE_DIR \\( -name '*.db' -o -name '*.sqlite' \\) -exec chmod 600 {} \\; 2>/dev/null\"\n```\n\n---\n\n## 第九步：最终验证\n\n并行验证所有组件：\n\n```bash\n# 应用响应\ncurl -s -o /dev/null -w '%{http_code}' https://$DOMAIN 2>/dev/null || curl -s -o /dev/null -w '%{http_code}' http://<IP>:$PORT\n\n# 进程状态（按项目类型）\nssh $SSH_TARGET \"pm2 list 2>/dev/null; systemctl status $PROJECT_NAME 2>/dev/null; docker compose ps 2>/dev/null\"\n\n# 安全\nssh $SSH_TARGET \"ufw status && fail2ban-client status sshd 2>/dev/null\"\n```\n\n全部通过后输出总结：\n\n```\n## 部署完成\n\n| 项目 | 状态 |\n|------|------|\n| 项目 | $PROJECT_NAME ($PROJECT_TYPE) |\n| 服务器 | $SSH_TARGET |\n| 部署路径 | $REMOTE_DIR |\n| 运行端口 | $PORT |\n| 进程管理 | PM2 / systemd / docker（状态 online） |\n| 开机自启 | 已配置 |\n| 域名 | $DOMAIN（或\"仅 IP\"） |\n| SSL | Cloudflare Origin / Let's Encrypt / 无 |\n| 防火墙 | UFW 启用 |\n| fail2ban | SSH 防护已启用 |\n| 访问地址 | https://$DOMAIN 或 http://<IP>:$PORT |\n```\n\n---\n\n## 踩坑总结\n\n| # | 坑 | 原因 | 正确做法 |\n|---|-----|------|----------|\n| 1 | rsync 大文件传输 SSH 断连 | 服务器 SSH 默认超时短 | 调整 ClientAliveInterval=60，rsync 加 ServerAliveInterval=30 |\n| 2 | rsync 断连不丢进度 | 增量传输 | 重试即可，自动跳过已传文件 |\n| 3 | 构建超时断连 | SSH 会话中断终止前台进程 | 用 nohup 后台执行，日志写 /tmp |\n| 4 | Cloudflare 521 错误 | 服务器只有 HTTP，CF 用 HTTPS 连 | 配 SSL 或 CF 改 Flexible |\n| 5 | Cloudflare 526 错误 | Origin Certificate 无效 | 检查 SAN 包含域名 + Key Usage 包含 Server Auth |\n| 6 | Origin Certificate 缺域名 | 创建时未填主机名 | 重新创建，包含 domain 和 *.domain |\n| 7 | Full (Strict) 526 | 证书链不完整 | cert.pem + origin-ca-rsa-root.pem → fullchain.pem |\n| 8 | UFW 启用后锁死 | 忘记先放通 22 端口 | 先 `ufw allow 22/tcp` 再 `ufw enable` |\n| 9 | Nginx 多 server 块冲突 | 多配置监听同端口 | 删 default，每项目独立配置 |\n| 10 | PM2 重启丢进程 | 未 save | `pm2 startup && pm2 save` |\n| 11 | Rust 服务器编译 OOM | 小内存 VPS 编译大项目 | 本地交叉编译，仅上传二进制 |\n| 12 | Go 二进制架构不匹配 | 本地 arm64 编译的放到 x86 服务器 | GOOS=linux GOARCH=amd64 交叉编译 |\n| 13 | Python venv 路径硬编码 | 本地 venv 上传到服务器路径不同 | 远程重新创建 venv，不上传本地 venv |\n| 14 | systemd 服务启动失败无日志 | 没看 journalctl | `journalctl -u $PROJECT_NAME -f` 排查 |\n| 15 | Docker 端口映射冲突 | 主机端口已占用 | `lsof -i:$PORT` 先检查 |\n| 16 | .env 权限 644 泄露密钥 | rsync 保留权限 | 部署后 chmod 600 |\n| 17 | Nginx 暴露版本号 | 默认配置 | `server_tokens off` |\n| 18 | 服务器连接频率限制 | 短时间多次 SSH 触发保护 | 等 30-60 秒后重试 |\n| 19 | Cloudflare 缓存命中率低 | Next.js 默认不设 Cache-Control | next.config.ts 配置 headers：静态资源 immutable、uploads s-maxage=30d、API no-store |\n| 20 | ISR 页面不被 CDN 缓存 | 页面没有 revalidate 导致每次回源 | 按变化频率设 revalidate：首页 1h、详情页 24h |\n| 21 | CI/CD 构建缺环境变量 | NEXT_PUBLIC_* 变量需构建时注入 | GitHub Secrets 添加变量，workflow build 步骤 env 注入 |\n| 22 | 外链图片在国内加载失败 | Steam CDN / SteamGridDB 被墙 | 批量下载到 public/uploads/，数据库改本地路径，rsync 同步到服务器 |\n| 23 | 服务器无 sqlite3 CLI | 精简系统未安装 | 用 node + better-sqlite3 执行 SQL，或安装 sqlite3 |\n\n---\n\n## 注意事项\n\n- 自动识别项目类型，不要假设是 Node.js\n- Rust/Go 低配服务器优先本地交叉编译\n- Python 不要上传本地 venv，远程重建\n- 所有 SSH 长操作加 ServerAliveInterval 防断连\n- 构建操作用 nohup 后台执行\n- 每次改网络配置后立即验证 SSH 连通性\n- 敏感文件部署后立即修正权限\n- 使用中文输出所有信息","tags":["server","deploy","claude","arsenal","majiayu000","agent-skills","ai-agents","ai-coding-assistant","automation","claude-code","code-review","developer-tools"],"capabilities":["skill","source-majiayu000","skill-server-deploy","topic-agent-skills","topic-ai-agents","topic-ai-coding-assistant","topic-automation","topic-claude","topic-claude-code","topic-code-review","topic-developer-tools","topic-devops","topic-productivity","topic-prompt-engineering","topic-python"],"categories":["claude-arsenal"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/majiayu000/claude-arsenal/server-deploy","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add majiayu000/claude-arsenal","source_repo":"https://github.com/majiayu000/claude-arsenal","install_from":"skills.sh"}},"qualityScore":"0.464","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 29 github stars · SKILL.md body (15,263 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-01T07:01:16.456Z","embedding":null,"createdAt":"2026-04-18T22:24:27.008Z","updatedAt":"2026-05-01T07:01:16.456Z","lastSeenAt":"2026-05-01T07:01:16.456Z","tsv":"'-20':746 '-60':1905 '/.bashrc':507 '/.cargo/env':447,709 '/.ssh':240,243 '/.ssh/authorized_keys':245,248 '/.ssh/id_ed25519':210 '/.ssh/id_ed25519.pub':198 '/.ssh/id_rsa.pub':194 '/clientalivecountmax':658 '/clientaliveinterval':651 '/dev/null':196,200,226,297,303,311,319,327,335,780,891,984,1027,1595,1611,1620,1626,1630,1643,1649,1654,1667 '/dl/go1.22.0.linux-amd64.tar.gz':496 '/etc/fail2ban/jail.local':1562 '/etc/nginx/nginx.conf':1315 '/etc/nginx/sites-available':1059,1133,1155,1201 '/etc/nginx/sites-enabled':1136,1204 '/etc/nginx/sites-enabled/default':1141,1209 '/etc/os-release':272 '/etc/ssh/sshd_config':653,660 '/etc/ssl/cloudflare':1399 '/etc/ssl/cloudflare/cert.pem':1421,1433 '/etc/ssl/cloudflare/fullchain.pem':1254,1423 '/etc/ssl/cloudflare/key.pem':1258 '/etc/ssl/cloudflare/origin-ca-rsa-root.pem':1416,1422 '/etc/systemd/system':793,905 '/index.html':1177 '/opt':177 '/python/rust/go/':8 '/server-security':1507 '/server_tokens':1313 '/setup_20.x':384 '/ssl/static/origin_ca_rsa_root.pem':1419 '/tmp':1748 '/tmp/build.log':685,700,713,726,736,747 '/usr/local':499 '/usr/local/go/bin':506 '0.0.0.0':818,829 '0a':32 '0b':78 '0c':147 '1':84,343,687,702,715,728,738,841,1282,1351,1375,1719 '1.1':1084 '10':623,1820 '11':1829 '12':1838 '120':659 '127.0.0.1':1079 '13':1851 '14':1862 '15':1360,1388,1873 '16':1881 '17':1891 '18':1898 '19':1907 '192.168.1.1':157 '1a':188 '1b':211 '1c':249 '1gb':353,432 '1h':1940 '2':94,195,199,225,296,302,310,318,326,334,342,686,701,714,727,737,1362,1390,1594,1610,1625,1642,1648,1653,1666,1734 '20':375,1929 '21':1943 '22':1542,1802,1957 '22/tcp':1521,1807 '23':1968 '24h':1942 '3':101,1368,1424,1570,1740 '30':620,1733,1904 '300':615 '3000':139 '3001':140 '301':1229 '30d':1190,1924 '4':113,827,868,874,1454,1749 '4000':141 '443':1234,1245 '443/tcp':1527 '4a':562 '4b':603 '4c':667 '5':217,255,838,932,1765 '5000':142 '500mb':634 '50m':1075 '512mb':350 '5173':143 '521':1751 '526':1462,1767,1793 '6':1780 '60':652,1729 '600':247,1405,1593,1609,1890 '64':357,460,476 '644':1884 '6a':1050 '6b':1147 '6c':1215 '6d':1300 '7':1790 '700':242 '7a':1327 '7b':1345 '8':1798 '80':1065,1161,1224 '80/tcp':1524 '8000':144 '8080':145 '86400':1572 '8888':146 '8a':1513 '8b':1548 '8c':1580 '9':1811 'aarch64':358,467 'aarch64-unknown-linux-gnu':466 'add':458,1107,1191,1259,1267,1276,1286 'addr':1098 'agre':1494 'agree-to':1493 'allow':1520,1523,1526,1534,1806 'alway':1266,1275,1285,1297 'amd64':516,1849 'api':1925 'app':816,832,864,870 'app.py':128 'applic':876 'apt':292,387,413,549,1474,1555 'apt-get':386,412,548,1473,1554 'arm64':1842 'askuserquest':76,81,1349 'auth':1779 'authent':1451 'avz':613 'b':449,509,584,593,828,966 'bantim':1571 'bash':192,213,229,251,265,372,385,403,433,452,488,512,525,544,611,643,678,690,706,719,731,753,788,900,993,1054,1150,1303,1393,1426,1469,1515,1550,1582,1615 'batchmod':219 'better':1976 'better-sqlite3':1975 'binari':587,925 'block':1284 'bodi':1073 'build':472,518,684,711,722,735,1953 'c':498,679,691,707,720,732 'ca':1408 'cach':1194,1913 'cache-control':1193,1912 'cargo':471,710 'cargo.toml':44 'cat':193,197,271,792,904,1058,1154,1420,1561 'cd':757,997 'cdn':1932,1960 'cert.pem':1401,1795 'certbot':1478,1481,1483 'certif':1240,1253,1256,1354,1373,1770,1782 'cf':1755,1762 'chmod':241,246,1404,1592,1608,1889 'ci/cd':1944 'cli':1971 'client':1071,1663 'clientalivecountmax':657 'clientaliveinterv':650,1728 'cloudflar':17,1342,1352,1358,1371,1377,1455,1498,1699,1750,1766,1908 'code':783,894,987,1030,1623,1633 'compos':64,734,992,1001,1010,1022,1651 'connect':1128 'connecttimeout':216,254 'content':1271 'control':1195,1914 'cpu':279 'cross':1295 'css':1180 'curl':380,437,532,777,888,981,1024,1413,1617,1627 'd':1003,1485,1487 'daemon':848,942 'daemon-reload':847,941 'db':1603 'deb.nodesource.com':383 'deb.nodesource.com/setup_20.x':382 'default':1529,1533,1818 'deni':1530 'deploy':3 'descript':797,909 'developers.cloudflare.com':1418 'developers.cloudflare.com/ssl/static/origin_ca_rsa_root.pem':1417 'df':287 'dir':159,174,628,632,759,809,921,924,962,970,999,1169,1588,1601,1682 'dir/.venv/bin/gunicorn':825 'dir/.venv/bin/python':812 'dir/target/release':955 'dist':572 'django':871 'dnf':294 'dns':1322,1328,1331,1356,1438,1442 'docker':61,62,63,171,331,332,523,527,538,541,595,729,733,990,991,1000,1005,1009,1021,1650,1688,1874 'docker-compose.yml':60 'dockerfil':59,74,598 'domain':182,1068,1070,1164,1166,1249,1251,1382,1384,1486,1489,1624,1694,1712,1787,1789 'e':616,1437 'echo':223,244,258,269,278,281,285,289,298,304,306,312,314,320,322,328,330,336,338,344,502,1536 'ed25519':207 'email':1496 'enabl':537,555,851,945,1539,1544,1565,1575,1810 'encrypt':1365,1467,1703 'env':123,1590,1882,1955 'environ':839,933 'eof':795,845,907,939,1563,1573 'exclud':624,626 'exec':1591,1607 'execstart':810,823,859,922 'expir':1189 'export':503 'extend':1441,1444 'f':209,1140,1208,1871 'fail2ban':1549,1560,1576,1579,1662,1708 'fail2ban-client':1661 'failur':836,930 'fastapi/starlette':861 'file':1174 'find':1586,1599 'flask':865 'flexibl':1764 'forward':1104,1109,1116 'frame':1263 'free':283 'fssl':381,533 'full':1459,1464,1791 'fullchain.pem':1797 'g':399 'get':388,414,550,1475,1556 'get.docker.com':534 'gif':1184 'git':573,579,582,591,596,600,625 'github':1949 'gnu':464,470,480 'go':49,170,323,324,482,517,588,716,721,898,967,1839 'go.dev':495 'go.dev/dl/go1.22.0.linux-amd64.tar.gz':494 'go.mod':48 'go1.22.0.linux-amd64.tar.gz':501 'goarch':515,1848 'goo':513,1846 'grep':273,1436 'gunicorn':58,822,866,872 'h':284,288 'header':87,96,103,115,1087,1092,1101,1113,1121,1127,1192,1260,1268,1277,1287,1917 'host':817,1088,1089,1230 'http':782,893,986,1029,1052,1082,1123,1622,1632,1754 'https':439,1216,1757 'ico':1185 'immut':1197,1919 'incom':1531 'index':1170 'index.html':65,1171 'instal':389,398,415,551,681,697,842,936,1476,1557 'interact':1492 'ip':91,108,1045,1096,1697 'isr':1930 'issuer':1440 'journalctl':1866,1867 'jpeg':1183 'jpg':1182 'js':1179 'key':1257,1445,1775 'key.pem':1403 'keygen':205 'let':1363,1465,1701 'linux':25,463,469,479,514,1847 'list':776,1641 'listen':1064,1160,1244 'ln':1131,1199 'localhost':784,895,988,1031 'locat':1076,1172,1178,1298 'lsof':1877 'm':277,693,813 'main':815,831,863,869 'main.go':134 'main.py':127,879 'main.rs':133 'manage.py':129 'max':1072 'maxag':1923 'maxretri':1569 'mkdir':238,1397 'mode':1283 'modul':570,602 'multi-user.target':844,938 'n':208 'name':162,179,275,521,725,763,765,799,853,857,887,911,926,947,951,957,964,972,980,1061,1067,1135,1138,1157,1163,1203,1206,1248,1589,1602,1605,1647,1674,1870 'network.target':801,913 'next':571,1946 'next.config.ts':1915 'next.js':1910 'nginx':15,69,339,340,542,553,556,559,1034,1037,1041,1062,1130,1142,1146,1158,1198,1210,1214,1242,1301,1316,1320,1482,1484,1812,1892 'no-stor':1926 'node':42,300,569,601,1974 'node.js':7,41,118,299,349,370,374,568,676,751,1985 'node.js/python/rust/go/':6 'nodej':167,391 'nohup':671,677,689,705,718,730,1745,1998 'non':1491 'non-interact':1490 'noout':1434 'nosniff':1274 'npm':397,680,682,762 'nproc':280 'o':215,218,233,253,519,618,621,723,779,890,983,1026,1415,1604,1619,1629 'ok':224 'on-failur':834,928 'onlin':1690 'oom':1832 'openssl':1430 'option':1264,1273 'origin':1293,1296,1353,1372,1407,1700,1769,1781 'origin-ca-rsa-root.pem':1796 'outgo':1535 'p':231,239,1398 'package.json':40,73,120 'pacman':295 'pass':1078 'path':504,505 'pip':406,420 'pm2':43,393,400,752,760,767,769,775,1640,1686,1821,1825,1827 'png':1181 'polici':1290 'port':180,785,819,820,830,896,934,935,989,1032,1080,1567,1634,1684,1714,1879 'pretti':274 'project':158,161,164,178,366,520,627,724,764,798,852,856,886,910,946,950,956,963,971,979,1060,1134,1137,1156,1202,1205,1646,1673,1675,1869 'project.wsgi':875 'project_name.service':794,906 'protect':1281 'proto':438,1117 'proxi':1077,1081,1085,1090,1099,1106,1111,1119,1125 'ps':1023,1652 'public':1196,1947 'public/uploads':1964 'pyc':578 'pycach':575 'pyproject.toml':52 'python':55,125,168,307,401,574,688,786,878,1852,1988 'python3':56,308,405,417,419,422,692,1480 'python3-certbot-nginx':1479 'python3-pip':418 'python3-venv':421 'pythonunbuff':840 'q':493 'qq':1559 'r':698 'real':1095 'referr':1289 'referrer-polici':1288 'releas':473,712 'reload':662,665,849,943,1145,1213,1319 'remot':173,631,758,808,811,824,920,923,954,961,969,998,1097,1168,1587,1600,1681 'request':1231 'requirements.txt':53,699 'restart':833,927,1012,1578 'restartsec':837,931 'return':1228 'revalid':1935,1938 'rm':1139,1207 'root':156,806,918,1167 'rsa':1386 'rsync':604,612,1720,1730,1735,1886,1966 'run':683 'rust':45,169,315,351,424,580,703,897,952,1830 'rust/go':131,359,1986 'rustc':316 'rustup':456 's-maxag':1921 'sameorigin':1265 'san':1773 'save':770,1824,1828 'scheme':1118 'script':121 'secret':1950 'sed':647,654,1307 'server':2,1063,1066,1159,1162,1222,1226,1236,1243,1247,1310,1450,1778,1814,1895 'server-deploy':1 'serveralivecountmax':622 'serveraliveinterv':619,1732,1995 'servic':802,914 'set':1086,1091,1100,1112,1120,1126 'setup.py':54 'sf':1132,1200 'sh':443,535 'sh.rustup.rs':442 'simpl':804,916 'size':1074 'skill':1508 'skill-server-deploy' 'sourc':446,708 'source-majiayu000' 'sql':1979 'sqlite':1606 'sqlite3':1970,1977,1981 'ssf':441 'ssh':10,85,151,153,186,190,204,214,221,232,236,252,256,266,267,377,378,394,395,409,410,434,435,489,490,529,530,545,546,608,617,629,638,641,644,645,663,742,743,754,755,772,773,789,790,881,882,901,902,974,975,994,995,1018,1019,1055,1056,1151,1152,1304,1305,1394,1395,1410,1411,1427,1428,1470,1471,1516,1517,1546,1551,1552,1568,1583,1584,1596,1597,1637,1638,1656,1657,1678,1709,1722,1725,1742,1901,1993,2001 'ssh-keygen':203 'sshd':666,1564,1665 'sshpass':230 'ssl':18,111,1048,1219,1239,1246,1252,1255,1324,1346,1370,1456,1698,1760 'ssl/tls':1378 'start':540,558,761,766,855,949 'startup':768,1826 'static':172 'status':885,978,1645,1660,1664 'steam':1959 'steamgriddb':1961 'stop':1015 'store':1928 'strict':1292,1460,1792 'strict-origin-when-cross-origin':1291 'stricthostkeycheck':234 'subject':1439 'svg':1186 'systemctl':536,539,554,557,661,664,846,850,854,884,940,944,948,977,1144,1212,1318,1574,1577,1644 'systemd':47,51,57,787,899,1007,1687,1863 'tail':745 'tar':497 'target':152,222,237,257,268,379,396,411,436,455,457,474,491,531,547,581,630,646,744,756,774,791,883,903,976,996,1020,1057,1153,1306,1396,1412,1429,1472,1518,1553,1585,1598,1639,1658,1679 'target/release':586 'text':1435 'timeout':614 'tls':1448 'tlsv1.2':440 'token':1311,1896 'topic-agent-skills' 'topic-ai-agents' 'topic-ai-coding-assistant' 'topic-automation' 'topic-claude' 'topic-claude-code' 'topic-code-review' 'topic-developer-tools' 'topic-devops' 'topic-productivity' 'topic-prompt-engineering' 'topic-python' 'tos':1495 'tri':1173 'true':1566 'type':165,367,803,915,1272,1676 'u':1868 'ufw':1519,1522,1525,1528,1532,1538,1659,1706,1799,1805,1809 'unam':260,276 'unit':796,908 'unknown':462,468,478 'unknown-linux-gnu':461,477 'unless':1014 'unless-stop':1013 'upgrad':1122,1124,1129 'upload':1920 'uri':1175,1176,1232 'usag':1446,1776 'user':805,917 'uvicorn':814,862 'v':301,341 'vendor':589 'venv':407,423,576,577,694,695,1853,1856,1859,1861,1990 'venv/bin/pip':696 'version':309,317,325,333,1083 'vps':1834 'w':781,826,867,873,892,985,1028,1621,1631 'wantedbi':843,937 'web':1449 'wget':492 'woff':1187 'woff2':1188 'workflow':1952 'workingdirectori':807,919 'www':1069,1165,1250,1339,1488 'x':1094,1103,1108,1115,1262,1270,1279 'x-content-type-opt':1269 'x-forwarded-for':1102 'x-forwarded-proto':1114 'x-frame-opt':1261 'x-real-ip':1093 'x-xss-protect':1278 'x509':1431 'x86':356,459,475,1844 'xss':1280 'xzf':500 'y':390,416,445,552,1477,1537,1558 'yes':220 'yum':293 '上下文已有的跳过':83 '上传':605 '上传到服务器路径不同':1857 '上传项目':561 '上线服务':21 '下载':1406 '不上传本地':1860 '不要上传本地':1989 '不要假设是':1984 '与':1323 '两种方案':426 '中提取':124,130 '主机名确保包含':1381 '主机端口已占用':1876 '二进制架构不匹配':1840 '二进制路径':953,968 '交叉编译':1850 '仅':1696 '仅上传':585 '仅上传二进制':594,1837 '仅上传二进制文件':522 '仅上传编译产物':481 '仅安装缺少的组件':369 '仅当用户有域名时执行':1326 '仅用':107,1044 '从':119,126,132 '代理':1499 '代理模式':1344 '会话中断终止前台进程':1743 '低配服务器优先本地交叉编译':1987 '使用':1011 '使用中文输出所有信息':2004 '使用保活参数':610 '保留权限':1887 '先':1804 '先上传代码':635 '先放通':1541 '先检查':1880 '先设':1458 '免密登录成功':259 '免费公共证书':1366 '兜底选项':92 '全部通过后输出总结':1668 '公钥':191 '关键':1540 '其他服务器':93 '内存':282,348,431 '内容':1335 '再':1808 '再单独上传大文件':636 '写入':1400 '写入服务器并拼接证书链':1392 '创建时未填主机名':1784 '创建证书':1380 '删':1817 '加':1227,1238,1731 '动态应用':1051 '包含':1447,1777,1786 '包含域名':1443,1774 '包管理器':290 '单条命令获取全部信息':264 '即可':1016 '原因':1717 '反向代理':16,1042,1053 '变量':149 '变量定义':148 '变量需构建时注入':1948 '可能断连':609 '可选':184 '同样两种方案':484 '同步到服务器':1967 '名称':1334 '后台执行':672,1746,1999 '后续统一安装':362 '启动':1008 '启动应用与进程管理':749 '启用':1707 '启用后立即验证':1545 '启用后锁死':1800 '告知用户在域名注册商后台添加':1330 '告知用户操作':1376 '告知用户重新创建':1453 '命令':675 '和':1383,1402,1788 '和安全头':1241 '在对应的':1221 '坑':1716 '块':1237 '块冲突':1815 '块同上':1299 '块基础上':1223 '域名':102,104,183,1693 '增量传输':1737 '外链图片在国内加载失败':1958 '多':1813 '多配置监听同端口':1816 '大文件传输':1721 '大文件传输时':607 '如':72,155 '如之前用过的服务器':90 '如有':590 '如未安装':376,408,528 '如果':637,1461 '如果不确定':99 '如果使用':1341 '如果失败':227 '如果文件很大':633 '如果检测到多个标志文件':71 '如果没有公钥':201 '如果用户不想跑完整审计':1510 '如果用户选择':1043 '如果缺少':1452 '如检测不到':136 '安全':1655 '安全加固':19,1302,1504 '安装':373,392,404,526 '安装依赖':668 '安装对应运行时':368 '安装运行时环境':364 '完成后可重新开启':1502 '导致每次回源':1936 '将本地项目一键部署到远程':24 '小内存':1833 '已有域名':105 '已配置':1692 '年':1361,1389 '并行验证所有组件':1614 '应用响应':1616 '应用运行端口':181 '建议开启橙色云朵':1343 '开机自启':1691 '当用户需要部署项目':20 '必须验证证书':1425 '忘记先放通':1801 '或':122,465,821,960,1695,1713,1761 '或安装':1980 '或本地交叉编译':354 '或配置文件中提取':135 '所有':1992 '托管在':1357 '执行':1978 '扫描项目根目录':34 '批量下载到':1963 '按以下规则判断类型':35 '按变化频率设':1937 '按项目类型':564,1636 '排查':1872 '排除目录':566 '排除项':563 '推荐':511,1355 '推荐低配服务器':451 '收集以下信息':82 '收集信息':79 '改':1763 '敏感文件部署后立即修正权限':2003 '数据库改本地路径':1965 '文件':567 '文件权限':1581 '断连':1723 '断连不丢进度':1736 '新增':1233 '方案':428,448,485,508,583,592,958,965 '方案a':704,717 '方案选择':1347 '无':68,1704 '无其他标志':66 '无效':1771 '无需构建':740 '无需进程管理':1036 '日志写':1747 '暂不配置':1369 '暴露版本号':1893 '最小安全加固':1512 '最终验证':1613 '有':1218 '有域名时必装':543 '有效期':1387 '服务启动失败无日志':1864 '服务器':26,88,1677,1724,1845 '服务器ip':1337,1340 '服务器只有':1753 '服务器无':1969 '服务器环境检查':263 '服务器编译':430,487,1831 '服务器连接频率限制':1899 '服务默认随':1006 '未':1823 '未安装':305,313,321,329,337,345 '本地':1841,1855 '本地交叉编译':450,510,1836 '本地编译':453 '本地项目绝对路径':160 '权限':1883 '构建':669 '构建操作用':1997 '构建缺环境变量':1945 '构建超时断连':1741 '架构':355 '标志文件':36 '根据':365 '根据上下文动态生成选项':89 '根据当前工作目录自动推断':98 '根据服务器资源选择':427 '根据框架调整':860 '根据项目类型选择对应的进程管理方案':750 '根证书并拼接':1409 '检查':1772 '检查本地':189 '检查要点':346 '模式':1457 '橙色':1500 '正确做法':1718 '步骤':1049,1954 '每次改网络配置后立即验证':2000 '每项目独立配置':1819 '没看':1865 '泄露密钥':1885 '注入':1956 '注意':606,858 '注意事项':1982 '流程':1374,1468 '测试免密登录':212 '添加变量':1951 '源服务器':1379 '灰色':1501 '版本':1217 '状态':1671,1689 '环境安装':12 '生成一个':202 '用':75,80,670,1348,1744,1756,1973 '用密码登录并添加公钥':228 '用户提供证书和私钥后':1391 '直接托管':70,1035,1149 '直接指向静态文件目录':1038 '短时间多次':1900 '磁盘':286 '磁盘空间是否足够':347 '禁止使用':138 '私钥类型':1385 '秒后重试':1906 '端口':116,1225,1235,1803 '端口再':1543 '端口映射冲突':1875 '第一步':185 '第七步':1321 '第三步':363 '第九步':1612 '第二步':262 '第五步':748 '第八步':1503 '第六步':1040 '第四步':560 '第零步':30 '等':1903 '等待后查看构建结果':741 '精简系统未安装':1972 '系统':270 '纯脚本':877 '缓存':1933 '缓存命中率低':1909 '编译':352 '编译产物':46,50 '编译大项目':1835 '编译的放到':1843 '缺域名':1783 '自动检测':117 '自动识别项目类型':5,27,33,1983 '自动跳过已传文件':1739 '至少执行':1511 '被墙':1962 '见第六步':1039 '触发保护':1902 '让用户指定':137 '让用户输入':106 '让用户选择部署方式':77 '记录':1332 '记录类型':1333 '记录缺少的组件':361 '访问':109,1046 '访问地址':1711 '证书时':1220 '证书有效期':1359 '证书链不完整':1794 '询问':1350 '询问用户':100 '详情页':1941 '说明':150 '调整':1727 '调整服务器':640 '调用':1506 '路径硬编码':1854 '跳过域名和':110 '跳过此步和后续':1047 '踩坑总结':1715 '运行和进程管理方案':29 '运行时':38 '运行端口':114,1683 '进程状态':1635 '进程管理':14,39,1685 '进行完整安全审计':1509 '远程部署目录':175 '远程重建':1991 '远程重新创建':1858 '连':1758 '连接':86 '连接与密钥配置':187 '连接串':154 '连通性':1547,2002 '适配对应的构建':28 '通用服务器部署':23 '通用项目部署到远程服务器':4 '部署后':1888 '部署完成':1669 '部署完成后':1505 '部署路径':1680 '配':1759 '配置':11,112,642,1325,1916 '配置域名时使用':22 '配置开机自启':1004 '配置指引':1329 '重启丢进程':1822 '重新创建':1785 '重试即可':1738 '错误':1752,1768 '错误则降级为':1463 '长操作加':1994 '防护已启用':1710 '防断连':1996 '防止断连中断':673 '防火墙':1514,1705 '需匹配编译目标':360 '需安装对应':454 '需定期续期':1367 '需要上传':597 '需要临时关闭':1497 '静态站':9,599,739,1033,1148 '静态站点':67 '静态资源':1918 '页面不被':1931 '页面没有':1934 '项目':97,371,402,425,483,524,1670,1672 '项目上传':13 '项目名称':163 '项目类型':37,166,565,674 '项目识别与信息收集':31 '项目路径':95 '频繁断连':639 '首页':1939 '验证':771,880,973,1017 '验证免密登录':250 '默认':176 '默认不设':1911 '默认超时短':1726 '默认配置':1894","prices":[{"id":"b882d72e-f2f4-465d-956d-20069e2eb490","listingId":"68e80fc6-f7f0-4f4f-b578-d91c7857061f","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"majiayu000","category":"claude-arsenal","install_from":"skills.sh"},"createdAt":"2026-04-18T22:24:27.008Z"}],"sources":[{"listingId":"68e80fc6-f7f0-4f4f-b578-d91c7857061f","source":"github","sourceId":"majiayu000/claude-arsenal/server-deploy","sourceUrl":"https://github.com/majiayu000/claude-arsenal/tree/main/skills/server-deploy","isPrimary":false,"firstSeenAt":"2026-04-18T22:24:27.008Z","lastSeenAt":"2026-05-01T07:01:16.456Z"}],"details":{"listingId":"68e80fc6-f7f0-4f4f-b578-d91c7857061f","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"majiayu000","slug":"server-deploy","github":{"repo":"majiayu000/claude-arsenal","stars":29,"topics":["agent-skills","ai-agents","ai-coding-assistant","automation","claude","claude-code","code-review","developer-tools","devops","productivity","prompt-engineering","python","software-development","typescript","workflows"],"license":"mit","html_url":"https://github.com/majiayu000/claude-arsenal","pushed_at":"2026-04-29T04:12:22Z","description":"52 production-ready Claude Code skills and 7 specialized agents for software development, DevOps, product workflows, and automation.","skill_md_sha":"f7bb7bf0fec000e7be9e1b3916151263996acd4f","skill_md_path":"skills/server-deploy/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/majiayu000/claude-arsenal/tree/main/skills/server-deploy"},"layout":"multi","source":"github","category":"claude-arsenal","frontmatter":{"name":"server-deploy","description":"通用项目部署到远程服务器。自动识别项目类型（Node.js/Python/Rust/Go/静态站），SSH 配置、环境安装、项目上传、进程管理、Nginx 反向代理、Cloudflare SSL、安全加固。当用户需要部署项目、上线服务、配置域名时使用"},"skills_sh_url":"https://skills.sh/majiayu000/claude-arsenal/server-deploy"},"updatedAt":"2026-05-01T07:01:16.456Z"}}