2026-02-01 03:12:27 +08:00
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
|
|
|
|
# ========================================
|
|
|
|
|
|
# PolyHermes 交互式一键部署脚本
|
|
|
|
|
|
# ========================================
|
|
|
|
|
|
# 功能:
|
|
|
|
|
|
# - 交互式配置环境变量
|
|
|
|
|
|
# - 自动生成安全密钥
|
|
|
|
|
|
# - 使用 Docker Hub 线上镜像部署
|
|
|
|
|
|
# - 支持配置预检和回滚
|
|
|
|
|
|
# ========================================
|
|
|
|
|
|
|
|
|
|
|
|
set -e
|
|
|
|
|
|
|
|
|
|
|
|
# 颜色输出
|
|
|
|
|
|
RED='\033[0;31m'
|
|
|
|
|
|
GREEN='\033[0;32m'
|
|
|
|
|
|
YELLOW='\033[1;33m'
|
|
|
|
|
|
BLUE='\033[0;34m'
|
|
|
|
|
|
CYAN='\033[0;36m'
|
|
|
|
|
|
NC='\033[0m' # No Color
|
|
|
|
|
|
|
|
|
|
|
|
# 打印函数
|
|
|
|
|
|
info() {
|
|
|
|
|
|
echo -e "${GREEN}[✓]${NC} $1"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
warn() {
|
|
|
|
|
|
echo -e "${YELLOW}[⚠]${NC} $1"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
error() {
|
|
|
|
|
|
echo -e "${RED}[✗]${NC} $1"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
title() {
|
|
|
|
|
|
echo -e "${CYAN}${1}${NC}"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 生成随机密钥
|
|
|
|
|
|
generate_secret() {
|
|
|
|
|
|
local length=${1:-32}
|
|
|
|
|
|
if command -v openssl &> /dev/null; then
|
|
|
|
|
|
openssl rand -hex $length
|
|
|
|
|
|
else
|
|
|
|
|
|
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $((length * 2)) | head -n 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 生成随机端口号(10000-60000之间)
|
|
|
|
|
|
generate_random_port() {
|
|
|
|
|
|
echo $((10000 + RANDOM % 50001))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 读取用户输入(支持默认值)
|
|
|
|
|
|
read_input() {
|
|
|
|
|
|
local prompt="$1"
|
|
|
|
|
|
local default="$2"
|
|
|
|
|
|
local is_secret="$3"
|
|
|
|
|
|
local value=""
|
|
|
|
|
|
|
|
|
|
|
|
# 构建提示信息(不使用颜色,因为 read -p 可能不支持)
|
|
|
|
|
|
local prompt_text=""
|
|
|
|
|
|
if [ -n "$default" ]; then
|
|
|
|
|
|
if [ "$is_secret" = "secret" ]; then
|
|
|
|
|
|
prompt_text="${prompt} [回车自动生成]: "
|
|
|
|
|
|
else
|
|
|
|
|
|
prompt_text="${prompt} [默认: ${default}]: "
|
|
|
|
|
|
fi
|
|
|
|
|
|
else
|
|
|
|
|
|
prompt_text="${prompt}: "
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 使用 read -p 确保提示正确显示
|
|
|
|
|
|
read -r -p "$prompt_text" value
|
|
|
|
|
|
|
|
|
|
|
|
# 如果用户没有输入,使用默认值
|
|
|
|
|
|
if [ -z "$value" ]; then
|
|
|
|
|
|
if [ "$is_secret" = "secret" ] && [ -z "$default" ]; then
|
|
|
|
|
|
# 自动生成密钥
|
|
|
|
|
|
case "$prompt" in
|
|
|
|
|
|
*JWT*)
|
|
|
|
|
|
value=$(generate_secret 64)
|
|
|
|
|
|
# 输出到 stderr,避免被捕获到返回值中
|
|
|
|
|
|
info "已自动生成 JWT 密钥(128字符)" >&2
|
|
|
|
|
|
;;
|
|
|
|
|
|
*管理员*|*ADMIN*)
|
|
|
|
|
|
value=$(generate_secret 32)
|
|
|
|
|
|
info "已自动生成管理员重置密钥(64字符)" >&2
|
|
|
|
|
|
;;
|
|
|
|
|
|
*加密*|*CRYPTO*)
|
|
|
|
|
|
value=$(generate_secret 32)
|
|
|
|
|
|
info "已自动生成加密密钥(64字符)" >&2
|
|
|
|
|
|
;;
|
|
|
|
|
|
*数据库密码*|*DB_PASSWORD*)
|
|
|
|
|
|
value=$(generate_secret 16)
|
|
|
|
|
|
info "已自动生成数据库密码(32字符)" >&2
|
|
|
|
|
|
;;
|
|
|
|
|
|
*)
|
|
|
|
|
|
value="$default"
|
|
|
|
|
|
;;
|
|
|
|
|
|
esac
|
|
|
|
|
|
else
|
|
|
|
|
|
value="$default"
|
|
|
|
|
|
fi
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo "$value"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 检查 Docker 环境
|
|
|
|
|
|
check_docker() {
|
|
|
|
|
|
title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
title " 步骤 1: 环境检查"
|
|
|
|
|
|
title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
|
|
|
|
|
|
# 检查 Docker
|
|
|
|
|
|
if ! command -v docker &> /dev/null; then
|
|
|
|
|
|
error "Docker 未安装"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
info "请先安装 Docker:"
|
|
|
|
|
|
info " macOS: brew install docker"
|
|
|
|
|
|
info " Ubuntu/Debian: apt-get install docker.io"
|
|
|
|
|
|
info " CentOS/RHEL: yum install docker"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
info "Docker 已安装: $(docker --version | head -1)"
|
|
|
|
|
|
|
|
|
|
|
|
# 检查 Docker Compose
|
|
|
|
|
|
if docker compose version &> /dev/null 2>&1; then
|
|
|
|
|
|
info "Docker Compose 已安装: $(docker compose version)"
|
|
|
|
|
|
elif command -v docker-compose &> /dev/null; then
|
|
|
|
|
|
info "Docker Compose 已安装: $(docker-compose --version)"
|
|
|
|
|
|
else
|
|
|
|
|
|
error "Docker Compose 未安装"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
info "请先安装 Docker Compose:"
|
|
|
|
|
|
info " https://docs.docker.com/compose/install/"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 检查 Docker 守护进程
|
|
|
|
|
|
if ! docker info &> /dev/null; then
|
|
|
|
|
|
error "Docker 守护进程未运行"
|
|
|
|
|
|
info "请启动 Docker 服务:"
|
|
|
|
|
|
info " macOS: 打开 Docker Desktop"
|
|
|
|
|
|
info " Linux: systemctl start docker"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
info "Docker 守护进程运行正常"
|
|
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 交互式配置收集
|
|
|
|
|
|
collect_configuration() {
|
|
|
|
|
|
title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
title " 步骤 2: 配置收集"
|
|
|
|
|
|
title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
info "💡 所有配置项均为可选,直接按回车即可使用默认值或自动生成"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
warn "密钥配置:回车将自动生成安全的随机密钥"
|
|
|
|
|
|
warn "其他配置:回车将使用括号中的默认值"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
|
|
# 基础配置
|
|
|
|
|
|
title "【基础配置】"
|
|
|
|
|
|
echo -e "${CYAN}将配置:服务器端口、MySQL端口、时区${NC}"
|
|
|
|
|
|
# 生成随机端口作为默认值
|
|
|
|
|
|
DEFAULT_PORT=$(generate_random_port)
|
|
|
|
|
|
SERVER_PORT=$(read_input "➤ 服务器端口" "$DEFAULT_PORT")
|
|
|
|
|
|
MYSQL_PORT=$(read_input "➤ MySQL 端口(外部访问)" "3307")
|
|
|
|
|
|
TZ=$(read_input "➤ 时区" "Asia/Shanghai")
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
|
|
# 数据库配置
|
|
|
|
|
|
title "【数据库配置】"
|
|
|
|
|
|
echo -e "${CYAN}将配置:数据库用户名、数据库密码${NC}"
|
|
|
|
|
|
echo -e "${YELLOW}💡 提示:密码留空将自动生成 32 字符的安全随机密码${NC}"
|
|
|
|
|
|
DB_USERNAME=$(read_input "➤ 数据库用户名" "root")
|
|
|
|
|
|
DB_PASSWORD=$(read_input "➤ 数据库密码" "" "secret")
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
|
|
# 安全配置
|
|
|
|
|
|
title "【安全配置】"
|
|
|
|
|
|
echo -e "${CYAN}将配置:JWT密钥、管理员密码重置密钥、数据加密密钥${NC}"
|
|
|
|
|
|
echo -e "${YELLOW}💡 提示:留空将自动生成高强度随机密钥(推荐)${NC}"
|
|
|
|
|
|
JWT_SECRET=$(read_input "➤ JWT 密钥" "" "secret")
|
|
|
|
|
|
ADMIN_RESET_PASSWORD_KEY=$(read_input "➤ 管理员密码重置密钥" "" "secret")
|
|
|
|
|
|
CRYPTO_SECRET_KEY=$(read_input "➤ 加密密钥(用于加密 API Key)" "" "secret")
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
|
|
# 日志配置
|
|
|
|
|
|
title "【日志配置】"
|
|
|
|
|
|
echo -e "${CYAN}将配置:Root日志级别、应用日志级别${NC}"
|
|
|
|
|
|
echo -e "${YELLOW}可选级别: TRACE, DEBUG, INFO, WARN, ERROR, OFF${NC}"
|
|
|
|
|
|
LOG_LEVEL_ROOT=$(read_input "➤ Root 日志级别(第三方库)" "WARN")
|
|
|
|
|
|
LOG_LEVEL_APP=$(read_input "➤ 应用日志级别" "INFO")
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
|
|
# 自动设置不需要用户输入的配置
|
|
|
|
|
|
SPRING_PROFILES_ACTIVE="prod"
|
|
|
|
|
|
ALLOW_PRERELEASE="false"
|
|
|
|
|
|
GITHUB_REPO="WrBug/PolyHermes"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 下载 docker-compose.prod.yml(如果不存在)
|
|
|
|
|
|
download_docker_compose_file() {
|
|
|
|
|
|
title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
title " 步骤 3: 获取部署配置"
|
|
|
|
|
|
title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
|
|
|
|
|
|
if [ -f "docker-compose.prod.yml" ]; then
|
|
|
|
|
|
info "检测到现有 docker-compose.prod.yml,跳过下载"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
return 0
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
info "正在从 GitHub 下载 docker-compose.prod.yml..."
|
|
|
|
|
|
|
|
|
|
|
|
# GitHub raw 文件链接
|
|
|
|
|
|
local compose_url="https://raw.githubusercontent.com/WrBug/PolyHermes/main/docker-compose.prod.yml"
|
|
|
|
|
|
|
|
|
|
|
|
# 尝试下载
|
|
|
|
|
|
if curl -fsSL "$compose_url" -o docker-compose.prod.yml; then
|
|
|
|
|
|
info "docker-compose.prod.yml 下载成功"
|
|
|
|
|
|
else
|
|
|
|
|
|
error "docker-compose.prod.yml 下载失败"
|
|
|
|
|
|
warn "请检查网络连接或手动下载:"
|
|
|
|
|
|
warn " $compose_url"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 生成 .env 文件
|
|
|
|
|
|
generate_env_file() {
|
|
|
|
|
|
title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
title " 步骤 4: 生成环境变量文件"
|
|
|
|
|
|
title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
|
|
|
|
|
|
# 备份现有 .env 文件
|
|
|
|
|
|
if [ -f ".env" ]; then
|
|
|
|
|
|
BACKUP_FILE=".env.backup.$(date +%Y%m%d_%H%M%S)"
|
|
|
|
|
|
cp .env "$BACKUP_FILE"
|
|
|
|
|
|
warn "已备份现有配置文件到: $BACKUP_FILE"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 生成新的 .env 文件
|
|
|
|
|
|
cat > .env <<EOF
|
|
|
|
|
|
# ========================================
|
|
|
|
|
|
# PolyHermes 生产环境配置
|
|
|
|
|
|
# 生成时间: $(date '+%Y-%m-%d %H:%M:%S')
|
|
|
|
|
|
# ========================================
|
|
|
|
|
|
|
|
|
|
|
|
# ============================================
|
|
|
|
|
|
# 基础配置
|
|
|
|
|
|
# ============================================
|
|
|
|
|
|
TZ=${TZ}
|
|
|
|
|
|
SPRING_PROFILES_ACTIVE=${SPRING_PROFILES_ACTIVE}
|
|
|
|
|
|
SERVER_PORT=${SERVER_PORT}
|
|
|
|
|
|
MYSQL_PORT=${MYSQL_PORT}
|
|
|
|
|
|
|
|
|
|
|
|
# ============================================
|
|
|
|
|
|
# 数据库配置
|
|
|
|
|
|
# ============================================
|
|
|
|
|
|
DB_URL=jdbc:mysql://mysql:3306/polyhermes?useSSL=false&serverTimezone=UTC&characterEncoding=utf8&allowPublicKeyRetrieval=true
|
|
|
|
|
|
DB_USERNAME=${DB_USERNAME}
|
|
|
|
|
|
DB_PASSWORD=${DB_PASSWORD}
|
|
|
|
|
|
|
|
|
|
|
|
# ============================================
|
|
|
|
|
|
# 安全配置(请妥善保管)
|
|
|
|
|
|
# ============================================
|
|
|
|
|
|
JWT_SECRET=${JWT_SECRET}
|
|
|
|
|
|
ADMIN_RESET_PASSWORD_KEY=${ADMIN_RESET_PASSWORD_KEY}
|
|
|
|
|
|
CRYPTO_SECRET_KEY=${CRYPTO_SECRET_KEY}
|
|
|
|
|
|
|
|
|
|
|
|
# ============================================
|
|
|
|
|
|
# 日志配置
|
|
|
|
|
|
# ============================================
|
|
|
|
|
|
LOG_LEVEL_ROOT=${LOG_LEVEL_ROOT}
|
|
|
|
|
|
LOG_LEVEL_APP=${LOG_LEVEL_APP}
|
|
|
|
|
|
|
|
|
|
|
|
# ============================================
|
|
|
|
|
|
# 其他配置
|
|
|
|
|
|
# ============================================
|
|
|
|
|
|
ALLOW_PRERELEASE=${ALLOW_PRERELEASE}
|
|
|
|
|
|
GITHUB_REPO=${GITHUB_REPO}
|
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
|
|
info "配置文件已生成: .env"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
|
|
# 显示配置摘要
|
|
|
|
|
|
title "【配置摘要】"
|
|
|
|
|
|
echo " 服务器端口: ${SERVER_PORT}"
|
|
|
|
|
|
echo " MySQL 端口: ${MYSQL_PORT}"
|
|
|
|
|
|
echo " 时区: ${TZ}"
|
|
|
|
|
|
echo " 数据库用户: ${DB_USERNAME}"
|
|
|
|
|
|
echo " 数据库密码: ${DB_PASSWORD:0:8}... (已隐藏)"
|
|
|
|
|
|
echo " JWT 密钥: ${JWT_SECRET:0:16}... (已隐藏)"
|
|
|
|
|
|
echo " 管理员重置密钥: ${ADMIN_RESET_PASSWORD_KEY:0:16}... (已隐藏)"
|
|
|
|
|
|
echo " 加密密钥: ${CRYPTO_SECRET_KEY:0:16}... (已隐藏)"
|
|
|
|
|
|
echo " 日志级别: Root=${LOG_LEVEL_ROOT}, App=${LOG_LEVEL_APP}"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 拉取镜像
|
|
|
|
|
|
pull_images() {
|
|
|
|
|
|
title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
title " 步骤 5: 拉取 Docker 镜像"
|
|
|
|
|
|
title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
|
|
|
|
|
|
info "正在从 Docker Hub 拉取最新镜像..."
|
|
|
|
|
|
|
|
|
|
|
|
# 拉取应用镜像
|
|
|
|
|
|
if docker pull wrbug/polyhermes:latest; then
|
|
|
|
|
|
info "应用镜像拉取成功: wrbug/polyhermes:latest"
|
|
|
|
|
|
else
|
|
|
|
|
|
error "应用镜像拉取失败"
|
|
|
|
|
|
warn "可能的原因:"
|
|
|
|
|
|
warn " 1. 网络连接问题"
|
|
|
|
|
|
warn " 2. Docker Hub 服务异常"
|
|
|
|
|
|
warn " 3. 镜像不存在"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 拉取 MySQL 镜像
|
|
|
|
|
|
if docker pull mysql:8.2; then
|
|
|
|
|
|
info "MySQL 镜像拉取成功: mysql:8.2"
|
|
|
|
|
|
else
|
|
|
|
|
|
warn "MySQL 镜像拉取失败,将在启动时自动下载"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 部署服务
|
|
|
|
|
|
deploy_services() {
|
|
|
|
|
|
title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
title " 步骤 6: 部署服务"
|
|
|
|
|
|
title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
|
|
|
|
|
|
# 停止现有服务
|
|
|
|
|
|
if docker compose -f docker-compose.prod.yml ps -q 2>/dev/null | grep -q .; then
|
|
|
|
|
|
warn "检测到正在运行的服务,正在停止..."
|
|
|
|
|
|
docker compose -f docker-compose.prod.yml down
|
|
|
|
|
|
info "已停止现有服务"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 启动服务
|
|
|
|
|
|
info "正在启动服务..."
|
|
|
|
|
|
if docker compose -f docker-compose.prod.yml up -d; then
|
|
|
|
|
|
info "服务启动成功"
|
|
|
|
|
|
else
|
|
|
|
|
|
error "服务启动失败"
|
|
|
|
|
|
error "请检查日志: docker compose -f docker-compose.prod.yml logs"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 健康检查
|
|
|
|
|
|
health_check() {
|
|
|
|
|
|
title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
title " 步骤 7: 健康检查"
|
|
|
|
|
|
title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
|
|
|
|
|
|
info "等待服务启动(最多等待 60 秒)..."
|
|
|
|
|
|
|
|
|
|
|
|
local max_attempts=12
|
|
|
|
|
|
local attempt=0
|
|
|
|
|
|
|
|
|
|
|
|
while [ $attempt -lt $max_attempts ]; do
|
|
|
|
|
|
attempt=$((attempt + 1))
|
|
|
|
|
|
|
|
|
|
|
|
# 检查容器状态
|
|
|
|
|
|
if docker compose -f docker-compose.prod.yml ps | grep -q "Up"; then
|
|
|
|
|
|
info "容器运行正常"
|
|
|
|
|
|
|
|
|
|
|
|
# 检查应用是否响应
|
|
|
|
|
|
if curl -s -o /dev/null -w "%{http_code}" http://localhost:${SERVER_PORT} | grep -q "200\|302\|401"; then
|
|
|
|
|
|
info "应用响应正常"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
return 0
|
|
|
|
|
|
fi
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo -n "."
|
|
|
|
|
|
sleep 5
|
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
warn "健康检查超时,请手动检查服务状态"
|
|
|
|
|
|
warn "查看日志: docker compose -f docker-compose.prod.yml logs -f"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 显示部署信息
|
|
|
|
|
|
show_deployment_info() {
|
|
|
|
|
|
title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
title " 部署完成!"
|
|
|
|
|
|
title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
|
|
info "访问地址: ${GREEN}http://localhost:${SERVER_PORT}${NC}"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
|
|
title "【常用命令】"
|
2026-02-01 03:17:58 +08:00
|
|
|
|
echo -e " 查看服务状态: ${CYAN}docker compose -f docker-compose.prod.yml ps${NC}"
|
|
|
|
|
|
echo -e " 查看日志: ${CYAN}docker compose -f docker-compose.prod.yml logs -f${NC}"
|
|
|
|
|
|
echo -e " 停止服务: ${CYAN}docker compose -f docker-compose.prod.yml down${NC}"
|
|
|
|
|
|
echo -e " 重启服务: ${CYAN}docker compose -f docker-compose.prod.yml restart${NC}"
|
|
|
|
|
|
echo -e " 更新镜像: ${CYAN}docker pull wrbug/polyhermes:latest && docker compose -f docker-compose.prod.yml up -d${NC}"
|
2026-02-01 03:12:27 +08:00
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
|
|
title "【数据库连接信息】"
|
2026-02-01 03:17:58 +08:00
|
|
|
|
echo -e " 主机: ${CYAN}localhost${NC}"
|
|
|
|
|
|
echo -e " 端口: ${CYAN}${MYSQL_PORT}${NC}"
|
|
|
|
|
|
echo -e " 数据库: ${CYAN}polyhermes${NC}"
|
|
|
|
|
|
echo -e " 用户名: ${CYAN}${DB_USERNAME}${NC}"
|
|
|
|
|
|
echo -e " 密码: ${CYAN}${DB_PASSWORD}${NC}"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
|
|
title "【管理员重置密钥】"
|
|
|
|
|
|
echo -e " 重置密钥: ${CYAN}${ADMIN_RESET_PASSWORD_KEY}${NC}"
|
|
|
|
|
|
echo -e " ${YELLOW}💡 此密钥用于重置管理员密码,请妥善保管${NC}"
|
2026-02-01 03:12:27 +08:00
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
|
|
warn "重要提示:"
|
|
|
|
|
|
warn " 1. 请妥善保管 .env 文件,勿提交到版本控制系统"
|
|
|
|
|
|
warn " 2. 定期备份数据库数据(位于 Docker volume: polyhermes_mysql-data)"
|
|
|
|
|
|
warn " 3. 生产环境建议配置反向代理(如 Nginx)并启用 HTTPS"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 主函数
|
|
|
|
|
|
main() {
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
title "========================================="
|
|
|
|
|
|
title " PolyHermes 交互式一键部署脚本 "
|
|
|
|
|
|
title "========================================="
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
|
|
# 执行部署流程
|
|
|
|
|
|
check_docker
|
|
|
|
|
|
|
|
|
|
|
|
# 检查是否已存在 .env 文件
|
|
|
|
|
|
if [ -f ".env" ]; then
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
title "【检测到现有配置】"
|
|
|
|
|
|
info "发现已存在的 .env 配置文件"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
echo -ne "${YELLOW}是否使用现有配置直接更新镜像?[Y/n]: ${NC}"
|
|
|
|
|
|
read -r use_existing
|
|
|
|
|
|
use_existing=${use_existing:-Y}
|
|
|
|
|
|
|
|
|
|
|
|
if [[ "$use_existing" =~ ^[Yy]$ ]]; then
|
|
|
|
|
|
info "将使用现有配置,跳过配置步骤"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
# 从现有 .env 文件读取必要的变量
|
|
|
|
|
|
source .env 2>/dev/null || true
|
|
|
|
|
|
else
|
|
|
|
|
|
warn "将重新配置,现有配置将被备份"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
collect_configuration
|
|
|
|
|
|
fi
|
|
|
|
|
|
else
|
|
|
|
|
|
collect_configuration
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
download_docker_compose_file
|
|
|
|
|
|
|
|
|
|
|
|
# 只有在重新配置时才生成新的 .env 文件
|
|
|
|
|
|
if [[ ! "$use_existing" =~ ^[Yy]$ ]] || [ ! -f ".env" ]; then
|
|
|
|
|
|
generate_env_file
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 确认部署
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
title "【确认部署】"
|
|
|
|
|
|
echo -ne "${YELLOW}是否开始部署?[Y/n](回车默认为是): ${NC}"
|
|
|
|
|
|
read -r confirm
|
|
|
|
|
|
|
|
|
|
|
|
# 默认为 Y,只有明确输入 n/N 才取消
|
|
|
|
|
|
confirm=${confirm:-Y}
|
|
|
|
|
|
if [[ "$confirm" =~ ^[Nn]$ ]]; then
|
|
|
|
|
|
warn "部署已取消"
|
|
|
|
|
|
exit 0
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
pull_images
|
|
|
|
|
|
deploy_services
|
|
|
|
|
|
health_check
|
|
|
|
|
|
show_deployment_info
|
|
|
|
|
|
|
|
|
|
|
|
info "部署流程已完成!"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 捕获 Ctrl+C
|
|
|
|
|
|
trap 'echo ""; warn "部署已中断"; exit 1' INT
|
|
|
|
|
|
|
|
|
|
|
|
# 运行主函数
|
|
|
|
|
|
main "$@"
|