测试
This commit is contained in:
parent
baf702291c
commit
85799af6df
267
README.md
267
README.md
@ -1,29 +1,31 @@
|
||||
# jsite 自动化部署和管理脚本
|
||||
# jsite.sh - 前端自动化部署脚本
|
||||
|
||||
这是一个集成了完整部署和日常管理功能的自动化脚本,支持多种任务模式。
|
||||
## 概述
|
||||
|
||||
## 功能特性
|
||||
`jsite.sh` 是一个用于自动化部署和管理前端网站的bash脚本。它支持多种操作模式,包括部署、启动、停止、重启等。
|
||||
|
||||
- 🚀 **完整部署**:一键部署完整的jsite环境
|
||||
- 🏗️ **网站管理**:创建、删除、构建、启动、停止、重启网站
|
||||
- 📊 **状态监控**:查看网站运行状态和日志
|
||||
- 🔧 **环境管理**:Docker、Node.js、PM2、Traefik等环境组件
|
||||
- ⚡ **智能端口分配**:自动分配和管理端口资源
|
||||
## 主要功能
|
||||
|
||||
- 自动创建和管理jingrow用户
|
||||
- 安装和配置Node.js、npm、PM2
|
||||
- 自动化部署前端项目
|
||||
- 集成Traefik反向代理
|
||||
- 支持多种操作模式
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 基本语法
|
||||
|
||||
```bash
|
||||
./install_jsite.sh --mode <任务模式> [其他参数]
|
||||
./jsite.sh --mode <模式> --site-name <网站名称>
|
||||
```
|
||||
|
||||
### 支持的任务模式
|
||||
### 支持的模式
|
||||
|
||||
| 模式 | 功能 | 示例 |
|
||||
| 模式 | 描述 | 示例 |
|
||||
|------|------|------|
|
||||
| `deploy` | 完整部署模式(默认) | `--mode deploy --site-name myproject` |
|
||||
| `create` | 创建新网站 | `--mode create --site-name myproject --git-repo <仓库地址>` |
|
||||
| `deploy` | 完整部署网站 | `--mode deploy --site-name myproject` |
|
||||
| `create` | 创建新网站 | `--mode create --site-name myproject` |
|
||||
| `delete` | 删除网站 | `--mode delete --site-name myproject` |
|
||||
| `build` | 构建网站 | `--mode build --site-name myproject` |
|
||||
| `start` | 启动网站 | `--mode start --site-name myproject` |
|
||||
@ -33,157 +35,152 @@
|
||||
| `list` | 列出所有网站 | `--mode list` |
|
||||
| `logs` | 查看网站日志 | `--mode logs --site-name myproject` |
|
||||
|
||||
### 常用参数
|
||||
|
||||
| 参数 | 说明 | 默认值 |
|
||||
|------|------|--------|
|
||||
| `--mode` | 任务模式 | `deploy` |
|
||||
| `--site-name` | 网站名称 | `jingrow` |
|
||||
| `--git-repo` | Git仓库地址 | `http://git.jingrow.com:3000/jsite/jingrow` |
|
||||
| `--node-version` | Node.js版本 | `22` |
|
||||
| `--start-port` | 起始端口 | `3001` |
|
||||
| `--site-url` | 网站域名 | `starrbud.com` |
|
||||
|
||||
### 使用示例
|
||||
|
||||
#### 1. 完整部署新项目
|
||||
### 常用命令示例
|
||||
|
||||
```bash
|
||||
./install_jsite.sh \
|
||||
--mode deploy \
|
||||
--site-name myproject \
|
||||
--git-repo http://git.example.com/myproject \
|
||||
--site-url myproject.com \
|
||||
--public-ip 8.217.167.199
|
||||
```
|
||||
# 部署新网站
|
||||
./jsite.sh --mode deploy --site-name jingrow
|
||||
|
||||
#### 2. 创建新网站
|
||||
|
||||
```bash
|
||||
./install_jsite.sh \
|
||||
--mode create \
|
||||
--site-name myproject \
|
||||
--git-repo http://git.example.com/myproject \
|
||||
--site-url myproject.com
|
||||
```
|
||||
|
||||
#### 3. 构建和启动网站
|
||||
|
||||
```bash
|
||||
# 构建项目
|
||||
./install_jsite.sh --mode build --site-name myproject
|
||||
|
||||
# 启动项目
|
||||
./install_jsite.sh --mode start --site-name myproject
|
||||
```
|
||||
|
||||
#### 4. 管理网站状态
|
||||
|
||||
```bash
|
||||
# 查看状态
|
||||
./install_jsite.sh --mode status --site-name myproject
|
||||
|
||||
# 停止网站
|
||||
./install_jsite.sh --mode stop --site-name myproject
|
||||
# 启动网站
|
||||
./jsite.sh --mode start --site-name jingrow
|
||||
|
||||
# 重启网站
|
||||
./install_jsite.sh --mode restart --site-name myproject
|
||||
./jsite.sh --mode restart --site-name jingrow
|
||||
|
||||
# 查看网站状态
|
||||
./jsite.sh --mode status --site-name jingrow
|
||||
|
||||
# 查看所有网站
|
||||
./jsite.sh --mode list
|
||||
```
|
||||
|
||||
#### 5. 查看所有网站
|
||||
## 故障排除
|
||||
|
||||
### 常见错误及解决方案
|
||||
|
||||
#### 1. PM2进程未找到错误
|
||||
|
||||
**错误信息:**
|
||||
```
|
||||
[PM2][ERROR] Process or Namespace jingrow not found
|
||||
```
|
||||
|
||||
**原因:** 网站尚未部署或PM2进程未正确启动
|
||||
|
||||
**解决方案:**
|
||||
1. 首先检查网站是否存在:
|
||||
```bash
|
||||
./jsite.sh --mode status --site-name jingrow
|
||||
```
|
||||
|
||||
2. 如果网站不存在,先部署:
|
||||
```bash
|
||||
./jsite.sh --mode deploy --site-name jingrow
|
||||
```
|
||||
|
||||
3. 如果网站存在但未运行,启动网站:
|
||||
```bash
|
||||
./jsite.sh --mode start --site-name jingrow
|
||||
```
|
||||
|
||||
#### 2. 权限错误
|
||||
|
||||
**解决方案:**
|
||||
```bash
|
||||
./install_jsite.sh --mode list
|
||||
# 确保脚本有执行权限
|
||||
chmod +x jsite.sh
|
||||
|
||||
# 以root用户运行
|
||||
sudo ./jsite.sh --mode start --site-name jingrow
|
||||
```
|
||||
|
||||
#### 6. 查看日志
|
||||
#### 3. 端口冲突
|
||||
|
||||
**解决方案:**
|
||||
```bash
|
||||
./install_jsite.sh --mode logs --site-name myproject
|
||||
# 检查端口占用
|
||||
netstat -tlnp | grep :3001
|
||||
|
||||
# 停止占用端口的进程
|
||||
sudo kill -9 <进程ID>
|
||||
```
|
||||
|
||||
## 工作流程
|
||||
### 手动检查和修复
|
||||
|
||||
### 完整部署流程 (deploy)
|
||||
1. 创建jingrow用户
|
||||
2. 安装Docker(可选跳过)
|
||||
3. 安装Node.js和NVM
|
||||
4. 克隆项目代码
|
||||
5. 创建环境配置文件
|
||||
6. 安装项目依赖
|
||||
7. 安装PM2并启动项目
|
||||
8. 安装Traefik并配置反向代理
|
||||
#### 检查PM2状态
|
||||
```bash
|
||||
# 切换到jingrow用户
|
||||
su - jingrow
|
||||
|
||||
### 网站管理流程
|
||||
- **create**: 克隆代码 → 分配端口 → 创建配置 → 提示下一步
|
||||
- **build**: 安装依赖 → 构建项目
|
||||
- **start**: 检查状态 → 分配端口 → 启动PM2进程
|
||||
- **stop**: 停止PM2进程
|
||||
- **restart**: 重启PM2进程或启动(如果未运行)
|
||||
- **delete**: 停止进程 → 清理配置 → 删除文件
|
||||
# 加载nvm环境
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
|
||||
|
||||
## 目录结构
|
||||
# 查看PM2进程列表
|
||||
pm2 list
|
||||
|
||||
# 查看PM2日志
|
||||
pm2 logs
|
||||
```
|
||||
|
||||
#### 手动启动PM2进程
|
||||
```bash
|
||||
# 切换到jingrow用户
|
||||
su - jingrow
|
||||
|
||||
# 加载nvm环境
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
|
||||
|
||||
# 启动进程
|
||||
pm2 start jingrow
|
||||
|
||||
# 或者重新加载配置
|
||||
pm2 reload jingrow
|
||||
```
|
||||
|
||||
## 配置说明
|
||||
|
||||
### 环境变量
|
||||
|
||||
脚本支持以下环境变量配置:
|
||||
|
||||
- `SITE_NAME`: 网站名称(默认:jingrow)
|
||||
- `GIT_REPO`: Git仓库地址
|
||||
- `NODE_VERSION`: Node.js版本(默认:22)
|
||||
- `START_PORT`: 起始端口(默认:3001)
|
||||
- `SITE_URL`: 网站域名
|
||||
- `BACKEND_SERVER_URL`: 后端服务器地址
|
||||
|
||||
### 目录结构
|
||||
|
||||
```
|
||||
/home/jingrow/
|
||||
├── jsite/ # 网站项目目录
|
||||
│ ├── myproject1/ # 项目1
|
||||
│ ├── myproject2/ # 项目2
|
||||
│ └── site_port.json # 端口分配记录
|
||||
├── traefik-docker/ # Traefik配置目录
|
||||
│ └── conf.d/website/ # 网站配置文件
|
||||
└── .nvm/ # Node.js版本管理
|
||||
├── .nvm/ # Node版本管理器
|
||||
├── traefik-docker/ # Traefik配置
|
||||
└── ...
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **权限要求**:脚本需要root权限运行
|
||||
2. **端口管理**:自动分配端口,避免冲突
|
||||
3. **环境依赖**:确保系统支持Docker和Node.js
|
||||
4. **域名配置**:需要正确配置DNS解析
|
||||
5. **SSL证书**:Traefik自动申请Let's Encrypt证书
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **端口被占用**
|
||||
- 检查端口分配文件:`/home/jingrow/jsite/site_port.json`
|
||||
- 手动修改端口或停止占用进程
|
||||
|
||||
2. **PM2启动失败**
|
||||
- 检查项目依赖是否正确安装
|
||||
- 查看PM2日志:`pm2 logs <项目名>`
|
||||
- 确认package.json中有start脚本
|
||||
|
||||
3. **Traefik配置问题**
|
||||
- 检查配置文件:`/home/jingrow/traefik-docker/conf.d/website/`
|
||||
- 重启Traefik服务
|
||||
|
||||
4. **域名访问问题**
|
||||
- 确认DNS解析正确
|
||||
- 检查防火墙设置
|
||||
- 验证SSL证书状态
|
||||
|
||||
### 日志查看
|
||||
|
||||
```bash
|
||||
# PM2日志
|
||||
pm2 logs <项目名>
|
||||
|
||||
# Traefik日志
|
||||
docker logs <traefik容器名>
|
||||
|
||||
# 系统日志
|
||||
journalctl -u docker
|
||||
```
|
||||
1. 脚本需要以root权限运行
|
||||
2. 确保服务器有足够的磁盘空间和内存
|
||||
3. 确保网络连接正常,能够访问Git仓库
|
||||
4. 建议在生产环境使用前先在测试环境验证
|
||||
|
||||
## 更新日志
|
||||
|
||||
- **v2.0**: 整合jsite.sh功能,支持多种任务模式
|
||||
- **v1.0**: 基础部署功能
|
||||
### v1.1.0
|
||||
- 修复了start_site和restart_site函数的无限递归问题
|
||||
- 改进了错误处理和日志输出
|
||||
- 优化了PM2进程管理逻辑
|
||||
|
||||
## 许可证
|
||||
## 技术支持
|
||||
|
||||
MIT License
|
||||
如果遇到问题,请检查:
|
||||
1. 脚本执行日志
|
||||
2. PM2进程状态
|
||||
3. 系统资源使用情况
|
||||
4. 网络连接状态
|
||||
|
||||
|
||||
115
jsite.sh
115
jsite.sh
@ -436,9 +436,6 @@ get_available_port() {
|
||||
|
||||
# 检查项目是否已有分配的端口
|
||||
if [ -f "$port_file" ]; then
|
||||
# 确保jq工具已安装
|
||||
ensure_jq_installed
|
||||
|
||||
# 使用jq查询已分配的端口
|
||||
if command -v jq &> /dev/null; then
|
||||
local existing_port=$(jq -r ".$site_name // empty" "$port_file" 2>/dev/null || echo "")
|
||||
@ -465,15 +462,12 @@ get_available_port() {
|
||||
user_specified_port=true
|
||||
fi
|
||||
|
||||
if [ "$user_specified_port" = true ]; then
|
||||
# 用户传入了自定义端口,优先使用用户指定的端口
|
||||
# 检查用户指定的端口是否已被使用
|
||||
local port_available=true
|
||||
if [ -f "$port_file" ]; then
|
||||
# 确保jq工具已安装
|
||||
ensure_jq_installed
|
||||
|
||||
if command -v jq &> /dev/null; then
|
||||
if [ "$user_specified_port" = true ]; then
|
||||
# 用户传入了自定义端口,优先使用用户指定的端口
|
||||
# 检查用户指定的端口是否已被使用
|
||||
local port_available=true
|
||||
if [ -f "$port_file" ]; then
|
||||
if command -v jq &> /dev/null; then
|
||||
local used_ports=$(jq -r '.[]' "$port_file" 2>/dev/null || echo "")
|
||||
if echo "$used_ports" | grep -q "^$base_port$"; then
|
||||
port_available=false
|
||||
@ -492,9 +486,6 @@ get_available_port() {
|
||||
else
|
||||
# 用户指定的端口已被使用,使用最大端口号 + 1
|
||||
if [ -f "$port_file" ]; then
|
||||
# 确保jq工具已安装
|
||||
ensure_jq_installed
|
||||
|
||||
if command -v jq &> /dev/null; then
|
||||
local max_port=$(jq -r 'max(.[])' "$port_file" 2>/dev/null || echo "$base_port")
|
||||
if [ -n "$max_port" ] && [ "$max_port" != "null" ]; then
|
||||
@ -511,9 +502,6 @@ get_available_port() {
|
||||
else
|
||||
# 用户没有传入自定义端口,使用自动分配逻辑
|
||||
if [ -f "$port_file" ]; then
|
||||
# 确保jq工具已安装
|
||||
ensure_jq_installed
|
||||
|
||||
if command -v jq &> /dev/null; then
|
||||
# 使用jq找到最大端口号
|
||||
local max_port=$(jq -r 'max(.[])' "$port_file" 2>/dev/null || echo "$base_port")
|
||||
@ -547,9 +535,6 @@ save_port_assignment() {
|
||||
chown jingrow:jingrow /home/jingrow/jsite
|
||||
fi
|
||||
|
||||
# 确保jq工具已安装
|
||||
ensure_jq_installed
|
||||
|
||||
# 检查jq是否可用
|
||||
if command -v jq &> /dev/null; then
|
||||
# 使用jq保存到JSON文件
|
||||
@ -601,9 +586,6 @@ get_or_assign_port() {
|
||||
local already_saved=false
|
||||
|
||||
if [ -f "$port_file" ]; then
|
||||
# 确保jq工具已安装
|
||||
ensure_jq_installed
|
||||
|
||||
if command -v jq &> /dev/null; then
|
||||
local existing_port=$(jq -r ".$site_name // empty" "$port_file" 2>/dev/null || echo "")
|
||||
if [ -n "$existing_port" ] && [ "$existing_port" != "null" ] && [ "$existing_port" != "empty" ]; then
|
||||
@ -640,9 +622,6 @@ show_port_assignments() {
|
||||
fi
|
||||
|
||||
log_info "当前端口分配情况:"
|
||||
# 确保jq工具已安装
|
||||
ensure_jq_installed
|
||||
|
||||
if command -v jq &> /dev/null; then
|
||||
# 使用jq格式化输出
|
||||
jq -r 'to_entries[] | " - \(.key): \(.value)"' "$port_file" 2>/dev/null || log_warning "无法解析端口分配文件"
|
||||
@ -1142,45 +1121,6 @@ install_docker() {
|
||||
log_success "将jingrow用户添加到docker组"
|
||||
}
|
||||
|
||||
# 6.1 安装jq工具(如果未安装)
|
||||
install_jq() {
|
||||
log_info "检查jq工具安装状态..."
|
||||
|
||||
if command -v jq &> /dev/null; then
|
||||
log_warning "jq工具已安装"
|
||||
else
|
||||
log_info "开始安装jq工具..."
|
||||
|
||||
# 设置非交互式环境
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
export DEBCONF_NONINTERACTIVE_SEEN=true
|
||||
|
||||
# 更新包索引
|
||||
apt-get update
|
||||
|
||||
# 安装jq工具
|
||||
apt-get install -y --force-yes jq
|
||||
|
||||
if command -v jq &> /dev/null; then
|
||||
log_success "jq工具安装完成"
|
||||
else
|
||||
log_error "jq工具安装失败"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# 6.2 确保jq工具已安装
|
||||
ensure_jq_installed() {
|
||||
if ! command -v jq &> /dev/null; then
|
||||
log_warning "jq工具未安装,正在安装..."
|
||||
if ! install_jq; then
|
||||
log_error "jq工具安装失败,无法处理JSON文件"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# 7. 启动traefik
|
||||
start_traefik() {
|
||||
log_info "启动traefik服务..."
|
||||
@ -1532,9 +1472,6 @@ delete_site() {
|
||||
# 删除端口分配记录
|
||||
log_info "删除端口分配记录..."
|
||||
local port_file="$JSITE_BASE_DIR/site_port.json"
|
||||
# 确保jq工具已安装
|
||||
ensure_jq_installed
|
||||
|
||||
if [ -f "$port_file" ] && command -v jq &> /dev/null; then
|
||||
if jq "del(.$SITE_NAME)" "$port_file" > "${port_file}.tmp" 2>/dev/null; then
|
||||
mv "${port_file}.tmp" "$port_file"
|
||||
@ -1604,9 +1541,31 @@ build_site() {
|
||||
|
||||
# 启动网站
|
||||
start_site() {
|
||||
local status=$(get_site_status "$SITE_NAME")
|
||||
|
||||
if [ "$status" = "not_exists" ]; then
|
||||
log_error "网站 $SITE_NAME 不存在,请先部署网站"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$status" = "running" ]; then
|
||||
log_warning "网站 $SITE_NAME 已在运行中"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log_info "启动网站: $SITE_NAME"
|
||||
restart_site
|
||||
return $?
|
||||
|
||||
# 尝试启动PM2进程
|
||||
if ! su - "jingrow" -c "
|
||||
export NVM_DIR=\"\$HOME/.nvm\"
|
||||
[ -s \"\$NVM_DIR/nvm.sh\" ] && \. \"\$NVM_DIR/nvm.sh\"
|
||||
pm2 start '$SITE_NAME'
|
||||
"; then
|
||||
log_error "网站启动失败"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_success "网站 $SITE_NAME 启动成功"
|
||||
}
|
||||
|
||||
# 停止网站
|
||||
@ -1657,8 +1616,15 @@ restart_site() {
|
||||
fi
|
||||
else
|
||||
# 如果未运行,则启动
|
||||
start_site
|
||||
return $?
|
||||
log_info "网站未运行,正在启动..."
|
||||
if ! su - "jingrow" -c "
|
||||
export NVM_DIR=\"\$HOME/.nvm\"
|
||||
[ -s \"\$NVM_DIR/nvm.sh\" ] && \. \"\$NVM_DIR/nvm.sh\"
|
||||
pm2 start '$SITE_NAME'
|
||||
"; then
|
||||
log_error "网站启动失败"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
log_success "网站 $SITE_NAME 重启成功"
|
||||
@ -1789,9 +1755,6 @@ main() {
|
||||
log_warning "跳过Docker安装"
|
||||
fi
|
||||
|
||||
# 安装jq工具(用于处理JSON文件)
|
||||
install_jq
|
||||
|
||||
install_nodejs
|
||||
|
||||
if ! clone_jsite_project; then
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user