添加一键部署脚本

This commit is contained in:
2025-12-15 13:57:25 +08:00
parent 10d5363e29
commit 809c735498

417
install.sh Executable file
View File

@@ -0,0 +1,417 @@
#!/bin/bash
# zsglpt 一键部署脚本
# 用法: curl -sSL https://your-domain/install.sh | bash
# 或: bash install.sh [install|uninstall|ssl|status]
set -e
# ==================== 配置 ====================
APP_NAME="zsglpt"
APP_PORT="51233"
CONTAINER_NAME="knowledge-automation-multiuser"
GIT_REPO="https://git.workyai.cn/237899745/zsglpt.git"
INSTALL_DIR="/opt/$APP_NAME"
# ==================== 颜色 ====================
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
log_step() { echo -e "${BLUE}[STEP]${NC} $1"; }
# ==================== 检测环境 ====================
detect_os() {
if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$ID
else
log_error "无法检测操作系统"
fi
}
detect_bt_panel() {
if [ -d "/www/server/panel" ] && [ -f "/etc/init.d/bt" ]; then
BT_PANEL=true
BT_NGINX_VHOST="/www/server/panel/vhost/nginx"
BT_NGINX_BIN="/www/server/nginx/sbin/nginx"
log_info "检测到宝塔面板"
else
BT_PANEL=false
log_info "未检测到宝塔面板,使用系统 nginx"
fi
}
check_root() {
if [ "$EUID" -ne 0 ]; then
log_error "请使用 root 用户运行此脚本"
fi
}
# ==================== 安装依赖 ====================
install_deps() {
log_step "安装依赖..."
if command -v apt &> /dev/null; then
apt update -qq
apt install -y -qq git curl docker.io docker-compose nginx certbot python3-certbot-nginx 2>/dev/null || true
elif command -v yum &> /dev/null; then
yum install -y -q git curl docker docker-compose nginx certbot python3-certbot-nginx 2>/dev/null || true
fi
# 启动 docker
systemctl enable docker 2>/dev/null || true
systemctl start docker 2>/dev/null || true
}
# ==================== 交互式配置 ====================
get_config() {
echo ""
echo -e "${BLUE}========== $APP_NAME 部署配置 ==========${NC}"
echo ""
# 域名
read -p "请输入域名 (例: zsglpt.example.com): " DOMAIN
if [ -z "$DOMAIN" ]; then
log_error "域名不能为空"
fi
# 端口
read -p "请输入服务端口 [默认: $APP_PORT]: " INPUT_PORT
APP_PORT=${INPUT_PORT:-$APP_PORT}
# Git 认证
read -p "Git 用户名 [默认: 237899745]: " GIT_USER
GIT_USER=${GIT_USER:-237899745}
read -sp "Git 密码: " GIT_PASS
echo ""
if [ -z "$GIT_PASS" ]; then
log_error "Git 密码不能为空"
fi
# SSL
read -p "是否配置 SSL? [Y/n]: " SETUP_SSL
SETUP_SSL=${SETUP_SSL:-Y}
if [[ "$SETUP_SSL" =~ ^[Yy]$ ]]; then
read -p "SSL 证书邮箱 (用于 Let's Encrypt): " SSL_EMAIL
SSL_EMAIL=${SSL_EMAIL:-admin@$DOMAIN}
fi
# 确认
echo ""
echo -e "${YELLOW}========== 配置确认 ==========${NC}"
echo "域名: $DOMAIN"
echo "端口: $APP_PORT"
echo "安装目录: $INSTALL_DIR"
echo "SSL: $SETUP_SSL"
echo ""
read -p "确认安装? [Y/n]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^[Yy]?$ ]]; then
log_error "安装已取消"
fi
}
# ==================== 克隆代码 ====================
clone_repo() {
log_step "克隆代码..."
if [ -d "$INSTALL_DIR" ]; then
log_warn "目录已存在,更新代码..."
cd "$INSTALL_DIR"
git fetch origin
git reset --hard origin/master
else
GIT_URL="https://${GIT_USER}:${GIT_PASS}@git.workyai.cn/237899745/zsglpt.git"
git clone "$GIT_URL" "$INSTALL_DIR"
cd "$INSTALL_DIR"
fi
# 保存配置
cat > "$INSTALL_DIR/.deploy_config" << EOF
DOMAIN=$DOMAIN
APP_PORT=$APP_PORT
GIT_USER=$GIT_USER
SSL_EMAIL=$SSL_EMAIL
INSTALL_TIME=$(date '+%Y-%m-%d %H:%M:%S')
EOF
}
# ==================== Docker 部署 ====================
deploy_docker() {
log_step "部署 Docker 容器..."
cd "$INSTALL_DIR"
# 修改 docker-compose 端口映射
if [ -f docker-compose.yml ]; then
sed -i "s/51232:51233/${APP_PORT}:51233/g" docker-compose.yml
fi
# 构建并启动
docker-compose down 2>/dev/null || true
docker-compose up -d --build
log_info "等待容器启动..."
sleep 8
if docker ps | grep -q "$CONTAINER_NAME"; then
log_info "容器启动成功"
else
log_error "容器启动失败,请检查日志: docker logs $CONTAINER_NAME"
fi
}
# ==================== Nginx 配置 ====================
setup_nginx() {
log_step "配置 Nginx..."
if $BT_PANEL; then
NGINX_CONF="$BT_NGINX_VHOST/${DOMAIN}.conf"
NGINX_CMD="$BT_NGINX_BIN"
else
NGINX_CONF="/etc/nginx/sites-available/${DOMAIN}.conf"
NGINX_CMD="nginx"
fi
# 生成配置
cat > "$NGINX_CONF" << EOF
# $APP_NAME - $DOMAIN
# 由 install.sh 自动生成,请勿手动修改
server {
listen 80;
server_name $DOMAIN;
location / {
proxy_pass http://127.0.0.1:$APP_PORT;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
}
}
EOF
# 非宝塔环境需要创建软链接
if ! $BT_PANEL; then
ln -sf "$NGINX_CONF" "/etc/nginx/sites-enabled/${DOMAIN}.conf" 2>/dev/null || true
fi
# 测试并重载
$NGINX_CMD -t && $NGINX_CMD -s reload
log_info "Nginx 配置完成"
}
# ==================== SSL 配置 ====================
setup_ssl() {
if [[ ! "$SETUP_SSL" =~ ^[Yy]$ ]]; then
return
fi
log_step "配置 SSL 证书..."
if $BT_PANEL; then
# 宝塔面板使用 acme.sh
if [ -f "/root/.acme.sh/acme.sh" ]; then
/root/.acme.sh/acme.sh --issue -d "$DOMAIN" --webroot "$INSTALL_DIR/static" --force || true
# 更新 nginx 配置
NGINX_CONF="$BT_NGINX_VHOST/${DOMAIN}.conf"
cat > "$NGINX_CONF" << EOF
# $APP_NAME - $DOMAIN (SSL)
# 由 install.sh 自动生成
server {
listen 80;
server_name $DOMAIN;
return 301 https://\$host\$request_uri;
}
server {
listen 443 ssl http2;
server_name $DOMAIN;
ssl_certificate /root/.acme.sh/${DOMAIN}_ecc/fullchain.cer;
ssl_certificate_key /root/.acme.sh/${DOMAIN}_ecc/${DOMAIN}.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://127.0.0.1:$APP_PORT;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_read_timeout 86400;
}
}
EOF
$BT_NGINX_BIN -t && $BT_NGINX_BIN -s reload
else
log_warn "未找到 acme.sh请在宝塔面板手动配置 SSL"
fi
else
# 使用 certbot
certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos -m "$SSL_EMAIL" || log_warn "SSL 配置失败,请手动配置"
fi
log_info "SSL 配置完成"
}
# ==================== 卸载 ====================
uninstall() {
echo -e "${RED}========== 卸载 $APP_NAME ==========${NC}"
# 读取配置
if [ -f "$INSTALL_DIR/.deploy_config" ]; then
source "$INSTALL_DIR/.deploy_config"
else
read -p "请输入域名: " DOMAIN
fi
read -p "确认卸载 $APP_NAME? 数据将被删除! [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then
log_info "卸载已取消"
exit 0
fi
log_step "停止容器..."
cd "$INSTALL_DIR" 2>/dev/null && docker-compose down 2>/dev/null || true
docker rm -f "$CONTAINER_NAME" 2>/dev/null || true
log_step "删除 Nginx 配置..."
detect_bt_panel
if $BT_PANEL; then
rm -f "$BT_NGINX_VHOST/${DOMAIN}.conf"
$BT_NGINX_BIN -s reload 2>/dev/null || true
else
rm -f "/etc/nginx/sites-available/${DOMAIN}.conf"
rm -f "/etc/nginx/sites-enabled/${DOMAIN}.conf"
nginx -s reload 2>/dev/null || true
fi
# 备份数据
if [ -d "$INSTALL_DIR/data" ]; then
BACKUP_DIR="/root/${APP_NAME}_backup_$(date +%Y%m%d_%H%M%S)"
log_step "备份数据到 $BACKUP_DIR..."
mkdir -p "$BACKUP_DIR"
cp -r "$INSTALL_DIR/data" "$BACKUP_DIR/"
fi
log_step "删除安装目录..."
rm -rf "$INSTALL_DIR"
log_info "卸载完成!"
[ -d "$BACKUP_DIR" ] && log_info "数据已备份到: $BACKUP_DIR"
}
# ==================== 状态检查 ====================
status() {
echo -e "${BLUE}========== $APP_NAME 状态 ==========${NC}"
if [ -f "$INSTALL_DIR/.deploy_config" ]; then
source "$INSTALL_DIR/.deploy_config"
echo "域名: $DOMAIN"
echo "端口: $APP_PORT"
echo "安装时间: $INSTALL_TIME"
fi
echo ""
echo "容器状态:"
docker ps -a | grep "$CONTAINER_NAME" || echo "容器未运行"
echo ""
echo "最近日志:"
docker logs --tail 10 "$CONTAINER_NAME" 2>/dev/null || echo "无日志"
}
# ==================== 更新 ====================
update() {
log_step "更新 $APP_NAME..."
if [ ! -d "$INSTALL_DIR" ]; then
log_error "未找到安装目录,请先安装"
fi
cd "$INSTALL_DIR"
# 备份数据库
if [ -f "data/app_data.db" ]; then
cp "data/app_data.db" "data/app_data.db.$(date +%Y%m%d_%H%M%S).bak"
fi
# 拉取代码
git fetch origin
git reset --hard origin/master
# 重建容器
docker-compose down
docker-compose up -d --build
log_info "更新完成!"
}
# ==================== 主函数 ====================
main() {
check_root
detect_os
detect_bt_panel
case "${1:-install}" in
install)
install_deps
get_config
clone_repo
deploy_docker
setup_nginx
setup_ssl
echo ""
echo -e "${GREEN}========== 安装完成 ==========${NC}"
echo "访问地址: http://$DOMAIN"
[[ "$SETUP_SSL" =~ ^[Yy]$ ]] && echo "HTTPS: https://$DOMAIN"
echo ""
;;
uninstall)
uninstall
;;
update)
update
;;
status)
status
;;
ssl)
if [ -f "$INSTALL_DIR/.deploy_config" ]; then
source "$INSTALL_DIR/.deploy_config"
fi
SETUP_SSL=Y
setup_ssl
;;
*)
echo "用法: $0 [install|uninstall|update|status|ssl]"
echo ""
echo " install - 安装部署 (默认)"
echo " uninstall - 卸载并备份数据"
echo " update - 更新到最新版本"
echo " status - 查看运行状态"
echo " ssl - 配置/更新 SSL 证书"
;;
esac
}
main "$@"