docs: add PM2 one-click start
This commit is contained in:
50
README.md
50
README.md
@@ -55,8 +55,16 @@ https://github.com/ZgDaniel/cc-web 给我装!
|
|||||||
```bash
|
```bash
|
||||||
git clone https://github.com/ZgDaniel/cc-web.git
|
git clone https://github.com/ZgDaniel/cc-web.git
|
||||||
cd cc-web
|
cd cc-web
|
||||||
npm install
|
|
||||||
cp .env.example .env # 可选,不设密码则首次启动自动生成
|
cp .env.example .env # 可选,不设密码则首次启动自动生成
|
||||||
|
./start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
`start.sh` 会检查 Node.js/npm 环境,自动安装 PM2(如未安装),安装项目依赖,并以 `ccweb` 为默认应用名启动或重启服务。
|
||||||
|
|
||||||
|
如只想前台临时运行,也可以手动执行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
npm start
|
npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -137,6 +145,7 @@ cc-web/
|
|||||||
│ ├── mock-claude.js # 回归用 mock Claude CLI
|
│ ├── mock-claude.js # 回归用 mock Claude CLI
|
||||||
│ └── mock-codex.js # 回归用 mock Codex CLI
|
│ └── mock-codex.js # 回归用 mock Codex CLI
|
||||||
├── .env.example # 环境变量模板
|
├── .env.example # 环境变量模板
|
||||||
|
├── start.sh # Linux / macOS PM2 一键启动脚本
|
||||||
├── start.bat # Windows 一键启动脚本
|
├── start.bat # Windows 一键启动脚本
|
||||||
├── .gitignore
|
├── .gitignore
|
||||||
├── package.json
|
├── package.json
|
||||||
@@ -186,6 +195,45 @@ tail -f logs/process.log | jq .
|
|||||||
|
|
||||||
## 生产部署
|
## 生产部署
|
||||||
|
|
||||||
|
### PM2 一键启动
|
||||||
|
|
||||||
|
推荐在 Linux 服务器使用非 root 用户部署:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/ZgDaniel/cc-web.git
|
||||||
|
cd cc-web
|
||||||
|
cp .env.example .env # 可选,不设密码则首次启动自动生成
|
||||||
|
./start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
脚本默认执行以下动作:
|
||||||
|
|
||||||
|
- 检查 Node.js >= 18 与 npm
|
||||||
|
- 检查 PM2,未安装时自动执行 `npm install -g pm2`
|
||||||
|
- 使用 `npm ci` 安装项目依赖(无 `package-lock.json` 时退回 `npm install`)
|
||||||
|
- 使用 PM2 启动或重启 `server.js`,默认应用名为 `ccweb`
|
||||||
|
- 执行 `pm2 save` 保存当前进程快照
|
||||||
|
|
||||||
|
常用命令:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pm2 status ccweb
|
||||||
|
pm2 logs ccweb
|
||||||
|
pm2 restart ccweb --update-env
|
||||||
|
```
|
||||||
|
|
||||||
|
如果需要服务器重启后自动恢复 PM2 进程,请执行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pm2 startup
|
||||||
|
```
|
||||||
|
|
||||||
|
然后按命令输出的提示执行生成的 `sudo ...` 命令,最后再次执行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pm2 save
|
||||||
|
```
|
||||||
|
|
||||||
### systemd 服务
|
### systemd 服务
|
||||||
|
|
||||||
创建 `/etc/systemd/system/cc-web.service`:
|
创建 `/etc/systemd/system/cc-web.service`:
|
||||||
|
|||||||
103
start.sh
Executable file
103
start.sh
Executable file
@@ -0,0 +1,103 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
APP_NAME="${CC_WEB_PM2_NAME:-ccweb}"
|
||||||
|
ENTRY_FILE="${CC_WEB_ENTRY:-server.js}"
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
APP_DIR="${SCRIPT_DIR}"
|
||||||
|
ENTRY_PATH="${APP_DIR}/${ENTRY_FILE}"
|
||||||
|
|
||||||
|
log() {
|
||||||
|
printf '[cc-web pm2] %s\n' "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
printf '[cc-web pm2] ERROR: %s\n' "$*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_command() {
|
||||||
|
local cmd="$1"
|
||||||
|
local hint="$2"
|
||||||
|
if ! command -v "${cmd}" >/dev/null 2>&1; then
|
||||||
|
fail "${cmd} 未安装。${hint}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
install_pm2() {
|
||||||
|
if command -v pm2 >/dev/null 2>&1; then
|
||||||
|
log "PM2 已安装: $(command -v pm2)"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "未检测到 PM2,开始安装..."
|
||||||
|
if npm install -g pm2; then
|
||||||
|
log "PM2 安装完成"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v sudo >/dev/null 2>&1; then
|
||||||
|
log "普通 npm 全局安装失败,尝试使用 sudo 安装 PM2..."
|
||||||
|
sudo npm install -g pm2
|
||||||
|
log "PM2 安装完成"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
fail "PM2 自动安装失败,且当前环境没有 sudo。请先手动安装: npm install -g pm2"
|
||||||
|
}
|
||||||
|
|
||||||
|
install_dependencies() {
|
||||||
|
cd "${APP_DIR}"
|
||||||
|
|
||||||
|
if [[ -f package-lock.json ]]; then
|
||||||
|
log "安装项目依赖: npm ci"
|
||||||
|
npm ci
|
||||||
|
else
|
||||||
|
log "安装项目依赖: npm install"
|
||||||
|
npm install
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
start_or_restart_app() {
|
||||||
|
cd "${APP_DIR}"
|
||||||
|
|
||||||
|
if pm2 describe "${APP_NAME}" >/dev/null 2>&1; then
|
||||||
|
log "PM2 应用已存在,执行重启: ${APP_NAME}"
|
||||||
|
pm2 restart "${APP_NAME}" --update-env
|
||||||
|
else
|
||||||
|
log "启动 PM2 应用: ${APP_NAME}"
|
||||||
|
pm2 start "${ENTRY_PATH}" --name "${APP_NAME}" --cwd "${APP_DIR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "保存 PM2 进程快照"
|
||||||
|
pm2 save
|
||||||
|
|
||||||
|
log "当前 PM2 状态"
|
||||||
|
pm2 status "${APP_NAME}"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
if [[ "$(id -u)" -eq 0 ]]; then
|
||||||
|
fail "请使用非 root 用户执行。该服务会启动 Claude/Codex 子进程,root 运行风险过高。"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ -f "${ENTRY_PATH}" ]] || fail "找不到入口文件: ${ENTRY_PATH}"
|
||||||
|
|
||||||
|
ensure_command node "请先安装 Node.js 18 或更高版本。"
|
||||||
|
ensure_command npm "请先安装 npm。"
|
||||||
|
|
||||||
|
local node_major
|
||||||
|
node_major="$(node -p "Number(process.versions.node.split('.')[0])")"
|
||||||
|
if [[ "${node_major}" -lt 18 ]]; then
|
||||||
|
fail "Node.js 版本过低,当前为 $(node -v),要求 >= 18。"
|
||||||
|
fi
|
||||||
|
|
||||||
|
install_pm2
|
||||||
|
install_dependencies
|
||||||
|
start_or_restart_app
|
||||||
|
|
||||||
|
log "完成。若需要开机自启,请执行 pm2 startup,并按输出提示执行生成的命令。"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
Reference in New Issue
Block a user