flnxi-Wu/scripts/tools/install.sh
WuYongJie d1c6efc79d
Some checks failed
CI Check / check (push) Has been cancelled
feat: NAS 部署与 Harbor 推送流程
2025-12-03 14:39:06 +08:00

379 lines
12 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# ============================================
# FLNXI素材库 - 一键安装脚本
# ============================================
set -e
echo "========================================"
echo " FLNXI素材库 - 一键安装向导"
echo "========================================"
echo ""
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 检查是否为root用户
if [ "$EUID" -eq 0 ]; then
echo -e "${YELLOW}警告: 不建议使用root用户运行此脚本${NC}"
read -p "是否继续? (y/n): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi
# 检查 Docker 是否安装
echo -e "${BLUE}[1/8]${NC} 检查 Docker 环境..."
if ! command -v docker &> /dev/null; then
echo -e "${RED}错误: 未检测到 Docker,请先安装 Docker${NC}"
echo "安装指南: https://docs.docker.com/engine/install/"
exit 1
fi
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
echo -e "${RED}错误: 未检测到 Docker Compose,请先安装 Docker Compose${NC}"
echo "安装指南: https://docs.docker.com/compose/install/"
exit 1
fi
# 检查 Docker 权限(自动处理)
echo "检查 Docker 权限..."
USE_SUDO=""
if ! docker ps &> /dev/null; then
# 检测到权限问题,自动使用 sudo
if command -v sudo &> /dev/null; then
echo -e "${YELLOW}检测到 Docker 权限问题,将自动使用 sudo 运行 Docker 命令${NC}"
USE_SUDO="sudo"
else
echo -e "${RED}错误: 无法访问 Docker 且未找到 sudo 命令${NC}"
echo "请使用 root 用户运行此脚本,或联系管理员配置 Docker 权限"
exit 1
fi
fi
# 更新 docker 和 docker-compose 命令
if [ -n "$USE_SUDO" ]; then
DOCKER_CMD="sudo docker"
# 检测 docker-compose 命令
if sudo docker compose version &> /dev/null; then
DOCKER_COMPOSE="sudo docker compose"
else
DOCKER_COMPOSE="sudo docker-compose"
fi
else
DOCKER_CMD="docker"
# 检测 docker-compose 命令
if docker compose version &> /dev/null; then
DOCKER_COMPOSE="docker compose"
else
DOCKER_COMPOSE="docker-compose"
fi
fi
# 验证 Docker 是否可用
if ! $DOCKER_CMD ps &> /dev/null; then
echo -e "${RED}错误: 无法访问 Docker,请检查权限或使用 root 用户运行${NC}"
exit 1
fi
echo -e "${GREEN}✓ Docker 环境检查通过${NC}"
echo -e "${GREEN}✓ 使用命令: $DOCKER_COMPOSE${NC}"
# 创建 .env.production 文件
echo ""
echo -e "${BLUE}[2/8]${NC} 配置环境变量..."
if [ ! -f .env.production ]; then
# 自动检测服务器IP
echo "正在自动检测服务器IP地址..."
# 尝试多种方法获取IP
SERVER_IP=""
# 方法1: 通过 ip route 获取
if command -v ip &> /dev/null; then
SERVER_IP=$(ip route get 1 2>/dev/null | awk '{print $7; exit}')
fi
# 方法2: 通过 hostname 获取
if [ -z "$SERVER_IP" ] && command -v hostname &> /dev/null; then
SERVER_IP=$(hostname -I 2>/dev/null | awk '{print $1}')
fi
# 方法3: 通过 ifconfig 获取
if [ -z "$SERVER_IP" ] && command -v ifconfig &> /dev/null; then
SERVER_IP=$(ifconfig 2>/dev/null | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | head -n 1)
fi
# 如果自动检测失败,提示用户输入
if [ -z "$SERVER_IP" ]; then
echo -e "${YELLOW}无法自动检测IP地址${NC}"
read -p "请输入服务器IP地址: " SERVER_IP
else
echo -e "${GREEN}检测到服务器IP: $SERVER_IP${NC}"
read -p "是否使用此IP? (Y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Nn]$ ]]; then
read -p "请输入服务器IP地址: " SERVER_IP
fi
fi
# 询问端口配置
echo ""
echo "端口配置 (直接回车使用默认值):"
read -p "应用端口 [4320]: " APP_PORT
APP_PORT=${APP_PORT:-4320}
read -p "MinIO API端口 [9000]: " MINIO_API_PORT
MINIO_API_PORT=${MINIO_API_PORT:-9000}
read -p "MinIO控制台端口 [9001]: " MINIO_CONSOLE_PORT
MINIO_CONSOLE_PORT=${MINIO_CONSOLE_PORT:-9001}
# 生成随机密码
echo ""
echo "生成安全密码..."
POSTGRES_PASSWORD=$(openssl rand -base64 16 2>/dev/null || cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)
MINIO_ROOT_PASSWORD=$(openssl rand -base64 16 2>/dev/null || cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)
NEXTAUTH_SECRET=$(openssl rand -base64 32 2>/dev/null || cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
# 询问初始管理员账号
echo ""
echo "配置初始管理员账号 (首次登录使用):"
read -p "管理员邮箱 [admin@flnxi.com]: " INIT_ADMIN_EMAIL
INIT_ADMIN_EMAIL=${INIT_ADMIN_EMAIL:-admin@flnxi.com}
read -sp "管理员密码 (输入时不会显示): " INIT_ADMIN_PASSWORD
echo
if [ -z "$INIT_ADMIN_PASSWORD" ]; then
INIT_ADMIN_PASSWORD=$(openssl rand -base64 16 2>/dev/null || cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)
echo -e "${YELLOW}已自动生成密码,请查看下方保存的信息${NC}"
fi
# 选择部署环境
echo ""
echo "选择部署环境:"
echo " 1) 测试环境 (test) - 使用测试镜像标签(需要登录)"
echo " 2) 正式环境 (prod) - 使用正式镜像标签(公开,无需登录)"
read -p "请选择 [1/2,默认: 2]: " ENV_CHOICE
ENV_CHOICE=${ENV_CHOICE:-2}
if [ "$ENV_CHOICE" = "1" ]; then
IMAGE_ENV="test"
IMAGE_TAG="test"
HARBOR_PROJECT="flnxi" # 使用同一个项目
echo -e "${YELLOW}已选择: 测试环境(需要 Harbor 登录)${NC}"
# 测试环境需要登录 Harbor(因为测试标签可能是私有的)
echo ""
echo "Harbor 镜像仓库配置(测试环境需要登录):"
read -p "Harbor 地址 [harbor.flnxi.com]: " HARBOR_URL
HARBOR_URL=${HARBOR_URL:-harbor.flnxi.com}
read -p "Harbor 用户名: " HARBOR_USERNAME
read -sp "Harbor 密码: " HARBOR_PASSWORD
echo
else
IMAGE_ENV="prod"
IMAGE_TAG="latest"
HARBOR_PROJECT="flnxi" # 使用同一个项目
echo -e "${GREEN}已选择: 正式环境(公开镜像,无需登录)${NC}"
# 正式环境使用公开镜像,无需登录
HARBOR_URL="harbor.flnxi.com"
HARBOR_USERNAME=""
HARBOR_PASSWORD=""
fi
# 创建 .env.production 文件(客户安装使用)
cat > .env.production << EOF
# FLNXI素材库 - 生产环境配置
# 生成时间: $(date)
# 服务器配置
SERVER_IP=$SERVER_IP
APP_PORT=$APP_PORT
# 数据库配置
POSTGRES_USER=postgres
POSTGRES_PASSWORD=$POSTGRES_PASSWORD
POSTGRES_DB=flnxi
# MinIO 配置
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=$MINIO_ROOT_PASSWORD
MINIO_API_PORT=$MINIO_API_PORT
MINIO_CONSOLE_PORT=$MINIO_CONSOLE_PORT
S3_BUCKET=flnxi-materials
# 应用安全配置
NEXTAUTH_SECRET=$NEXTAUTH_SECRET
NEXTAUTH_URL=http://$SERVER_IP:$APP_PORT
APP_PUBLIC_URL=http://$SERVER_IP:$APP_PORT
# 初始管理员账号
INIT_ADMIN_EMAIL=$INIT_ADMIN_EMAIL
INIT_ADMIN_PASSWORD=$INIT_ADMIN_PASSWORD
# 镜像环境配置
IMAGE_ENV=$IMAGE_ENV
IMAGE_TAG=$IMAGE_TAG
HARBOR_PROJECT=$HARBOR_PROJECT
DOCKER_REGISTRY=harbor.flnxi.com/$HARBOR_PROJECT
# Harbor 配置(如果配置了)
EOF
if [ -n "$HARBOR_USERNAME" ] && [ -n "$HARBOR_PASSWORD" ]; then
cat >> .env.production << EOF
HARBOR_URL=$HARBOR_URL
HARBOR_USERNAME=$HARBOR_USERNAME
HARBOR_PASSWORD=$HARBOR_PASSWORD
EOF
fi
echo -e "${GREEN}✓ 环境配置文件已创建${NC}"
echo ""
echo -e "${YELLOW}重要信息 (请保存):${NC}"
echo "----------------------------------------"
echo "服务器IP: $SERVER_IP"
echo "应用端口: $APP_PORT"
echo "应用地址: http://$SERVER_IP:$APP_PORT"
echo ""
echo "初始管理员账号:"
echo " - 邮箱: $INIT_ADMIN_EMAIL"
echo " - 密码: $INIT_ADMIN_PASSWORD"
echo ""
echo "MinIO控制台: http://$SERVER_IP:$MINIO_CONSOLE_PORT"
echo " - 用户名: minioadmin"
echo " - 密码: $MINIO_ROOT_PASSWORD"
echo ""
echo "数据库信息:"
echo " - 数据库名: flnxi"
echo " - 用户名: postgres"
echo " - 密码: $POSTGRES_PASSWORD"
echo "----------------------------------------"
echo ""
read -p "按回车键继续安装..."
else
echo -e "${GREEN}✓ 检测到已存在的配置文件${NC}"
if [ -f .env.production ]; then
source .env.production
elif [ -f .env ]; then
source .env
fi
fi
# 创建必要的目录
echo ""
echo -e "${BLUE}[3/8]${NC} 创建数据目录..."
mkdir -p uploads
chmod 755 uploads
echo -e "${GREEN}✓ 数据目录创建完成${NC}"
# 登录 Harbor(如果配置了)
if [ -n "$HARBOR_USERNAME" ] && [ -n "$HARBOR_PASSWORD" ]; then
echo ""
echo -e "${BLUE}[4/8]${NC} 登录 Harbor 镜像仓库..."
echo "$HARBOR_PASSWORD" | docker login $HARBOR_URL -u $HARBOR_USERNAME --password-stdin
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ Harbor 登录成功${NC}"
else
echo -e "${YELLOW}警告: Harbor 登录失败,将尝试继续...${NC}"
fi
else
echo ""
echo -e "${BLUE}[4/8]${NC} 跳过 Harbor 登录(使用公开镜像或已登录)..."
fi
# 停止旧容器(如果存在)
echo ""
echo -e "${BLUE}[5/8]${NC} 清理旧容器..."
$DOCKER_COMPOSE -f docker-compose.prod.yml down 2>/dev/null || true
echo -e "${GREEN}✓ 清理完成${NC}"
# 拉取镜像(从 Harbor)
echo ""
echo -e "${BLUE}[6/8]${NC} 拉取 Docker 镜像..."
echo "这可能需要几分钟时间,请耐心等待..."
$DOCKER_COMPOSE -f docker-compose.prod.yml pull
echo -e "${GREEN}✓ 镜像拉取完成${NC}"
# 启动服务
echo ""
echo -e "${BLUE}[7/8]${NC} 启动服务..."
$DOCKER_COMPOSE -f docker-compose.prod.yml up -d
echo -e "${GREEN}✓ 服务启动成功${NC}"
# 等待服务就绪
echo ""
echo -e "${BLUE}[8/8]${NC} 等待服务启动..."
echo "正在等待数据库启动..."
sleep 10
# 检查服务状态
echo ""
echo "检查服务状态..."
$DOCKER_COMPOSE -f docker-compose.prod.yml ps
# 初始化数据库
echo ""
echo "初始化数据库..."
max_retries=30
retry_count=0
while [ $retry_count -lt $max_retries ]; do
if $DOCKER_COMPOSE -f docker-compose.prod.yml exec -T app npx prisma db push --accept-data-loss 2>/dev/null; then
echo -e "${GREEN}✓ 数据库初始化成功${NC}"
break
else
retry_count=$((retry_count + 1))
if [ $retry_count -lt $max_retries ]; then
echo "等待应用启动... ($retry_count/$max_retries)"
sleep 5
else
echo -e "${RED}数据库初始化失败,请稍后手动执行:${NC}"
echo " $DOCKER_COMPOSE -f docker-compose.prod.yml exec app npx prisma db push"
fi
fi
done
# 显示安装完成信息
echo ""
echo "========================================"
echo -e "${GREEN} 安装完成!${NC}"
echo "========================================"
echo ""
echo -e "${BLUE}访问地址:${NC}"
echo " 应用首页: http://$SERVER_IP:$APP_PORT"
echo " MinIO控制台: http://$SERVER_IP:$MINIO_CONSOLE_PORT"
echo ""
echo -e "${BLUE}MinIO 管理员账号:${NC}"
echo " 用户名: minioadmin"
echo " 密码: $MINIO_ROOT_PASSWORD"
echo ""
echo -e "${BLUE}首次使用:${NC}"
echo " 1. 访问 http://$SERVER_IP:$APP_PORT"
echo " 2. 使用初始管理员账号登录:"
echo " - 邮箱: $INIT_ADMIN_EMAIL"
echo " - 密码: $INIT_ADMIN_PASSWORD"
echo " 3. 登录后可在系统设置中修改密码"
echo ""
echo -e "${BLUE}常用命令:${NC}"
echo " 查看日志: $DOCKER_COMPOSE -f docker-compose.prod.yml logs -f"
echo " 重启服务: $DOCKER_COMPOSE -f docker-compose.prod.yml restart"
echo " 停止服务: $DOCKER_COMPOSE -f docker-compose.prod.yml down"
echo " 启动服务: $DOCKER_COMPOSE -f docker-compose.prod.yml up -d"
echo ""
echo -e "${YELLOW}注意事项:${NC}"
echo " - 所有配置信息已保存在 .env.production 文件中"
echo " - 请妥善保管初始管理员账号、数据库密码和MinIO密码"
echo " - 数据存储在 Docker volumes 中,卸载前请备份"
echo ""
echo "========================================"