提交 470c849b authored 作者: 陈泽健's avatar 陈泽健

feat(scripts): 主脚本模块化拆分函数,新增中间件自动化部署脚本

- 创建了新的中间件部署脚本 auto_middleware_install.sh
- 实现了 MySQL 数据库的 Docker 部署功能,包括初始化和定时备份
- 实现了 EMQX 消息队列的 Docker 部署功能
- 实现了 Redis 缓存的 Docker 部署功能
- 实现了 FastDFS 文件存储的 Docker 部署功能
- 实现了 ngrok 内网穿透的 Docker 部署功能
- 实现了 Nacos 配置中心的 Docker 部署功能
- 实现了 Nginx 反向代理的 Docker 部署功能
- 添加了需求文档说明模块化拆分方案
上级 50a5ba3c
# 主脚本模块化拆分中间件
## 代码路径
- 需调用代码路径:[自动化部署脚本/x86架构/新统一平台/auto_middleware_install.sh]
- 主脚本:[自动化部署脚本/x86架构/新统一平台/new_auto.sh]
## 功能需求
### 功能目标
**目标:** 当前主脚本代码量过于庞大,不利于维护,现需将中间件的相关部署函数拆分出来,通过在主脚本中调用auto_middleware_install.sh,带上中间件服务的传参实现部署。
### 需求描述
#### 调用逻辑
- 设置一个字段`middleware_type`,接收需部署的中间件服务名称,字段支持数组,支持多个中间件服务同时部署
- redis:`redis`
- mysql:`mysql`
- emqx:`emqx`
- fdfs:`fdfs`
- ngrok:`ngrok`
- nacos:`nacos`
- nginx:`nginx`
- 调用方式:
- 获取脚本所在目录,使用绝对路径调用
- 使用环境变量传递中间件类型,多个服务用空格分隔
```bash
# 获取脚本所在目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# 单个服务部署
middleware_type=redis "$SCRIPT_DIR/auto_middleware_install.sh"
# 多个服务部署(空格分隔)
middleware_type="redis mysql emqx" "$SCRIPT_DIR/auto_middleware_install.sh"
```
- 接收脚本执行的返回参数,并使用log函数打印日志
- 0:部署成功,使用`log "INFO"`打印日志
- 1:部署失败,使用`log "ERROR"`打印错误日志,使用`return 1`退出当前函数部署操作
- 执行时机:
- 暂时先跟在docker_x86之后再执行
#### 脚本设计要求
- 主入口函数:
-`auto_middleware_install.sh`中增加主入口函数`install_middleware()`
- 主入口函数负责:
- 解析`middleware_type`环境变量
- 根据参数调用对应的中间件部署函数
- 返回部署结果
- log函数依赖:
- 脚本中的log函数与主脚本保持一致
- 在主脚本中先source导入`auto_middleware_install.sh`,再调用`install_middleware`函数
- 变量初始化:
- 在主入口函数中初始化以下变量:
- `sudoset`:sudo命令前缀(根据用户权限判断)
- `SUDO`:sudo命令(兼容不同函数中的变量名)
- `server_ip`:服务器IP地址(由主脚本传入)
#### 中间件部署函数列表
- `mysql_x86()` - MySQL数据库部署
- `emqx_x86()` - EMQX消息队列部署
- `redis_x86()` - Redis缓存部署
- `fastfds_x86()` - FastDFS文件存储部署
- `ngrok_x86()` - ngrok内网穿透部署
- `nacos_x86()` - Nacos配置中心部署
- `nginx_x86()` - Nginx反向代理部署
## 规范文档
- 代码规范: `Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md`
- 问题总结: `Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md`
- 方法总结: `Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md`
- 文档规范: `Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md`
- 测试规范: `Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md`
---
\ No newline at end of file
# 主脚本模块化拆分中间件计划执行文档
## 需求来源
- 需求文档:`Docs/PRD/自动化部署脚本/新统一平台/需求文档/_PRD_主脚本模块化拆分中间件_需求文档.md`
---
## 实现计划
### 1. 代码结构设计
```bash
auto_middleware_install.sh
├── mysql_x86() # 已有函数
├── emqx_x86() # 已有函数
├── redis_x86() # 已有函数
├── fastfds_x86() # 已有函数
├── ngrok_x86() # 已有函数
├── nacos_x86() # 已有函数
├── nginx_x86() # 已有函数
└── install_middleware() # 新增主入口函数
├── 初始化变量(sudoset/SUDO/server_ip)
├── 解析middleware_type环境变量
├── 遍历调用对应的中间件函数
└── 返回部署结果
```
### 2. 实现步骤
- [ ] 在auto_middleware_install.sh末尾增加install_middleware()主入口函数
- [ ] 实现变量初始化逻辑(sudoset/SUDO/server_ip)
- [ ] 实现middleware_type参数解析
- [ ] 实现中间件函数映射和调用逻辑
- [ ] 实现返回值处理和日志打印
- [ ] 在主脚本new_auto.sh中source导入auto_middleware_install.sh
- [ ] 在主脚本docker_x86后调用install_middleware函数
### 3. 技术要点
#### 3.1 变量初始化
```bash
# 初始化sudo相关变量
if [[ $(id -u) -ne 0 ]]; then
sudoset="sudo"
SUDO="sudo"
else
sudoset=""
SUDO=""
fi
# 获取服务器IP
server_ip=$(ip -4 addr show scope global | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -n1)
if [[ -z "$server_ip" ]]; then
server_ip=$(hostname -I | awk '{print $1}')
fi
```
#### 3.2 参数解析
```bash
# 解析middleware_type环境变量
local middlewares="${middleware_type:-}"
if [[ -z "$middlewares" ]]; then
log "ERROR" "未指定中间件类型"
return 1
fi
```
#### 3.3 中间件函数映射
```bash
# 中间件名称到函数的映射
declare -A middleware_map=(
["mysql"]="mysql_x86"
["emqx"]="emqx_x86"
["redis"]="redis_x86"
["fdfs"]="fastfds_x86"
["ngrok"]="ngrok_x86"
["nacos"]="nacos_x86"
["nginx"]="nginx_x86"
)
```
#### 3.4 主脚本调用方式
```bash
# 导入中间件部署脚本
source "$SCRIPT_DIR/auto_middleware_install.sh"
# 调用部署函数
middleware_type="redis mysql" install_middleware
```
### 4. 函数位置
- auto_middleware_install.sh:在所有中间件函数之后添加install_middleware主入口
- new_auto.sh:在docker_x86函数之后添加source导入和调用
### 5. 返回值定义
| 返回值 | 含义 | 处理方式 |
|--------|------|----------|
| 0 | 全部部署成功 | 继续执行 |
| 1 | 存在部署失败 | log ERROR + return 1 |
### 6. 中间件部署顺序
```
建议部署顺序:mysql → redis → emqx → nacos → fdfs → ngrok → nginx
(MySQL数据库应优先部署,其他中间件可能依赖它)
```
---
## 代码修改
### 修改文件
1. `自动化部署脚本/x86架构/新统一平台/auto_middleware_install.sh` - 添加主入口函数
2. `自动化部署脚本/x86架构/新统一平台/new_auto.sh` - 添加source导入和调用
---
## 测试计划
- [ ] 测试单个中间件部署(middleware_type=redis)
- [ ] 测试多个中间件部署(middleware_type="redis mysql")
- [ ] 测试全部中间件部署
- [ ] 测试无效中间件名称
- [ ] 测试空参数场景
- [ ] 测试部署失败场景
---
## 优化功能回填
> 本章节用于记录实现过程中发现的优化点和改进措施
| 日期 | 优化项 | 状态 | 备注 |
|------|--------|------|------|
| - | - | - | - |
#==============================================================#
# 函数名: mysql_x86
# 功能: 部署基于 Docker 的 MySQL 服务(x86 架构)
# 说明: 1. 检查本地是否已运行 umysql 容器
# 2. 若无,则从离线 tar 加载镜像并启动容器
# 3. 初始化数据库:创建用户、数据库、授权
# 4. 配置定时备份脚本(每天 13:00)
# 作者: [ubains]
# 日期: $(date +%Y-%m-%d)
#--------------------------------------------------------------#
# 参数: 无
# 返回: 0: 成功
# 1: 失败
#--------------------------------------------------------------#
# 依赖: docker, crond (或 cronie), sudo
# 注意: 请确保以下资源已上传:
# - /data/temp/umysql.tar.gz
# - $PWD/UbainsmysqlBakUp.sh
# 并确保宿主机 /data/middleware/mysql/ 目录存在
#==============================================================#
function mysql_x86() {
# --- 配置参数 ---
local container_name="umysql"
local image_tar="/data/temp/umysql.tar.gz"
local image_name="139.9.60.86:5000/umysql:v5.2"
local image_id="4c5574ba4b04"
local mysql_root_password="dNrprU&2S"
local mysql_port="8306"
local host_data_dir="/data/middleware/mysql"
local backup_script_src="$PWD/UbainsmysqlBakUp.sh"
local backup_script_dst="/usr/local/docker/UbainsmysqlBakUp.sh"
local cron_user="root"
log "INFO" "=================================================================="
log "INFO" "开始部署 MySQL 服务 (Docker 版, x86)"
log "INFO" "=================================================================="
# 自动判断是否需要 sudo
local SUDO=""
if [[ $(id -u) -ne 0 ]]; then
if command -v sudo >/dev/null; then
SUDO="sudo"
else
log "ERROR" "⛔ 当前不是 root 用户,且系统未安装 sudo,无法执行操作"
return 1
fi
fi
# ------------------- 检查容器是否已运行 -------------------
log "INFO" "🔍 检查容器 '$container_name' 是否已运行..."
if $SUDO docker ps --format '{{.Names}}' | grep -qw "$container_name"; then
log "INFO" "✅ 容器 '$container_name' 已在运行"
return 0
fi
# ------------------- 检查镜像是否存在 -------------------
log "INFO" "🔍 检查镜像 $image_name 是否存在..."
if $SUDO docker images --format '{{.Repository}}:{{.Tag}}' | grep -qw "$image_name"; then
log "INFO" "✅ 镜像 $image_name 已存在"
else
log "WARN" "❌ 镜像 $image_name 不存在,开始加载离线包..."
if [[ ! -f "$image_tar" ]]; then
log "ERROR" "⛔ 镜像文件不存在: $image_tar"
return 1
fi
if $SUDO docker load -i "$image_tar"; then
log "INFO" "🎉 镜像加载成功"
else
log "ERROR" "⛔ 镜像加载失败,请检查文件完整性"
return 1
fi
fi
# ------------------- 启动容器 -------------------
log "INFO" "🚀 正在启动 MySQL 容器: $container_name"
$SUDO docker run -d \
--name "$container_name" \
--mac-address="02:42:ac:11:00:05" \
-p "${mysql_port}:3306" \
-v "${host_data_dir}/conf/my.cnf:/etc/mysql/my.cnf" \
-v "${host_data_dir}/conf.d:/etc/mysql/conf.d" \
-v "${host_data_dir}/log:/var/log/mysql" \
-v "${host_data_dir}/data:/var/lib/mysql" \
-v "/etc/localtime:/etc/localtime:ro" \
--restart=always \
-e "MYSQL_ROOT_PASSWORD=$mysql_root_password" \
"$image_name"
if [[ $? -ne 0 ]]; then
log "ERROR" "⛔ 容器启动失败,请检查端口占用或磁盘权限"
log "INFO" "📄 查看最近容器日志以排查问题..."
$SUDO docker logs "$container_name" 2>/dev/null || true
return 1
fi
sleep 120
log "INFO" "✅ 容器启动成功,等待 MySQL 服务就绪..."
# ------------------- 初始化数据库:创建用户、数据库、授权、导入数据 -------------------
log "INFO" "🔧 初始化数据库:创建用户、数据库、授权..."
# 先拷贝 nacos_mysql.sql 到容器内
log "INFO" "📁 拷贝 /data/temp/nacos_mysql.sql 到容器 '$container_name' 内..."
if $SUDO docker cp "/data/temp/nacos_mysql.sql" "$container_name:/tmp/nacos_mysql.sql"; then
log "INFO" "✅ SQL 文件已成功拷贝到容器内"
else
log "ERROR" "⛔ 无法拷贝 nacos_mysql.sql 到容器,请检查文件路径或容器状态"
return 1
fi
# 先拷贝 devops_voice.sql 到容器内
log "INFO" "📁 拷贝 /data/temp/devops_voice.sql 到容器 '$container_name' 内..."
if $SUDO docker cp "/data/temp/devops_voice.sql" "$container_name:/tmp/devops_voice.sql"; then
log "INFO" "✅ SQL 文件已成功拷贝到容器内"
else
log "ERROR" "⛔ 无法拷贝 devops_voice.sql 到容器,请检查文件路径或容器状态"
return 1
fi
# 先拷贝 huazhao2.sql 到容器内
log "INFO" "📁 拷贝 /data/temp/huazhao2.sql 到容器 '$container_name' 内..."
if $SUDO docker cp "/data/temp/huazhao2.sql" "$container_name:/tmp/huazhao2.sql"; then
log "INFO" "✅ SQL 文件已成功拷贝到容器内"
else
log "ERROR" "⛔ 无法拷贝 huazhao2.sql 到容器,请检查文件路径或容器状态"
return 1
fi
# 先拷贝 offline.sql 到容器内
log "INFO" "📁 拷贝 /data/temp/offline.sql 到容器 '$container_name' 内..."
if $SUDO docker cp "/data/temp/offline.sql" "$container_name:/tmp/offline.sql"; then
log "INFO" "✅ SQL 文件已成功拷贝到容器内"
else
log "ERROR" "⛔ 无法拷贝 offline.sql 到容器,请检查文件路径或容器状态"
return 1
fi
# 定义要执行的 SQL 命令序列(注意顺序)
local init_sql=(
"CREATE USER IF NOT EXISTS 'nacos'@'%' IDENTIFIED BY 'nacos2025';"
"CREATE USER IF NOT EXISTS 'mysqluser'@'%' IDENTIFIED BY 'dNrprU&2S';"
"CREATE DATABASE IF NOT EXISTS nacos_mysql CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
"CREATE DATABASE IF NOT EXISTS devops CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
"CREATE DATABASE IF NOT EXISTS devops_voice CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
"CREATE DATABASE IF NOT EXISTS offline CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
"CREATE DATABASE IF NOT EXISTS huazhao2 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
"GRANT ALL PRIVILEGES ON nacos_mysql.* TO 'nacos'@'%';"
"GRANT ALL PRIVILEGES ON devops.* TO 'mysqluser'@'%';"
"FLUSH PRIVILEGES;"
"ALTER TABLE devops.cmdb_roomdevice ADD COLUMN ICON_H5 VARCHAR(64) NULL;"
"ALTER TABLE devops.cmdb_company ADD COLUMN SMART_HOME INT NULL DEFAULT 0;"
"ALTER TABLE devops.cmdb_roomdevice ADD COLUMN IS_H5 INT NULL DEFAULT 0;"
"ALTER TABLE devops.cmdb_roomdevice ADD COLUMN MAC_ADDR VARCHAR(64) NULL;"
"ALTER TABLE devops.cmdb_roomdevice ADD COLUMN VERSION VARCHAR(64) NULL;"
"ALTER TABLE devops.cmdb_roomganged ADD COLUMN COMPANY_ID INT NULL;"
"ALTER TABLE devops.cmdb_company ADD COLUMN REMOTE_START INT NULL DEFAULT 0;"
"ALTER TABLE devops.cmdb_company ADD COLUMN REMOTE_END INT NULL DEFAULT 0;"
"ALTER TABLE devops.cmdb_companyauthentication ADD COLUMN APPLYDESCRIBE VARCHAR(256) NULL;"
"ALTER TABLE devops.cmdb_companyauthentication ADD COLUMN APPLYFEEDBACK VARCHAR(256) NULL;"
"FLUSH PRIVILEGES;"
"CREATE TABLE devops.cmdb_inspection (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
master_id INT DEFAULT NULL,
name VARCHAR(128) DEFAULT NULL,
status INT DEFAULT '0',
createTime DATETIME(6) DEFAULT NULL,
updateTime DATETIME(6) DEFAULT NULL,
createUser_id INT DEFAULT NULL,
runWay INT DEFAULT '0',
runType INT DEFAULT '0',
runDate VARCHAR(128) DEFAULT NULL,
runStartTime DATETIME(6) DEFAULT NULL,
runEndTime DATETIME(6) DEFAULT NULL,
inspectionTime DATETIME(6) DEFAULT NULL,
isEnable INT DEFAULT '0',
inspectionUser_id INT DEFAULT NULL,
company_id INT DEFAULT NULL,
delflag INT DEFAULT '0',
message_id INT DEFAULT NULL,
INDEX idx_master_id (master_id),
INDEX idx_createUser_id (createUser_id),
INDEX idx_inspectionUser_id (inspectionUser_id),
INDEX idx_company_id (company_id),
INDEX idx_message_id (message_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"
"ALTER TABLE ubains.rms_manage_company ADD COLUMN cnum_approvals_num INT NULL;"
"ALTER TABLE ubains.rms_manage_company ADD COLUMN company_process_id BIGINT NULL;"
"ALTER TABLE ubains.rms_manage_conference ADD COLUMN is_send_project_app INT NULL DEFAULT 0;"
"ALTER TABLE ubains.rms_manage_conference ADD COLUMN room_number VARCHAR(50) NULL;"
"ALTER TABLE ubains.rms_timing_task ADD COLUMN is_send_project_app INT NULL DEFAULT 0;"
"ALTER TABLE ubains.rms_manage_conference ADD COLUMN cloudlink_room_id VARCHAR(50) NULL;"
"ALTER TABLE ubains.rms_manage_conference ADD COLUMN polycom_room_id VARCHAR(50) NULL;"
"ALTER TABLE ubains.rms_meeting_approval ADD COLUMN project_app_note INT NULL DEFAULT 0;"
"ALTER TABLE ubains.rms_manage_conference ADD COLUMN conference_class VARCHAR(50) NULL;"
"ALTER TABLE ubains.rms_meeting_message ADD COLUMN cascade_meeting INT NULL;"
"ALTER TABLE ubains.rms_meeting_message ADD COLUMN cloudchairman_pw VARCHAR(255) NULL;"
"ALTER TABLE ubains.rms_meeting_message ADD COLUMN cloud_portal_multi_channel_id VARCHAR(50) NULL;"
"ALTER TABLE ubains.rms_meeting_message ADD COLUMN cloud_multi_channel_guest_pw VARCHAR(20) NULL;"
)
# 执行前半部分 SQL
for sql in "${init_sql[@]}"; do
$SUDO docker exec "$container_name" mysql -uroot -p"$mysql_root_password" -e "$sql"
if [[ $? -ne 0 ]]; then
log "ERROR" "⛔ 执行SQL语句失败: $sql"
log "INFO" "📄 输出容器最近日志..."
$SUDO docker logs "$container_name" | tail -30
return 1
fi
done
# 执行 source 导入 nacos_mysql.sql 到 nacos_mysql 数据库
log "INFO" "📥 正在导入 nacos_mysql.sql 到数据库 nacos_mysql..."
$SUDO docker exec "$container_name" mysql -uroot -p"$mysql_root_password" -D nacos_mysql -e "source /tmp/nacos_mysql.sql"
if [[ $? -eq 0 ]]; then
log "INFO" "✅ nacos_mysql.sql 数据导入成功"
# 在导入数据后执行 IP 替换
log "INFO" "🔄 正在更新配置中的 IP 地址..."
$SUDO docker exec "$container_name" mysql -uroot -p"$mysql_root_password" -D nacos_mysql -e \
"UPDATE config_info SET content = REPLACE(content, '192.168.5.234', '"$server_ip"')
WHERE data_id IN ('auth-sso-auth-dev.yml','auth-sso-gateway-dev.yml','auth-sso-system-dev.yml');"
log "INFO" "🔄 正在保存配置..."
$SUDO docker exec "$container_name" mysql -uroot -p"$mysql_root_password" -D nacos_mysql -e \
"FLUSH PRIVILEGES;"
if [[ $? -eq 0 ]]; then
log "INFO" "✅ 配置保存成功"
else
log "ERROR" "⛔ 配置保存失败"
return 1
fi
else
log "ERROR" "⛔ 数据导入失败,请检查 nacos_mysql.sql 文件内容或权限"
log "INFO" "📄 输出容器日志以排查问题..."
$SUDO docker logs "$container_name" | tail -50
return 1
fi
sleep 60
# 执行 source 导入 devops_voice.sql 到 devops_voice 数据库
log "INFO" "📥 正在导入 devops_voice.sql 到数据库 devops_voice..."
$SUDO docker exec "$container_name" mysql -uroot -p"$mysql_root_password" -D devops_voice -e "source /tmp/devops_voice.sql"
if [[ $? -eq 0 ]]; then
log "INFO" "✅ devops_voice.sql 数据导入成功"
else
log "ERROR" "⛔ 数据导入失败,请检查 devops_voice.sql 文件内容或权限"
log "INFO" "📄 输出容器日志以排查问题..."
$SUDO docker logs "$container_name" | tail -50
return 1
fi
sleep 60
# 执行 source 导入 huazhao2.sql 到 huazhao2 数据库
log "INFO" "📥 正在导入 huazhao2.sql 到数据库 huazhao2..."
$SUDO docker exec "$container_name" mysql -uroot -p"$mysql_root_password" -D huazhao2 -e "source /tmp/huazhao2.sql"
if [[ $? -eq 0 ]]; then
log "INFO" "✅ huazhao2.sql 数据导入成功"
else
log "ERROR" "⛔ 数据导入失败,请检查 huazhao2.sql 文件内容或权限"
log "INFO" "📄 输出容器日志以排查问题..."
$SUDO docker logs "$container_name" | tail -50
return 1
fi
sleep 60
# 执行 source 导入 offline.sql 到 offline 数据库
log "INFO" "📥 正在导入 offline.sql 到数据库 offline..."
$SUDO docker exec "$container_name" mysql -uroot -p"$mysql_root_password" -D offline -e "source /tmp/offline.sql"
if [[ $? -eq 0 ]]; then
log "INFO" "✅ offline.sql 数据导入成功"
else
log "ERROR" "⛔ 数据导入失败,请检查 offline.sql 文件内容或权限"
log "INFO" "📄 输出容器日志以排查问题..."
$SUDO docker logs "$container_name" | tail -50
return 1
fi
sleep 60
# ------------------- 提升用户权限 -------------------
for user in "root" "mysqluser"; do
$SUDO docker exec "$container_name" mysql -u"root" -p"$mysql_root_password" -e \
"UPDATE mysql.user SET Grant_priv='Y', Super_priv='Y' WHERE User='$user' AND Host='%'; FLUSH PRIVILEGES;" 2>/dev/null
done
log "INFO" "✅ 用户权限提升完成"
# ------------------- 部署备份脚本 -------------------
log "INFO" "📦 部署备份脚本到容器..."
$SUDO mkdir -p "$(dirname "$backup_script_dst")"
if $SUDO cp -f "$backup_script_src" "$backup_script_dst"; then
$SUDO chmod +x "$backup_script_dst"
log "INFO" "✅ 备份脚本已复制到: $backup_script_dst"
else
log "ERROR" "⛔ 备份脚本复制失败,请检查源文件是否存在"
return 1
fi
# ------------------- 配置定时任务 -------------------
log "INFO" "⏰ 配置定时备份任务 (每天 13:00)"
local cron_job="0 13 * * * bash $backup_script_dst"
if $SUDO crontab -u "$cron_user" -l 2>/dev/null | grep -Fq "$backup_script_dst"; then
log "INFO" "✅ 定时任务已存在"
else
( $SUDO crontab -u "$cron_user" -l 2>/dev/null; echo "$cron_job" ) | $SUDO crontab -u "$cron_user" -
if [[ $? -eq 0 ]]; then
log "INFO" "✅ 定时任务添加成功"
else
log "ERROR" "⛔ 定时任务添加失败"
return 1
fi
fi
# ------------------- 重启 crond -------------------
log "INFO" "🔄 重启 crond 服务..."
if command -v systemctl >/dev/null; then
$SUDO systemctl restart crond || $SUDO systemctl restart cron
else
$SUDO service crond restart || $SUDO service cron restart
fi
log "INFO" "✅ crond 服务已重启"
# ------------------- 最终状态输出 -------------------
log "INFO" "🎉 MySQL 部署完成!"
$SUDO docker ps --filter "name=$container_name" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
return 0
}
#x86架构安装mqtt
function emqx_x86()
{
# ------------------- 定义变量 -------------------
local container_name="uemqx"
local image_tar="/data/temp/uemqx5.8.7.tar.gz"
local image_name="emqx/emqx:5.8.7"
local host_config_dir="/data/middleware/emqx/config"
local host_dir="/data/middleware/emqx"
log "INFO" "=================================================================="
log "INFO" "开始部署 EMQX 服务 (Docker 版, x86)"
log "INFO" "=================================================================="
# ------------------- 检查容器是否已运行 -------------------
log "INFO" "🔍 检查 EMQX 容器是否已运行..."
if $sudoset docker ps --format '{{.Names}}' | grep -wq "$container_name"; then
log "INFO" "✅ 容器 '$container_name' 已在运行。"
return 0
fi
# ------------------- 检查镜像是否存在 -------------------
log "INFO" "🔍 检查 EMQX 镜像是否存在..."
if $sudoset docker images --format '{{.Repository}}:{{.Tag}}' | grep -wq "$image_name"; then
log "INFO" "✅ 镜像 $image_name 已存在。"
else
log "WARN" "❌ 镜像 $image_name 不存在,开始加载离线包..."
if [[ ! -f "$image_tar" ]]; then
log "ERROR" "⛔ 镜像文件不存在: $image_tar"
return 1
fi
if $sudoset docker load -i "$image_tar"; then
log "INFO" "🎉 镜像加载成功"
else
log "ERROR" "⛔ 镜像加载失败,请检查文件完整性"
return 1
fi
fi
# EMQX 容器使用用户 1000:1000
$sudoset chown -R 1000:1000 "$host_dir"/{data,log}
log "INFO" "✅ 目录创建完成,权限已设置"
# ------------------- 启动 EMQX 容器 -------------------
log "INFO" "🚀 正在启动 EMQX 容器: $container_name ..."
$sudoset docker run -d \
--name "$container_name" \
--mac-address="02:42:ac:12:00:06" \
--privileged \
--restart=always \
-p 1883:1883 \
-p 8083:8083 \
-p 8883:8883 \
-v "$host_config_dir/emqx.conf:/opt/emqx/etc/emqx.conf:ro" \
-v "$host_config_dir/auth-built-in-db-bootstrap.csv:/opt/emqx/etc/auth-built-in-db-bootstrap.csv:ro" \
-v "$host_config_dir/acl.conf:/opt/emqx/etc/acl.conf:ro" \
-v "$host_dir/data:/opt/emqx/data" \
-v "$host_dir/log:/opt/emqx/log" \
"$image_name"
if [ $? -ne 0 ]; then
log "ERROR" "⛔ 容器启动失败"
return 1
fi
log "INFO" "✅ EMQX 容器启动成功,等待初始化..."
sleep 5
# ------------------- 验证容器状态 -------------------
if $sudoset docker ps --format '{{.Names}}' | grep -wq "$container_name"; then
log "INFO" "🎉 EMQX 部署完成!"
$sudoset docker ps --filter "name=$container_name" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
else
log "ERROR" "⛔ 容器启动后未运行,请检查日志: docker logs $container_name"
return 1
fi
return 0
}
function redis_x86()
{
# ------------------- 定义变量 -------------------
local container_name="uredis"
local image_tar="/data/temp/redis8.2.2.tar.gz"
local image_name="139.9.60.86:5000/redis:v3"
local image_id="3bd8c109f88b"
local redis_conf_host="/data/middleware/redis/config/redis.conf"
local redis_data_host="/data/middleware/redis/data"
local redis_port="6379"
log "INFO" "=================================================================="
log "INFO" "开始部署 Redis 服务 (Docker 版, x86)"
log "INFO" "=================================================================="
# ------------------- 检查容器是否已运行 -------------------
log "INFO" "🔍 检查 Redis 容器是否已运行..."
if $sudoset docker ps --format '{{.Names}}' | grep -wq "$container_name"; then
log "INFO" "✅ 容器 '$container_name' 已在运行。"
return 0
fi
# ------------------- 自动配置 sysctl -------------------
log "INFO" "🔧 配置系统参数: /etc/sysctl.conf"
local sysctl_config="
#新增
net.core.somaxconn = 511
vm.overcommit_memory = 1
"
# 检查是否已存在配置,避免重复添加
if ! grep -Fq "#新增" /etc/sysctl.conf; then
echo "$sysctl_config" | $sudoset tee -a /etc/sysctl.conf > /dev/null
if [ $? -eq 0 ]; then
log "INFO" "✅ sysctl 配置已追加"
else
log "ERROR" "⛔ 写入 /etc/sysctl.conf 失败,请检查权限"
return 1
fi
else
log "INFO" "✅ sysctl 配置已存在,跳过添加"
fi
# 应用配置
$sudoset sysctl -p > /dev/null 2>&1
if [ $? -eq 0 ]; then
log "INFO" "✅ sysctl 参数已生效"
else
log "WARN" "⚠️ sysctl -p 执行可能有警告,继续执行"
fi
# ------------------- 检查镜像是否存在 -------------------
log "INFO" "🔍 检查 Redis 镜像是否存在..."
if $sudoset docker images --format '{{.Repository}}:{{.Tag}}' | grep -wq "$image_name"; then
log "INFO" "✅ 镜像 $image_name 已存在。"
else
log "WARN" "❌ 镜像 $image_name 不存在,开始加载离线包..."
if [[ ! -f "$image_tar" ]]; then
log "ERROR" "⛔ 镜像文件不存在: $image_tar"
return 1
fi
if $sudoset docker load -i "$image_tar"; then
log "INFO" "🎉 镜像加载成功"
else
log "ERROR" "⛔ 镜像加载失败,请检查文件完整性"
return 1
fi
fi
# ------------------- 启动 Redis 容器 -------------------
log "INFO" "🚀 正在启动 Redis 容器: $container_name ..."
$sudoset docker run -d \
--name "$container_name" \
--security-opt seccomp=unconfined \
--network host \
-v "$redis_conf_host:/etc/redis/redis.conf" \
-v "$redis_data_host:/data" \
-v "/etc/localtime:/etc/localtime:ro" \
--restart=always \
"$image_name" \
redis-server /etc/redis/redis.conf --appendonly yes
if [ $? -ne 0 ]; then
log "ERROR" "⛔ 容器启动失败"
return 1
fi
log "INFO" "✅ Redis 容器启动成功,等待初始化..."
sleep 5
# ------------------- 验证状态 -------------------
if $sudoset docker ps --format '{{.Names}}' | grep -wq "$container_name"; then
log "INFO" "🎉 Redis 部署完成!"
$sudoset docker ps --filter "name=$container_name" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
else
log "ERROR" "⛔ 容器启动后未运行,请检查日志: docker logs $container_name"
return 1
fi
return 0
}
#安装fastfds
function fastfds_x86()
{
# ------------------- 定义变量 -------------------
local image_tar="/data/temp/ufastdfs.tar.gz"
local image_name="139.9.60.86:5000/ufastdfs:v1"
local tracker_container="utracker"
local storage_container="ustorage"
local tracker_host_dir="/data/storage/tracker"
local storage_host_dir="/data/storage/storage"
log "INFO" "=================================================================="
log "INFO" "开始部署 FastDFS 服务 (Docker 版, x86)"
log "INFO" "=================================================================="
# 自动获取本机 IP(优先使用非 loopback 的 IPv4)
local host_ip
host_ip=$(ip -4 addr show scope global | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -n1)
if [[ -z "$host_ip" ]]; then
host_ip=$(hostname -I | awk '{print $1}')
fi
if [[ -z "$host_ip" ]]; then
log "ERROR" "⛔ 无法获取本机 IP 地址"
return 1
fi
log "INFO" "🌐 检测到本机 IP: $host_ip"
# ------------------- 检查两个容器是否都已运行 -------------------
log "INFO" "🔍 检查 FastDFS 容器是否已运行..."
local tracker_running=false
local storage_running=false
if $sudoset docker ps --format '{{.Names}}' | grep -wq "^$tracker_container$"; then
tracker_running=true
log "INFO" "✅ 容器 '$tracker_container' 已在运行。"
fi
if $sudoset docker ps --format '{{.Names}}' | grep -wq "^$storage_container$"; then
storage_running=true
log "INFO" "✅ 容器 '$storage_container' 已在运行。"
fi
if [[ "$tracker_running" == true && "$storage_running" == true ]]; then
log "INFO" "🎉 FastDFS 服务已全部运行,跳过安装。"
return 0
fi
# ------------------- 检查镜像是否存在 -------------------
log "INFO" "🔍 检查 FastDFS 镜像是否存在..."
if $sudoset docker images --format '{{.Repository}}:{{.Tag}}' | grep -wq "$image_name"; then
log "INFO" "✅ 镜像 $image_name 已存在。"
else
log "WARN" "❌ 镜像 $image_name 不存在,开始加载离线包..."
if [[ ! -f "$image_tar" ]]; then
log "ERROR" "⛔ 镜像文件不存在: $image_tar"
return 1
fi
if $sudoset docker load -i "$image_tar"; then
log "INFO" "🎉 镜像加载成功"
else
log "ERROR" "⛔ 镜像加载失败,请检查文件完整性"
return 1
fi
fi
# ------------------- 启动 Tracker 容器 -------------------
if [[ "$tracker_running" == false ]]; then
log "INFO" "🚀 正在启动 Tracker 服务: $tracker_container ..."
$sudoset docker run -d \
--network=host \
--name "$tracker_container" \
--restart=always \
-v "$tracker_host_dir:/var/fdfs" \
-v "/etc/localtime:/etc/localtime:ro" \
"$image_name" \
tracker
if [ $? -ne 0 ]; then
log "ERROR" "⛔ Tracker 容器启动失败"
return 1
fi
log "INFO" "✅ Tracker 启动成功"
fi
# ------------------- 启动 Storage 容器 -------------------
if [[ "$storage_running" == false ]]; then
log "INFO" "🚀 正在启动 Storage 服务: $storage_container ..."
$sudoset docker run -d \
--network=host \
--name "$storage_container" \
--restart=always \
-e "TRACKER_SERVER=$host_ip:22122" \
-v "$storage_host_dir:/var/fdfs" \
-v "/etc/localtime:/etc/localtime:ro" \
"$image_name" \
storage
if [ $? -ne 0 ]; then
log "ERROR" "⛔ Storage 容器启动失败"
return 1
fi
log "INFO" "✅ Storage 启动成功"
fi
# ------------------- 等待并验证 -------------------
log "INFO" "⏳ 等待服务初始化..."
sleep 8
local all_running=true
for container in "$tracker_container" "$storage_container"; do
if ! $sudoset docker ps --format '{{.Names}}' | grep -wq "^$container$"; then
log "ERROR" "⛔ 容器 '$container' 启动后未运行"
all_running=false
fi
done
if [[ "$all_running" == true ]]; then
log "INFO" "🎉 FastDFS 部署完成!"
$sudoset docker ps --filter "name=utracker" --filter "name=ustorage" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
else
log "ERROR" "⛔ 部分容器启动失败,请检查日志: docker logs utracker / ustorage"
return 1
fi
return 0
}
#安装ngrok
function ngrok_x86()
{
# ------------------- 定义变量 -------------------
local container_name="ungrok"
local image_tar="/data/temp/ungrok2.tar.gz"
local image_name="ngrok:v1"
local image_id="493b3f514dfd"
local ngrok_script_host="/data/middleware/ngrok/ngrok.sh"
local ngrok_script_container="/home/ngrok.sh"
log "INFO" "=================================================================="
log "INFO" "开始部署 ngrok 服务 (Docker 版, x86)"
log "INFO" "=================================================================="
# ------------------- 检查容器是否已运行 -------------------
log "INFO" "🔍 检查 ngrok 容器是否已运行..."
if $sudoset docker ps --format '{{.Names}}' | grep -wq "^$container_name$"; then
log "INFO" "✅ 容器 '$container_name' 已在运行。"
return 0
fi
# ------------------- 检查镜像是否存在 -------------------
log "INFO" "🔍 检查 ngrok 镜像是否存在..."
if $sudoset docker images --format '{{.Repository}}:{{.Tag}}' | grep -wq "^$image_name$"; then
log "INFO" "✅ 镜像 $image_name 已存在。"
else
log "WARN" "❌ 镜像 $image_name 不存在,开始加载离线包..."
if [[ ! -f "$image_tar" ]]; then
log "ERROR" "⛔ 镜像文件不存在: $image_tar"
return 1
fi
if $sudoset docker load -i "$image_tar"; then
log "INFO" "🎉 镜像加载成功"
else
log "ERROR" "⛔ 镜像加载失败,请检查文件完整性"
return 1
fi
# 打标签
$sudoset docker tag "$image_id" "$image_name" 2>/dev/null || true
log "INFO" "🏷️ 镜像已标记为 $image_name"
fi
# ------------------- 检查 ngrok 启动脚本 -------------------
if [[ ! -f "$ngrok_script_host" ]]; then
log "ERROR" "⛔ ngrok 启动脚本不存在: $ngrok_script_host"
return 1
fi
if [[ ! -x "$ngrok_script_host" ]]; then
log "WARN" "🔧 ngrok 脚本无执行权限,正在添加..."
$sudoset chmod +x "$ngrok_script_host"
if [ $? -ne 0 ]; then
log "ERROR" "⛔ 无法为 $ngrok_script_host 添加执行权限"
return 1
fi
fi
log "INFO" "✅ ngrok 启动脚本检查通过"
# ------------------- 启动 ngrok 容器 -------------------
log "INFO" "🚀 正在启动 ngrok 容器: $container_name ..."
$SUDO docker run -d \
--name "$container_name" \
--restart=always \
--network=host \
-v /etc/localtime:/etc/localtime \
-v "$ngrok_script_host":/home/ngrok.sh \
"$image_name"
if [ $? -ne 0 ]; then
log "ERROR" "⛔ 容器启动失败"
return 1
fi
log "INFO" "✅ ngrok 容器已启动,等待初始化..."
sleep 5
# ------------------- 验证容器状态 -------------------
if $sudoset docker ps --format '{{.Names}}' | grep -wq "^$container_name$"; then
log "INFO" "🎉 ngrok 服务部署完成!"
$sudoset docker ps --filter "name=$container_name" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
else
log "ERROR" "⛔ 容器启动后未运行,请检查日志: docker logs $container_name"
return 1
fi
return 0
}
function nacos_x86() {
# --- 配置变量 ---
local container_name="unacos"
local image_tag="nacos-server:v2.5.2"
local tar_image="/data/temp/nacos-server-v2.5.2.tar.gz"
local host_data_dir="/data/middleware/nacos"
# 🔐 新增认证配置
local nacos_username="nacos" # 用户名
local nacos_password="dNrprU&2S" # 密码
log "INFO" "=================================================================="
log "INFO" "开始部署 Nacos Server (Standalone) - x86"
log "INFO" "=================================================================="
# 自动判断 sudo
local SUDO=""
if [[ $(id -u) -ne 0 ]]; then
if command -v sudo >/dev/null; then
SUDO="sudo"
else
log "ERROR" "⛔ 当前不是 root 用户且无 sudo 权限"
return 1
fi
fi
# --- 1. 检查容器是否已在运行 ---
if $SUDO docker ps --format '{{.Names}}' | grep -wq "^$container_name$"; then
log "INFO" "✅ 容器 '$container_name' 已在运行,跳过部署。"
log "INFO" "🎉 访问地址: http://\$IP:8848/nacos (默认账号密码: nacos/nacos)"
return 0
fi
# --- 2. 检查镜像是否存在 ---
if $SUDO docker images --format '{{.Repository}}:{{.Tag}}' | grep -wq "^$image_tag$"; then
log "INFO" "✅ 镜像 '$image_tag' 已存在,跳过加载。"
else
log "INFO" "📦 开始加载离线镜像包: $tar_image"
# 检查离线包是否存在
if [[ ! -f "$tar_image" ]]; then
log "ERROR" "⛔ 镜像文件不存在: $tar_image"
log "INFO" "请确保已上传 nacos-server-v2.5.1.tar.gz 到 /data/temp/"
return 1
fi
# 加载镜像
if ! $SUDO docker load -i "$tar_image"; then
log "ERROR" "⛔ 镜像加载失败,请检查文件是否完整或已损坏"
return 1
fi
log "INFO" "✅ 镜像加载成功"
fi
# --- 3. 启动 Nacos 容器 ---
log "INFO" "🚀 正在启动 Nacos 容器..."
$SUDO docker run -d \
--name "$container_name" \
--restart=always \
-p 8848:8848 \
-p 9848:9848 \
-e MODE=standalone \
-e NACOS_AUTH_ENABLE=true \
-e NACOS_AUTH_USERNAME="$nacos_username" \
-e NACOS_AUTH_PASSWORD="$nacos_password" \
-e NACOS_AUTH_IDENTITY_KEY="nacos" \
-e NACOS_AUTH_IDENTITY_VALUE="nacos" \
-v "$host_data_dir:/home/nacos" \
--mac-address="02:42:ac:11:00:10" \
"$image_tag"
if [[ $? -ne 0 ]]; then
log "ERROR" "⛔ Nacos 容器启动失败"
return 1
fi
log "INFO" "✅ Nacos 容器已启动,名称: $container_name"
# --- 4. 状态确认(容器是否仍在运行)---
sleep 5
if ! $SUDO docker ps --format '{{.Names}}' | grep -wq "^$container_name$"; then
log "ERROR" "⛔ 容器启动后退出,请检查日志: $SUDO docker logs $container_name"
return 1
fi
# --- 5. 获取本机 IP 地址 ---
local server_ip=$(ip addr show | grep -E 'inet\s+(192\.168|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|10\.)' | awk '{print $2}' | cut -d/ -f1 | head -n1)
if [[ -z "$server_ip" ]]; then
# 回退到 hostname -I
server_ip=$(hostname -I | awk '{print $1}')
fi
# --- 6. 输出访问信息 ---
if [[ -n "$server_ip" ]]; then
log "INFO" "✅ Nacos 部署完成!"
log "🎉 可通过浏览器访问: http://$server_ip:8848/nacos"
log "💡 默认账号密码: nacos / nacos"
else
log "INFO" "🎉 Nacos 部署完成。"
log "💡 默认账号密码: nacos / nacos"
log "📌 无法获取服务器 IP,请手动确认访问地址: http://<your-ip>:8848/nacos"
fi
return 0
}
function nginx_x86() {
# ------------------- 定义变量 -------------------
local temp_dir="/data/temp"
local nginx_version="1.29.3"
local nginx_image="nginx:${nginx_version}"
local nginx_container_name="unginx"
local nginx_image_tar="${temp_dir}/nginx-${nginx_version}.tar.gz"
local required_dirs=(
"/data/middleware/nginx/log"
"/data/middleware/nginx/data/cache"
"/data/middleware/nginx/data/html"
"/data/middleware/nginx/config"
"/data/services/web"
"/data/security/nginx_cert"
)
log "INFO" "=================================================================="
log "INFO" "开始部署 Nginx (离线编译安装) - x86"
log "INFO" "=================================================================="
# 目录预检查,缺失则创建
for dir in "${required_dirs[@]}"; do
if [ ! -d "$dir" ]; then
log "WARN" "目录 $dir 不存在,自动创建"
mkdir -p "$dir" || {
log "ERROR" "目录 $dir 创建失败"
return 1
}
fi
done
#创建nginx用户
groupadd -r nginx
useradd -r -g nginx -s /sbin/nologin -d /var/cache/nginx nginx
#检查是否创建成功
id nginx
#赋予权限
chown -R nginx:nginx /data/middleware/nginx/data/cache
chmod -R 755 /data/middleware/nginx/data/cache
# 赋予权限
chown -R 1000:1000 /data/middleware/nginx/log
chown -R 1000:1000 /data/middleware/nginx/data/cache
chmod -R 700 /data/middleware/nginx/data/cache
# 校验镜像包
if [ ! -s "$nginx_image_tar" ]; then
log "ERROR" "离线包 $nginx_image_tar 不存在或为空"
return 1
fi
# 加载镜像文件
if ! docker load -i "$nginx_image_tar"; then
log "ERROR" "镜像加载失败"
return 1
fi
log "INFO" "镜像加载成功"
# 检查容器是否存在
if docker ps -a --format '{{.Names}}' | grep -qw "$nginx_container_name"; then
log "WARN" "容器 $nginx_container_name 已存在,自动退出部署操作!!!"
return 0
fi
# 生成容器
if ! docker run -d \
--name "$nginx_container_name" \
--restart=always \
--mac-address "02:42:ac:11:00:25" \
-v /etc/localtime:/etc/localtime:ro \
-p 443:443 \
-v /data/middleware/nginx/config:/etc/nginx/conf.d \
-v /data/middleware/nginx/data/html:/usr/share/nginx/html \
-v /data/middleware/nginx/log:/var/log/nginx \
-v /data/middleware/nginx/data/cache:/var/cache/nginx \
-v /data/services/web:/data/services/web:rw \
-v /data/security/nginx_cert:/data/security/nginx_cert:ro \
"$nginx_image"; then
log "ERROR" "容器 $nginx_container_name 启动失败"
return 1
fi
# 拷贝/data/temp/nginx.conf到容器内/etc/nginx/目录下
docker cp /data/temp/nginx.conf $nginx_container_name:/etc/nginx/
log "INFO 已将nginx.conf复制到容器内/etc/nginx/目录下"
# 重启unginx容器
docker restart $nginx_container_name
log "INFO" "容器 $nginx_container_name 启动成功"
return 0
}
#===================================================================================
# 函数名称:install_middleware
# 功能说明:中间件部署主入口函数,解析参数并调用对应的中间件部署函数
# 参数说明:通过环境变量 middleware_type 传入中间件类型,多个用空格分隔
# 支持的中间件:redis、mysql、emqx、fdfs、ngrok、nacos、nginx
# 返回值:0-部署成功, 1-部署失败
#===================================================================================
install_middleware() {
log "INFO" "=================================================================="
log "INFO" "开始部署中间件服务"
log "INFO" "=================================================================="
# ------------------- 初始化变量 -------------------
# 初始化sudo相关变量
if [[ $(id -u) -ne 0 ]]; then
sudoset="sudo"
SUDO="sudo"
else
sudoset=""
SUDO=""
fi
# server_ip由主脚本传入
if [[ -z "$server_ip" ]]; then
log "WARN" "未传入服务器IP地址"
else
log "INFO" "服务器IP地址: $server_ip"
fi
# ------------------- 解析参数 -------------------
local middlewares="${middleware_type:-}"
if [[ -z "$middlewares" ]]; then
log "ERROR" "未指定中间件类型,请通过middleware_type环境变量指定"
return 1
fi
log "INFO" "待部署的中间件: $middlewares"
# ------------------- 中间件函数映射 -------------------
declare -A middleware_map=(
["mysql"]="mysql_x86"
["emqx"]="emqx_x86"
["redis"]="redis_x86"
["fdfs"]="fastfds_x86"
["ngrok"]="ngrok_x86"
["nacos"]="nacos_x86"
["nginx"]="nginx_x86"
)
# ------------------- 遍历部署中间件 -------------------
local deploy_failed=0
local deploy_order=()
# 按照建议顺序排序部署(mysql优先)
for middleware in mysql redis emqx nacos fdfs ngrok nginx; do
if [[ "$middlewares" =~ $middleware ]]; then
deploy_order+=("$middleware")
fi
done
# 执行部署
for middleware in "${deploy_order[@]}"; do
local func_name="${middleware_map[$middleware]}"
if [[ -z "$func_name" ]]; then
log "ERROR" "未找到中间件 '$middleware' 对应的部署函数"
deploy_failed=1
continue
fi
log "INFO" "----------------------------------------"
log "INFO" "开始部署: $middleware"
# 调用对应的部署函数
if $func_name; then
log "INFO" "✅ $middleware 部署成功"
else
log "ERROR" "❌ $middleware 部署失败"
deploy_failed=1
fi
done
# ------------------- 返回结果 -------------------
log "INFO" "=================================================================="
if [[ $deploy_failed -eq 0 ]]; then
log "INFO" "所有中间件部署完成"
return 0
else
log "ERROR" "部分中间件部署失败,请检查日志"
return 1
fi
}
......@@ -45,6 +45,16 @@ function log() {
echo "[$timestamp] [$level] $message" >> "$LOG_FILE"
}
#------------------------------导入中间件部署模块---------------------------------------------------
# 获取脚本所在目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# 导入中间件部署脚本
if [[ -f "$SCRIPT_DIR/auto_middleware_install.sh" ]]; then
source "$SCRIPT_DIR/auto_middleware_install.sh"
else
log "ERROR" "中间件部署脚本不存在: $SCRIPT_DIR/auto_middleware_install.sh"
exit 1
fi
#------------------------------检测模块-----------------------------------------------------
......@@ -718,534 +728,6 @@ function docker_x86() {
fi
}
#==============================================================#
# 函数名: mysql_x86
# 功能: 部署基于 Docker 的 MySQL 服务(x86 架构)
# 说明: 1. 检查本地是否已运行 umysql 容器
# 2. 若无,则从离线 tar 加载镜像并启动容器
# 3. 初始化数据库:创建用户、数据库、授权
# 4. 配置定时备份脚本(每天 13:00)
# 作者: [ubains]
# 日期: $(date +%Y-%m-%d)
#--------------------------------------------------------------#
# 参数: 无
# 返回: 0: 成功
# 1: 失败
#--------------------------------------------------------------#
# 依赖: docker, crond (或 cronie), sudo
# 注意: 请确保以下资源已上传:
# - /data/temp/umysql.tar.gz
# - $PWD/UbainsmysqlBakUp.sh
# 并确保宿主机 /data/middleware/mysql/ 目录存在
#==============================================================#
function mysql_x86() {
# --- 配置参数 ---
local container_name="umysql"
local image_tar="/data/temp/umysql.tar.gz"
local image_name="139.9.60.86:5000/umysql:v5.2"
local image_id="4c5574ba4b04"
local mysql_root_password="dNrprU&2S"
local mysql_port="8306"
local host_data_dir="/data/middleware/mysql"
local backup_script_src="$PWD/UbainsmysqlBakUp.sh"
local backup_script_dst="/usr/local/docker/UbainsmysqlBakUp.sh"
local cron_user="root"
log "INFO" "=================================================================="
log "INFO" "开始部署 MySQL 服务 (Docker 版, x86)"
log "INFO" "=================================================================="
# 自动判断是否需要 sudo
local SUDO=""
if [[ $(id -u) -ne 0 ]]; then
if command -v sudo >/dev/null; then
SUDO="sudo"
else
log "ERROR" "⛔ 当前不是 root 用户,且系统未安装 sudo,无法执行操作"
return 1
fi
fi
# ------------------- 检查容器是否已运行 -------------------
log "INFO" "🔍 检查容器 '$container_name' 是否已运行..."
if $SUDO docker ps --format '{{.Names}}' | grep -qw "$container_name"; then
log "INFO" "✅ 容器 '$container_name' 已在运行"
return 0
fi
# ------------------- 检查镜像是否存在 -------------------
log "INFO" "🔍 检查镜像 $image_name 是否存在..."
if $SUDO docker images --format '{{.Repository}}:{{.Tag}}' | grep -qw "$image_name"; then
log "INFO" "✅ 镜像 $image_name 已存在"
else
log "WARN" "❌ 镜像 $image_name 不存在,开始加载离线包..."
if [[ ! -f "$image_tar" ]]; then
log "ERROR" "⛔ 镜像文件不存在: $image_tar"
return 1
fi
if $SUDO docker load -i "$image_tar"; then
log "INFO" "🎉 镜像加载成功"
else
log "ERROR" "⛔ 镜像加载失败,请检查文件完整性"
return 1
fi
fi
# ------------------- 启动容器 -------------------
log "INFO" "🚀 正在启动 MySQL 容器: $container_name"
$SUDO docker run -d \
--name "$container_name" \
--mac-address="02:42:ac:11:00:05" \
-p "${mysql_port}:3306" \
-v "${host_data_dir}/conf/my.cnf:/etc/mysql/my.cnf" \
-v "${host_data_dir}/conf.d:/etc/mysql/conf.d" \
-v "${host_data_dir}/log:/var/log/mysql" \
-v "${host_data_dir}/data:/var/lib/mysql" \
-v "/etc/localtime:/etc/localtime:ro" \
--restart=always \
-e "MYSQL_ROOT_PASSWORD=$mysql_root_password" \
"$image_name"
if [[ $? -ne 0 ]]; then
log "ERROR" "⛔ 容器启动失败,请检查端口占用或磁盘权限"
log "INFO" "📄 查看最近容器日志以排查问题..."
$SUDO docker logs "$container_name" 2>/dev/null || true
return 1
fi
sleep 120
log "INFO" "✅ 容器启动成功,等待 MySQL 服务就绪..."
# ------------------- 初始化数据库:创建用户、数据库、授权、导入数据 -------------------
log "INFO" "🔧 初始化数据库:创建用户、数据库、授权..."
# 先拷贝 nacos_mysql.sql 到容器内
log "INFO" "📁 拷贝 /data/temp/nacos_mysql.sql 到容器 '$container_name' 内..."
if $SUDO docker cp "/data/temp/nacos_mysql.sql" "$container_name:/tmp/nacos_mysql.sql"; then
log "INFO" "✅ SQL 文件已成功拷贝到容器内"
else
log "ERROR" "⛔ 无法拷贝 nacos_mysql.sql 到容器,请检查文件路径或容器状态"
return 1
fi
# 先拷贝 devops_voice.sql 到容器内
log "INFO" "📁 拷贝 /data/temp/devops_voice.sql 到容器 '$container_name' 内..."
if $SUDO docker cp "/data/temp/devops_voice.sql" "$container_name:/tmp/devops_voice.sql"; then
log "INFO" "✅ SQL 文件已成功拷贝到容器内"
else
log "ERROR" "⛔ 无法拷贝 devops_voice.sql 到容器,请检查文件路径或容器状态"
return 1
fi
# 先拷贝 huazhao2.sql 到容器内
log "INFO" "📁 拷贝 /data/temp/huazhao2.sql 到容器 '$container_name' 内..."
if $SUDO docker cp "/data/temp/huazhao2.sql" "$container_name:/tmp/huazhao2.sql"; then
log "INFO" "✅ SQL 文件已成功拷贝到容器内"
else
log "ERROR" "⛔ 无法拷贝 huazhao2.sql 到容器,请检查文件路径或容器状态"
return 1
fi
# 先拷贝 offline.sql 到容器内
log "INFO" "📁 拷贝 /data/temp/offline.sql 到容器 '$container_name' 内..."
if $SUDO docker cp "/data/temp/offline.sql" "$container_name:/tmp/offline.sql"; then
log "INFO" "✅ SQL 文件已成功拷贝到容器内"
else
log "ERROR" "⛔ 无法拷贝 offline.sql 到容器,请检查文件路径或容器状态"
return 1
fi
# 定义要执行的 SQL 命令序列(注意顺序)
local init_sql=(
"CREATE USER IF NOT EXISTS 'nacos'@'%' IDENTIFIED BY 'nacos2025';"
"CREATE USER IF NOT EXISTS 'mysqluser'@'%' IDENTIFIED BY 'dNrprU&2S';"
"CREATE DATABASE IF NOT EXISTS nacos_mysql CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
"CREATE DATABASE IF NOT EXISTS devops CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
"CREATE DATABASE IF NOT EXISTS devops_voice CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
"CREATE DATABASE IF NOT EXISTS offline CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
"CREATE DATABASE IF NOT EXISTS huazhao2 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
"GRANT ALL PRIVILEGES ON nacos_mysql.* TO 'nacos'@'%';"
"GRANT ALL PRIVILEGES ON devops.* TO 'mysqluser'@'%';"
"FLUSH PRIVILEGES;"
"ALTER TABLE devops.cmdb_roomdevice ADD COLUMN ICON_H5 VARCHAR(64) NULL;"
"ALTER TABLE devops.cmdb_company ADD COLUMN SMART_HOME INT NULL DEFAULT 0;"
"ALTER TABLE devops.cmdb_roomdevice ADD COLUMN IS_H5 INT NULL DEFAULT 0;"
"ALTER TABLE devops.cmdb_roomdevice ADD COLUMN MAC_ADDR VARCHAR(64) NULL;"
"ALTER TABLE devops.cmdb_roomdevice ADD COLUMN VERSION VARCHAR(64) NULL;"
"ALTER TABLE devops.cmdb_roomganged ADD COLUMN COMPANY_ID INT NULL;"
"ALTER TABLE devops.cmdb_company ADD COLUMN REMOTE_START INT NULL DEFAULT 0;"
"ALTER TABLE devops.cmdb_company ADD COLUMN REMOTE_END INT NULL DEFAULT 0;"
"ALTER TABLE devops.cmdb_companyauthentication ADD COLUMN APPLYDESCRIBE VARCHAR(256) NULL;"
"ALTER TABLE devops.cmdb_companyauthentication ADD COLUMN APPLYFEEDBACK VARCHAR(256) NULL;"
"FLUSH PRIVILEGES;"
"CREATE TABLE devops.cmdb_inspection (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
master_id INT DEFAULT NULL,
name VARCHAR(128) DEFAULT NULL,
status INT DEFAULT '0',
createTime DATETIME(6) DEFAULT NULL,
updateTime DATETIME(6) DEFAULT NULL,
createUser_id INT DEFAULT NULL,
runWay INT DEFAULT '0',
runType INT DEFAULT '0',
runDate VARCHAR(128) DEFAULT NULL,
runStartTime DATETIME(6) DEFAULT NULL,
runEndTime DATETIME(6) DEFAULT NULL,
inspectionTime DATETIME(6) DEFAULT NULL,
isEnable INT DEFAULT '0',
inspectionUser_id INT DEFAULT NULL,
company_id INT DEFAULT NULL,
delflag INT DEFAULT '0',
message_id INT DEFAULT NULL,
INDEX idx_master_id (master_id),
INDEX idx_createUser_id (createUser_id),
INDEX idx_inspectionUser_id (inspectionUser_id),
INDEX idx_company_id (company_id),
INDEX idx_message_id (message_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"
"ALTER TABLE ubains.rms_manage_company ADD COLUMN cnum_approvals_num INT NULL;"
"ALTER TABLE ubains.rms_manage_company ADD COLUMN company_process_id BIGINT NULL;"
"ALTER TABLE ubains.rms_manage_conference ADD COLUMN is_send_project_app INT NULL DEFAULT 0;"
"ALTER TABLE ubains.rms_manage_conference ADD COLUMN room_number VARCHAR(50) NULL;"
"ALTER TABLE ubains.rms_timing_task ADD COLUMN is_send_project_app INT NULL DEFAULT 0;"
"ALTER TABLE ubains.rms_manage_conference ADD COLUMN cloudlink_room_id VARCHAR(50) NULL;"
"ALTER TABLE ubains.rms_manage_conference ADD COLUMN polycom_room_id VARCHAR(50) NULL;"
"ALTER TABLE ubains.rms_meeting_approval ADD COLUMN project_app_note INT NULL DEFAULT 0;"
"ALTER TABLE ubains.rms_manage_conference ADD COLUMN conference_class VARCHAR(50) NULL;"
"ALTER TABLE ubains.rms_meeting_message ADD COLUMN cascade_meeting INT NULL;"
"ALTER TABLE ubains.rms_meeting_message ADD COLUMN cloudchairman_pw VARCHAR(255) NULL;"
"ALTER TABLE ubains.rms_meeting_message ADD COLUMN cloud_portal_multi_channel_id VARCHAR(50) NULL;"
"ALTER TABLE ubains.rms_meeting_message ADD COLUMN cloud_multi_channel_guest_pw VARCHAR(20) NULL;"
)
# 执行前半部分 SQL
for sql in "${init_sql[@]}"; do
$SUDO docker exec "$container_name" mysql -uroot -p"$mysql_root_password" -e "$sql"
if [[ $? -ne 0 ]]; then
log "ERROR" "⛔ 执行SQL语句失败: $sql"
log "INFO" "📄 输出容器最近日志..."
$SUDO docker logs "$container_name" | tail -30
return 1
fi
done
# 执行 source 导入 nacos_mysql.sql 到 nacos_mysql 数据库
log "INFO" "📥 正在导入 nacos_mysql.sql 到数据库 nacos_mysql..."
$SUDO docker exec "$container_name" mysql -uroot -p"$mysql_root_password" -D nacos_mysql -e "source /tmp/nacos_mysql.sql"
if [[ $? -eq 0 ]]; then
log "INFO" "✅ nacos_mysql.sql 数据导入成功"
# 在导入数据后执行 IP 替换
log "INFO" "🔄 正在更新配置中的 IP 地址..."
$SUDO docker exec "$container_name" mysql -uroot -p"$mysql_root_password" -D nacos_mysql -e \
"UPDATE config_info SET content = REPLACE(content, '192.168.5.234', '"$server_ip"')
WHERE data_id IN ('auth-sso-auth-dev.yml','auth-sso-gateway-dev.yml','auth-sso-system-dev.yml');"
log "INFO" "🔄 正在保存配置..."
$SUDO docker exec "$container_name" mysql -uroot -p"$mysql_root_password" -D nacos_mysql -e \
"FLUSH PRIVILEGES;"
if [[ $? -eq 0 ]]; then
log "INFO" "✅ 配置保存成功"
else
log "ERROR" "⛔ 配置保存失败"
return 1
fi
else
log "ERROR" "⛔ 数据导入失败,请检查 nacos_mysql.sql 文件内容或权限"
log "INFO" "📄 输出容器日志以排查问题..."
$SUDO docker logs "$container_name" | tail -50
return 1
fi
sleep 60
# 执行 source 导入 devops_voice.sql 到 devops_voice 数据库
log "INFO" "📥 正在导入 devops_voice.sql 到数据库 devops_voice..."
$SUDO docker exec "$container_name" mysql -uroot -p"$mysql_root_password" -D devops_voice -e "source /tmp/devops_voice.sql"
if [[ $? -eq 0 ]]; then
log "INFO" "✅ devops_voice.sql 数据导入成功"
else
log "ERROR" "⛔ 数据导入失败,请检查 devops_voice.sql 文件内容或权限"
log "INFO" "📄 输出容器日志以排查问题..."
$SUDO docker logs "$container_name" | tail -50
return 1
fi
sleep 60
# 执行 source 导入 huazhao2.sql 到 huazhao2 数据库
log "INFO" "📥 正在导入 huazhao2.sql 到数据库 huazhao2..."
$SUDO docker exec "$container_name" mysql -uroot -p"$mysql_root_password" -D huazhao2 -e "source /tmp/huazhao2.sql"
if [[ $? -eq 0 ]]; then
log "INFO" "✅ huazhao2.sql 数据导入成功"
else
log "ERROR" "⛔ 数据导入失败,请检查 huazhao2.sql 文件内容或权限"
log "INFO" "📄 输出容器日志以排查问题..."
$SUDO docker logs "$container_name" | tail -50
return 1
fi
sleep 60
# 执行 source 导入 offline.sql 到 offline 数据库
log "INFO" "📥 正在导入 offline.sql 到数据库 offline..."
$SUDO docker exec "$container_name" mysql -uroot -p"$mysql_root_password" -D offline -e "source /tmp/offline.sql"
if [[ $? -eq 0 ]]; then
log "INFO" "✅ offline.sql 数据导入成功"
else
log "ERROR" "⛔ 数据导入失败,请检查 offline.sql 文件内容或权限"
log "INFO" "📄 输出容器日志以排查问题..."
$SUDO docker logs "$container_name" | tail -50
return 1
fi
sleep 60
# ------------------- 提升用户权限 -------------------
for user in "root" "mysqluser"; do
$SUDO docker exec "$container_name" mysql -u"root" -p"$mysql_root_password" -e \
"UPDATE mysql.user SET Grant_priv='Y', Super_priv='Y' WHERE User='$user' AND Host='%'; FLUSH PRIVILEGES;" 2>/dev/null
done
log "INFO" "✅ 用户权限提升完成"
# ------------------- 部署备份脚本 -------------------
log "INFO" "📦 部署备份脚本到容器..."
$SUDO mkdir -p "$(dirname "$backup_script_dst")"
if $SUDO cp -f "$backup_script_src" "$backup_script_dst"; then
$SUDO chmod +x "$backup_script_dst"
log "INFO" "✅ 备份脚本已复制到: $backup_script_dst"
else
log "ERROR" "⛔ 备份脚本复制失败,请检查源文件是否存在"
return 1
fi
# ------------------- 配置定时任务 -------------------
log "INFO" "⏰ 配置定时备份任务 (每天 13:00)"
local cron_job="0 13 * * * bash $backup_script_dst"
if $SUDO crontab -u "$cron_user" -l 2>/dev/null | grep -Fq "$backup_script_dst"; then
log "INFO" "✅ 定时任务已存在"
else
( $SUDO crontab -u "$cron_user" -l 2>/dev/null; echo "$cron_job" ) | $SUDO crontab -u "$cron_user" -
if [[ $? -eq 0 ]]; then
log "INFO" "✅ 定时任务添加成功"
else
log "ERROR" "⛔ 定时任务添加失败"
return 1
fi
fi
# ------------------- 重启 crond -------------------
log "INFO" "🔄 重启 crond 服务..."
if command -v systemctl >/dev/null; then
$SUDO systemctl restart crond || $SUDO systemctl restart cron
else
$SUDO service crond restart || $SUDO service cron restart
fi
log "INFO" "✅ crond 服务已重启"
# ------------------- 最终状态输出 -------------------
log "INFO" "🎉 MySQL 部署完成!"
$SUDO docker ps --filter "name=$container_name" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
return 0
}
#x86架构安装mqtt
function emqx_x86()
{
# ------------------- 定义变量 -------------------
local container_name="uemqx"
local image_tar="/data/temp/uemqx5.8.7.tar.gz"
local image_name="emqx/emqx:5.8.7"
local host_config_dir="/data/middleware/emqx/config"
local host_dir="/data/middleware/emqx"
log "INFO" "=================================================================="
log "INFO" "开始部署 EMQX 服务 (Docker 版, x86)"
log "INFO" "=================================================================="
# ------------------- 检查容器是否已运行 -------------------
log "INFO" "🔍 检查 EMQX 容器是否已运行..."
if $sudoset docker ps --format '{{.Names}}' | grep -wq "$container_name"; then
log "INFO" "✅ 容器 '$container_name' 已在运行。"
return 0
fi
# ------------------- 检查镜像是否存在 -------------------
log "INFO" "🔍 检查 EMQX 镜像是否存在..."
if $sudoset docker images --format '{{.Repository}}:{{.Tag}}' | grep -wq "$image_name"; then
log "INFO" "✅ 镜像 $image_name 已存在。"
else
log "WARN" "❌ 镜像 $image_name 不存在,开始加载离线包..."
if [[ ! -f "$image_tar" ]]; then
log "ERROR" "⛔ 镜像文件不存在: $image_tar"
return 1
fi
if $sudoset docker load -i "$image_tar"; then
log "INFO" "🎉 镜像加载成功"
else
log "ERROR" "⛔ 镜像加载失败,请检查文件完整性"
return 1
fi
fi
# EMQX 容器使用用户 1000:1000
$sudoset chown -R 1000:1000 "$host_dir"/{data,log}
log "INFO" "✅ 目录创建完成,权限已设置"
# ------------------- 启动 EMQX 容器 -------------------
log "INFO" "🚀 正在启动 EMQX 容器: $container_name ..."
$sudoset docker run -d \
--name "$container_name" \
--mac-address="02:42:ac:12:00:06" \
--privileged \
--restart=always \
-p 1883:1883 \
-p 8083:8083 \
-p 8883:8883 \
-v "$host_config_dir/emqx.conf:/opt/emqx/etc/emqx.conf:ro" \
-v "$host_config_dir/auth-built-in-db-bootstrap.csv:/opt/emqx/etc/auth-built-in-db-bootstrap.csv:ro" \
-v "$host_config_dir/acl.conf:/opt/emqx/etc/acl.conf:ro" \
-v "$host_dir/data:/opt/emqx/data" \
-v "$host_dir/log:/opt/emqx/log" \
"$image_name"
if [ $? -ne 0 ]; then
log "ERROR" "⛔ 容器启动失败"
return 1
fi
log "INFO" "✅ EMQX 容器启动成功,等待初始化..."
sleep 5
# ------------------- 验证容器状态 -------------------
if $sudoset docker ps --format '{{.Names}}' | grep -wq "$container_name"; then
log "INFO" "🎉 EMQX 部署完成!"
$sudoset docker ps --filter "name=$container_name" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
else
log "ERROR" "⛔ 容器启动后未运行,请检查日志: docker logs $container_name"
return 1
fi
return 0
}
function redis_x86()
{
# ------------------- 定义变量 -------------------
local container_name="uredis"
local image_tar="/data/temp/redis8.2.2.tar.gz"
local image_name="139.9.60.86:5000/redis:v3"
local image_id="3bd8c109f88b"
local redis_conf_host="/data/middleware/redis/config/redis.conf"
local redis_data_host="/data/middleware/redis/data"
local redis_port="6379"
log "INFO" "=================================================================="
log "INFO" "开始部署 Redis 服务 (Docker 版, x86)"
log "INFO" "=================================================================="
# ------------------- 检查容器是否已运行 -------------------
log "INFO" "🔍 检查 Redis 容器是否已运行..."
if $sudoset docker ps --format '{{.Names}}' | grep -wq "$container_name"; then
log "INFO" "✅ 容器 '$container_name' 已在运行。"
return 0
fi
# ------------------- 自动配置 sysctl -------------------
log "INFO" "🔧 配置系统参数: /etc/sysctl.conf"
local sysctl_config="
#新增
net.core.somaxconn = 511
vm.overcommit_memory = 1
"
# 检查是否已存在配置,避免重复添加
if ! grep -Fq "#新增" /etc/sysctl.conf; then
echo "$sysctl_config" | $sudoset tee -a /etc/sysctl.conf > /dev/null
if [ $? -eq 0 ]; then
log "INFO" "✅ sysctl 配置已追加"
else
log "ERROR" "⛔ 写入 /etc/sysctl.conf 失败,请检查权限"
return 1
fi
else
log "INFO" "✅ sysctl 配置已存在,跳过添加"
fi
# 应用配置
$sudoset sysctl -p > /dev/null 2>&1
if [ $? -eq 0 ]; then
log "INFO" "✅ sysctl 参数已生效"
else
log "WARN" "⚠️ sysctl -p 执行可能有警告,继续执行"
fi
# ------------------- 检查镜像是否存在 -------------------
log "INFO" "🔍 检查 Redis 镜像是否存在..."
if $sudoset docker images --format '{{.Repository}}:{{.Tag}}' | grep -wq "$image_name"; then
log "INFO" "✅ 镜像 $image_name 已存在。"
else
log "WARN" "❌ 镜像 $image_name 不存在,开始加载离线包..."
if [[ ! -f "$image_tar" ]]; then
log "ERROR" "⛔ 镜像文件不存在: $image_tar"
return 1
fi
if $sudoset docker load -i "$image_tar"; then
log "INFO" "🎉 镜像加载成功"
else
log "ERROR" "⛔ 镜像加载失败,请检查文件完整性"
return 1
fi
fi
# ------------------- 启动 Redis 容器 -------------------
log "INFO" "🚀 正在启动 Redis 容器: $container_name ..."
$sudoset docker run -d \
--name "$container_name" \
--security-opt seccomp=unconfined \
--network host \
-v "$redis_conf_host:/etc/redis/redis.conf" \
-v "$redis_data_host:/data" \
-v "/etc/localtime:/etc/localtime:ro" \
--restart=always \
"$image_name" \
redis-server /etc/redis/redis.conf --appendonly yes
if [ $? -ne 0 ]; then
log "ERROR" "⛔ 容器启动失败"
return 1
fi
log "INFO" "✅ Redis 容器启动成功,等待初始化..."
sleep 5
# ------------------- 验证状态 -------------------
if $sudoset docker ps --format '{{.Names}}' | grep -wq "$container_name"; then
log "INFO" "🎉 Redis 部署完成!"
$sudoset docker ps --filter "name=$container_name" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
else
log "ERROR" "⛔ 容器启动后未运行,请检查日志: docker logs $container_name"
return 1
fi
return 0
}
function java_x86()
{
log "INFO" "=================================================================="
......@@ -2468,339 +1950,6 @@ EOF
return 0
}
#安装fastfds
function fastfds_x86()
{
# ------------------- 定义变量 -------------------
local image_tar="/data/temp/ufastdfs.tar.gz"
local image_name="139.9.60.86:5000/ufastdfs:v1"
local tracker_container="utracker"
local storage_container="ustorage"
local tracker_host_dir="/data/storage/tracker"
local storage_host_dir="/data/storage/storage"
log "INFO" "=================================================================="
log "INFO" "开始部署 FastDFS 服务 (Docker 版, x86)"
log "INFO" "=================================================================="
# 自动获取本机 IP(优先使用非 loopback 的 IPv4)
local host_ip
host_ip=$(ip -4 addr show scope global | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -n1)
if [[ -z "$host_ip" ]]; then
host_ip=$(hostname -I | awk '{print $1}')
fi
if [[ -z "$host_ip" ]]; then
log "ERROR" "⛔ 无法获取本机 IP 地址"
return 1
fi
log "INFO" "🌐 检测到本机 IP: $host_ip"
# ------------------- 检查两个容器是否都已运行 -------------------
log "INFO" "🔍 检查 FastDFS 容器是否已运行..."
local tracker_running=false
local storage_running=false
if $sudoset docker ps --format '{{.Names}}' | grep -wq "^$tracker_container$"; then
tracker_running=true
log "INFO" "✅ 容器 '$tracker_container' 已在运行。"
fi
if $sudoset docker ps --format '{{.Names}}' | grep -wq "^$storage_container$"; then
storage_running=true
log "INFO" "✅ 容器 '$storage_container' 已在运行。"
fi
if [[ "$tracker_running" == true && "$storage_running" == true ]]; then
log "INFO" "🎉 FastDFS 服务已全部运行,跳过安装。"
return 0
fi
# ------------------- 检查镜像是否存在 -------------------
log "INFO" "🔍 检查 FastDFS 镜像是否存在..."
if $sudoset docker images --format '{{.Repository}}:{{.Tag}}' | grep -wq "$image_name"; then
log "INFO" "✅ 镜像 $image_name 已存在。"
else
log "WARN" "❌ 镜像 $image_name 不存在,开始加载离线包..."
if [[ ! -f "$image_tar" ]]; then
log "ERROR" "⛔ 镜像文件不存在: $image_tar"
return 1
fi
if $sudoset docker load -i "$image_tar"; then
log "INFO" "🎉 镜像加载成功"
else
log "ERROR" "⛔ 镜像加载失败,请检查文件完整性"
return 1
fi
fi
# ------------------- 启动 Tracker 容器 -------------------
if [[ "$tracker_running" == false ]]; then
log "INFO" "🚀 正在启动 Tracker 服务: $tracker_container ..."
$sudoset docker run -d \
--network=host \
--name "$tracker_container" \
--restart=always \
-v "$tracker_host_dir:/var/fdfs" \
-v "/etc/localtime:/etc/localtime:ro" \
"$image_name" \
tracker
if [ $? -ne 0 ]; then
log "ERROR" "⛔ Tracker 容器启动失败"
return 1
fi
log "INFO" "✅ Tracker 启动成功"
fi
# ------------------- 启动 Storage 容器 -------------------
if [[ "$storage_running" == false ]]; then
log "INFO" "🚀 正在启动 Storage 服务: $storage_container ..."
$sudoset docker run -d \
--network=host \
--name "$storage_container" \
--restart=always \
-e "TRACKER_SERVER=$host_ip:22122" \
-v "$storage_host_dir:/var/fdfs" \
-v "/etc/localtime:/etc/localtime:ro" \
"$image_name" \
storage
if [ $? -ne 0 ]; then
log "ERROR" "⛔ Storage 容器启动失败"
return 1
fi
log "INFO" "✅ Storage 启动成功"
fi
# ------------------- 等待并验证 -------------------
log "INFO" "⏳ 等待服务初始化..."
sleep 8
local all_running=true
for container in "$tracker_container" "$storage_container"; do
if ! $sudoset docker ps --format '{{.Names}}' | grep -wq "^$container$"; then
log "ERROR" "⛔ 容器 '$container' 启动后未运行"
all_running=false
fi
done
if [[ "$all_running" == true ]]; then
log "INFO" "🎉 FastDFS 部署完成!"
$sudoset docker ps --filter "name=utracker" --filter "name=ustorage" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
else
log "ERROR" "⛔ 部分容器启动失败,请检查日志: docker logs utracker / ustorage"
return 1
fi
return 0
}
#安装ngrok
function ngrok_x86()
{
# ------------------- 定义变量 -------------------
local container_name="ungrok"
local image_tar="/data/temp/ungrok2.tar.gz"
local image_name="ngrok:v1"
local image_id="493b3f514dfd"
local ngrok_script_host="/data/middleware/ngrok/ngrok.sh"
local ngrok_script_container="/home/ngrok.sh"
log "INFO" "=================================================================="
log "INFO" "开始部署 ngrok 服务 (Docker 版, x86)"
log "INFO" "=================================================================="
# ------------------- 检查容器是否已运行 -------------------
log "INFO" "🔍 检查 ngrok 容器是否已运行..."
if $sudoset docker ps --format '{{.Names}}' | grep -wq "^$container_name$"; then
log "INFO" "✅ 容器 '$container_name' 已在运行。"
return 0
fi
# ------------------- 检查镜像是否存在 -------------------
log "INFO" "🔍 检查 ngrok 镜像是否存在..."
if $sudoset docker images --format '{{.Repository}}:{{.Tag}}' | grep -wq "^$image_name$"; then
log "INFO" "✅ 镜像 $image_name 已存在。"
else
log "WARN" "❌ 镜像 $image_name 不存在,开始加载离线包..."
if [[ ! -f "$image_tar" ]]; then
log "ERROR" "⛔ 镜像文件不存在: $image_tar"
return 1
fi
if $sudoset docker load -i "$image_tar"; then
log "INFO" "🎉 镜像加载成功"
else
log "ERROR" "⛔ 镜像加载失败,请检查文件完整性"
return 1
fi
# 打标签
$sudoset docker tag "$image_id" "$image_name" 2>/dev/null || true
log "INFO" "🏷️ 镜像已标记为 $image_name"
fi
# ------------------- 检查 ngrok 启动脚本 -------------------
if [[ ! -f "$ngrok_script_host" ]]; then
log "ERROR" "⛔ ngrok 启动脚本不存在: $ngrok_script_host"
return 1
fi
if [[ ! -x "$ngrok_script_host" ]]; then
log "WARN" "🔧 ngrok 脚本无执行权限,正在添加..."
$sudoset chmod +x "$ngrok_script_host"
if [ $? -ne 0 ]; then
log "ERROR" "⛔ 无法为 $ngrok_script_host 添加执行权限"
return 1
fi
fi
log "INFO" "✅ ngrok 启动脚本检查通过"
# ------------------- 启动 ngrok 容器 -------------------
log "INFO" "🚀 正在启动 ngrok 容器: $container_name ..."
$SUDO docker run -d \
--name "$container_name" \
--restart=always \
--network=host \
-v /etc/localtime:/etc/localtime \
-v "$ngrok_script_host":/home/ngrok.sh \
"$image_name"
if [ $? -ne 0 ]; then
log "ERROR" "⛔ 容器启动失败"
return 1
fi
log "INFO" "✅ ngrok 容器已启动,等待初始化..."
sleep 5
# ------------------- 验证容器状态 -------------------
if $sudoset docker ps --format '{{.Names}}' | grep -wq "^$container_name$"; then
log "INFO" "🎉 ngrok 服务部署完成!"
$sudoset docker ps --filter "name=$container_name" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
else
log "ERROR" "⛔ 容器启动后未运行,请检查日志: docker logs $container_name"
return 1
fi
return 0
}
function nacos_x86() {
# --- 配置变量 ---
local container_name="unacos"
local image_tag="nacos-server:v2.5.2"
local tar_image="/data/temp/nacos-server-v2.5.2.tar.gz"
local host_data_dir="/data/middleware/nacos"
# 🔐 新增认证配置
local nacos_username="nacos" # 用户名
local nacos_password="dNrprU&2S" # 密码
log "INFO" "=================================================================="
log "INFO" "开始部署 Nacos Server (Standalone) - x86"
log "INFO" "=================================================================="
# 自动判断 sudo
local SUDO=""
if [[ $(id -u) -ne 0 ]]; then
if command -v sudo >/dev/null; then
SUDO="sudo"
else
log "ERROR" "⛔ 当前不是 root 用户且无 sudo 权限"
return 1
fi
fi
# --- 1. 检查容器是否已在运行 ---
if $SUDO docker ps --format '{{.Names}}' | grep -wq "^$container_name$"; then
log "INFO" "✅ 容器 '$container_name' 已在运行,跳过部署。"
log "INFO" "🎉 访问地址: http://\$IP:8848/nacos (默认账号密码: nacos/nacos)"
return 0
fi
# --- 2. 检查镜像是否存在 ---
if $SUDO docker images --format '{{.Repository}}:{{.Tag}}' | grep -wq "^$image_tag$"; then
log "INFO" "✅ 镜像 '$image_tag' 已存在,跳过加载。"
else
log "INFO" "📦 开始加载离线镜像包: $tar_image"
# 检查离线包是否存在
if [[ ! -f "$tar_image" ]]; then
log "ERROR" "⛔ 镜像文件不存在: $tar_image"
log "INFO" "请确保已上传 nacos-server-v2.5.1.tar.gz 到 /data/temp/"
return 1
fi
# 加载镜像
if ! $SUDO docker load -i "$tar_image"; then
log "ERROR" "⛔ 镜像加载失败,请检查文件是否完整或已损坏"
return 1
fi
log "INFO" "✅ 镜像加载成功"
fi
# --- 3. 启动 Nacos 容器 ---
log "INFO" "🚀 正在启动 Nacos 容器..."
$SUDO docker run -d \
--name "$container_name" \
--restart=always \
-p 8848:8848 \
-p 9848:9848 \
-e MODE=standalone \
-e NACOS_AUTH_ENABLE=true \
-e NACOS_AUTH_USERNAME="$nacos_username" \
-e NACOS_AUTH_PASSWORD="$nacos_password" \
-e NACOS_AUTH_IDENTITY_KEY="nacos" \
-e NACOS_AUTH_IDENTITY_VALUE="nacos" \
-v "$host_data_dir:/home/nacos" \
--mac-address="02:42:ac:11:00:10" \
"$image_tag"
if [[ $? -ne 0 ]]; then
log "ERROR" "⛔ Nacos 容器启动失败"
return 1
fi
log "INFO" "✅ Nacos 容器已启动,名称: $container_name"
# --- 4. 状态确认(容器是否仍在运行)---
sleep 5
if ! $SUDO docker ps --format '{{.Names}}' | grep -wq "^$container_name$"; then
log "ERROR" "⛔ 容器启动后退出,请检查日志: $SUDO docker logs $container_name"
return 1
fi
# --- 5. 获取本机 IP 地址 ---
local server_ip=$(ip addr show | grep -E 'inet\s+(192\.168|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|10\.)' | awk '{print $2}' | cut -d/ -f1 | head -n1)
if [[ -z "$server_ip" ]]; then
# 回退到 hostname -I
server_ip=$(hostname -I | awk '{print $1}')
fi
# --- 6. 输出访问信息 ---
if [[ -n "$server_ip" ]]; then
log "INFO" "✅ Nacos 部署完成!"
log "🎉 可通过浏览器访问: http://$server_ip:8848/nacos"
log "💡 默认账号密码: nacos / nacos"
else
log "INFO" "🎉 Nacos 部署完成。"
log "💡 默认账号密码: nacos / nacos"
log "📌 无法获取服务器 IP,请手动确认访问地址: http://<your-ip>:8848/nacos"
fi
return 0
}
function getLatestVersion() {
log "INFO" "检查中间件最新版本信息"
#判断是否能够访问外网,不能就跳过联网检查
......@@ -2846,219 +1995,6 @@ function getLatestVersion() {
log "INFO" "版本检查完成"
}
#function nginx_x86() {
# # ------------------- 定义变量 -------------------
# local temp_dir="/data/temp"
# local nginx_version="1.29.3"
# local nginx_image="nginx:${nginx_version}"
# local nginx_container_name="unginx"
# local nginx_image_tar="${temp_dir}/nginx-${nginx_version}.tar.gz"
# local required_dirs=(
# "/data/middleware/nginx/log"
# "/data/middleware/nginx/data/cache"
# "/data/middleware/nginx/data/html"
# "/data/middleware/nginx/config"
# "/data/services/web"
# "/data/security/nginx_cert"
# )
#
# log "INFO" "=================================================================="
# log "INFO" "开始部署 Nginx (离线编译安装) - x86"
# log "INFO" "=================================================================="
#
# # 目录预检查,缺失则创建
# for dir in "${required_dirs[@]}"; do
# if [ ! -d "$dir" ]; then
# log "WARN" "目录 $dir 不存在,自动创建"
# mkdir -p "$dir" || {
# log "ERROR" "目录 $dir 创建失败"
# return 1
# }
# fi
# done
#
# #创建nginx用户
# groupadd -r nginx
# useradd -r -g nginx -s /sbin/nologin -d /var/cache/nginx nginx
# #检查是否创建成功
# id nginx
# # 创建目录
# mkdir -p /data/middleware/nginx/data/{cache,html}
#
# # 统一设置属主为 nginx(假设 Nginx 运行用户为 nginx)
# chown -R nginx:nginx /data/middleware/nginx
#
# # 设置权限
# chmod -R 755 /data/middleware/nginx/data/html # 静态文件可读
# chmod -R 775 /data/middleware/nginx/data/cache # 缓存目录需写入
# chmod -R 755 /data/middleware/nginx/log # 日志目录可读写
#
# # 校验镜像包
# if [ ! -s "$nginx_image_tar" ]; then
# log "ERROR" "离线包 $nginx_image_tar 不存在或为空"
# return 1
# fi
#
# # 加载镜像文件
# if ! docker load -i "$nginx_image_tar"; then
# log "ERROR" "镜像加载失败"
# return 1
# fi
# log "INFO" "镜像加载成功"
#
# # 检查证书文件是否存在,如果不存在则生成自签名证书
# local cert_dir="/data/security/nginx_cert"
# local cert_file="$cert_dir/server.crt"
# local key_file="$cert_dir/server.key"
#
# if [ ! -f "$cert_file" ] || [ ! -f "$key_file" ]; then
# log "WARN" "证书文件不存在,正在生成自签名证书..."
#
# # 进入证书目录
# cd "$cert_dir" || {
# log "ERROR" "无法进入证书目录 $cert_dir"
# return 1
# }
#
# # 生成自签名证书
# if ! openssl req -x509 \
# -newkey rsa:2048 \
# -nodes \
# -keyout server.key \
# -out server.crt \
# -days 36500 \
# -config san.cnf \
# -extensions v3_req; then
# log "ERROR" "证书生成失败"
# fi
#
# log "INFO" "证书生成成功"
# else
# log "INFO" "证书文件已存在,跳过生成"
# fi
#
# # 检查容器是否存在
# if docker ps -a --format '{{.Names}}' | grep -qw "$nginx_container_name"; then
# log "WARN" "容器 $nginx_container_name 已存在,自动退出部署操作!!!"
# return 0
# fi
#
# # 生成容器
# if ! docker run -d \
# --name "$nginx_container_name" \
# --restart=always \
# --mac-address "02:42:ac:11:00:25" \
# -v /etc/localtime:/etc/localtime:ro \
# -p 443:443 \
# -v /data/middleware/nginx/config:/etc/nginx/conf.d \
# -v /data/middleware/nginx/data/html:/usr/share/nginx/html \
# -v /data/middleware/nginx/log:/var/log/nginx \
# -v /data/middleware/nginx/data/cache:/var/cache/nginx \
# -v /data/services/web:/data/services/web:rw \
# -v /data/security/nginx_cert:/data/security/nginx_cert:ro \
# "$nginx_image"; then
# log "ERROR" "容器 $nginx_container_name 启动失败"
# return 1
# fi
#
# log "INFO" "容器 $nginx_container_name 启动成功"
# return 0
#}
function nginx_x86() {
# ------------------- 定义变量 -------------------
local temp_dir="/data/temp"
local nginx_version="1.29.3"
local nginx_image="nginx:${nginx_version}"
local nginx_container_name="unginx"
local nginx_image_tar="${temp_dir}/nginx-${nginx_version}.tar.gz"
local required_dirs=(
"/data/middleware/nginx/log"
"/data/middleware/nginx/data/cache"
"/data/middleware/nginx/data/html"
"/data/middleware/nginx/config"
"/data/services/web"
"/data/security/nginx_cert"
)
log "INFO" "=================================================================="
log "INFO" "开始部署 Nginx (离线编译安装) - x86"
log "INFO" "=================================================================="
# 目录预检查,缺失则创建
for dir in "${required_dirs[@]}"; do
if [ ! -d "$dir" ]; then
log "WARN" "目录 $dir 不存在,自动创建"
mkdir -p "$dir" || {
log "ERROR" "目录 $dir 创建失败"
return 1
}
fi
done
#创建nginx用户
groupadd -r nginx
useradd -r -g nginx -s /sbin/nologin -d /var/cache/nginx nginx
#检查是否创建成功
id nginx
#赋予权限
chown -R nginx:nginx /data/middleware/nginx/data/cache
chmod -R 755 /data/middleware/nginx/data/cache
# 赋予权限
chown -R 1000:1000 /data/middleware/nginx/log
chown -R 1000:1000 /data/middleware/nginx/data/cache
chmod -R 700 /data/middleware/nginx/data/cache
# 校验镜像包
if [ ! -s "$nginx_image_tar" ]; then
log "ERROR" "离线包 $nginx_image_tar 不存在或为空"
return 1
fi
# 加载镜像文件
if ! docker load -i "$nginx_image_tar"; then
log "ERROR" "镜像加载失败"
return 1
fi
log "INFO" "镜像加载成功"
# 检查容器是否存在
if docker ps -a --format '{{.Names}}' | grep -qw "$nginx_container_name"; then
log "WARN" "容器 $nginx_container_name 已存在,自动退出部署操作!!!"
return 0
fi
# 生成容器
if ! docker run -d \
--name "$nginx_container_name" \
--restart=always \
--mac-address "02:42:ac:11:00:25" \
-v /etc/localtime:/etc/localtime:ro \
-p 443:443 \
-v /data/middleware/nginx/config:/etc/nginx/conf.d \
-v /data/middleware/nginx/data/html:/usr/share/nginx/html \
-v /data/middleware/nginx/log:/var/log/nginx \
-v /data/middleware/nginx/data/cache:/var/cache/nginx \
-v /data/services/web:/data/services/web:rw \
-v /data/security/nginx_cert:/data/security/nginx_cert:ro \
"$nginx_image"; then
log "ERROR" "容器 $nginx_container_name 启动失败"
return 1
fi
# 拷贝/data/temp/nginx.conf到容器内/etc/nginx/目录下
docker cp /data/temp/nginx.conf $nginx_container_name:/etc/nginx/
log "INFO 已将nginx.conf复制到容器内/etc/nginx/目录下"
# 重启unginx容器
docker restart $nginx_container_name
log "INFO" "容器 $nginx_container_name 启动成功"
return 0
}
# 无纸化信令服务部署
function paperless_x86() {
log "INFO" "=================================================================="
......@@ -3799,13 +2735,8 @@ function deploy_services() {
check_files
# 安装服务
docker_x86
mysql_x86
redis_x86
emqx_x86
fastfds_x86
ngrok_x86
nacos_x86
nginx_x86
# 部署中间件服务(mysql, redis, emqx, fdfs, ngrok, nacos, nginx)
middleware_type="mysql redis emqx fdfs ngrok nacos nginx" install_middleware
ntp_uos
deploy_jdk_host
start_java_meeting_service
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论