426 lines
14 KiB
Bash
426 lines
14 KiB
Bash
#!/bin/bash
|
||
|
||
# ============================================
|
||
# FLNXI素材库 - 全自动安装脚本
|
||
# 自动安装 Docker、Docker Compose 和应用
|
||
# ============================================
|
||
|
||
set -e
|
||
|
||
# 颜色定义
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m'
|
||
|
||
echo "========================================"
|
||
echo " FLNXI素材库 - 全自动安装"
|
||
echo "========================================"
|
||
echo ""
|
||
echo "此脚本将自动安装:"
|
||
echo " ✓ Docker"
|
||
echo " ✓ Docker Compose"
|
||
echo " ✓ FLNXI素材库系统"
|
||
echo ""
|
||
|
||
# 检查是否为root用户
|
||
if [ "$EUID" -ne 0 ]; then
|
||
echo -e "${YELLOW}提示: 建议使用 root 用户或 sudo 运行此脚本${NC}"
|
||
echo "如果遇到权限问题,请使用: sudo bash $0"
|
||
echo ""
|
||
fi
|
||
|
||
# 检测操作系统
|
||
detect_os() {
|
||
if [ -f /etc/os-release ]; then
|
||
. /etc/os-release
|
||
OS=$ID
|
||
OS_VERSION=$VERSION_ID
|
||
elif [ -f /etc/redhat-release ]; then
|
||
OS="centos"
|
||
else
|
||
OS=$(uname -s)
|
||
fi
|
||
|
||
echo -e "${BLUE}检测到操作系统: $OS $OS_VERSION${NC}"
|
||
}
|
||
|
||
# 安装 Docker
|
||
install_docker() {
|
||
echo ""
|
||
echo -e "${BLUE}[1/4]${NC} 检查 Docker..."
|
||
|
||
if command -v docker &> /dev/null; then
|
||
DOCKER_VERSION=$(docker --version | awk '{print $3}' | sed 's/,//')
|
||
echo -e "${GREEN}✓ Docker 已安装 (版本: $DOCKER_VERSION)${NC}"
|
||
|
||
# 检查 Docker 是否运行
|
||
if ! docker ps &> /dev/null; then
|
||
echo -e "${YELLOW}Docker 未运行,尝试启动...${NC}"
|
||
if command -v systemctl &> /dev/null; then
|
||
sudo systemctl start docker
|
||
sudo systemctl enable docker
|
||
else
|
||
sudo service docker start
|
||
fi
|
||
sleep 3
|
||
fi
|
||
return 0
|
||
fi
|
||
|
||
echo -e "${YELLOW}未检测到 Docker,开始安装...${NC}"
|
||
|
||
case $OS in
|
||
ubuntu|debian)
|
||
echo "使用 APT 安装 Docker..."
|
||
sudo apt-get update
|
||
sudo apt-get install -y \
|
||
ca-certificates \
|
||
curl \
|
||
gnupg \
|
||
lsb-release
|
||
|
||
# 添加 Docker 官方 GPG key
|
||
sudo mkdir -p /etc/apt/keyrings
|
||
curl -fsSL https://download.docker.com/linux/$OS/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||
|
||
# 添加 Docker 仓库
|
||
echo \
|
||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/$OS \
|
||
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||
|
||
# 安装 Docker
|
||
sudo apt-get update
|
||
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||
;;
|
||
|
||
centos|rhel|fedora)
|
||
echo "使用 YUM/DNF 安装 Docker..."
|
||
sudo yum install -y yum-utils
|
||
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
|
||
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||
;;
|
||
|
||
*)
|
||
echo -e "${YELLOW}使用通用安装脚本...${NC}"
|
||
curl -fsSL https://get.docker.com -o get-docker.sh
|
||
sudo sh get-docker.sh
|
||
rm get-docker.sh
|
||
;;
|
||
esac
|
||
|
||
# 启动 Docker
|
||
if command -v systemctl &> /dev/null; then
|
||
sudo systemctl start docker
|
||
sudo systemctl enable docker
|
||
else
|
||
sudo service docker start
|
||
fi
|
||
|
||
# 将当前用户添加到 docker 组
|
||
if [ "$EUID" -ne 0 ]; then
|
||
sudo usermod -aG docker $USER
|
||
echo -e "${YELLOW}注意: 需要重新登录以使 docker 组权限生效${NC}"
|
||
echo -e "${YELLOW}或运行: newgrp docker${NC}"
|
||
fi
|
||
|
||
sleep 3
|
||
echo -e "${GREEN}✓ Docker 安装完成${NC}"
|
||
}
|
||
|
||
# 安装 Docker Compose
|
||
install_docker_compose() {
|
||
echo ""
|
||
echo -e "${BLUE}[2/4]${NC} 检查 Docker Compose..."
|
||
|
||
# 检查是否已有 docker compose 插件
|
||
if docker compose version &> /dev/null; then
|
||
COMPOSE_VERSION=$(docker compose version | awk '{print $4}')
|
||
echo -e "${GREEN}✓ Docker Compose 已安装 (版本: $COMPOSE_VERSION)${NC}"
|
||
DOCKER_COMPOSE="docker compose"
|
||
return 0
|
||
fi
|
||
|
||
# 检查旧版 docker-compose
|
||
if command -v docker-compose &> /dev/null; then
|
||
COMPOSE_VERSION=$(docker-compose --version | awk '{print $4}' | sed 's/,//')
|
||
echo -e "${GREEN}✓ Docker Compose 已安装 (版本: $COMPOSE_VERSION)${NC}"
|
||
DOCKER_COMPOSE="docker-compose"
|
||
return 0
|
||
fi
|
||
|
||
echo -e "${YELLOW}未检测到 Docker Compose,开始安装...${NC}"
|
||
|
||
# 安装 Docker Compose 插件(推荐方式)
|
||
case $OS in
|
||
ubuntu|debian)
|
||
# 应该已随 Docker 安装
|
||
if ! docker compose version &> /dev/null; then
|
||
sudo apt-get update
|
||
sudo apt-get install -y docker-compose-plugin
|
||
fi
|
||
;;
|
||
|
||
centos|rhel|fedora)
|
||
# 应该已随 Docker 安装
|
||
if ! docker compose version &> /dev/null; then
|
||
sudo yum install -y docker-compose-plugin
|
||
fi
|
||
;;
|
||
|
||
*)
|
||
# 下载独立的 docker-compose
|
||
COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep 'tag_name' | cut -d\" -f4)
|
||
sudo curl -L "https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||
sudo chmod +x /usr/local/bin/docker-compose
|
||
;;
|
||
esac
|
||
|
||
# 再次检查
|
||
if docker compose version &> /dev/null; then
|
||
DOCKER_COMPOSE="docker compose"
|
||
echo -e "${GREEN}✓ Docker Compose 安装完成${NC}"
|
||
elif command -v docker-compose &> /dev/null; then
|
||
DOCKER_COMPOSE="docker-compose"
|
||
echo -e "${GREEN}✓ Docker Compose 安装完成${NC}"
|
||
else
|
||
echo -e "${RED}✗ Docker Compose 安装失败${NC}"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# 配置环境
|
||
configure_environment() {
|
||
echo ""
|
||
echo -e "${BLUE}[3/4]${NC} 配置环境..."
|
||
|
||
# 创建 .env 文件(如果不存在)
|
||
if [ ! -f .env ]; then
|
||
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 | sed 's/addr://')
|
||
fi
|
||
|
||
# 如果自动检测失败,使用默认值
|
||
if [ -z "$SERVER_IP" ]; then
|
||
SERVER_IP="localhost"
|
||
fi
|
||
|
||
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
|
||
|
||
# 生成随机密码
|
||
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
|
||
|
||
# 创建 .env.production 文件
|
||
cat > .env.production << EOF
|
||
# FLNXI素材库 - 生产环境配置
|
||
# 生成时间: $(date)
|
||
|
||
# 服务器配置
|
||
SERVER_IP=$SERVER_IP
|
||
APP_PORT=4320
|
||
|
||
# 数据库配置
|
||
POSTGRES_USER=postgres
|
||
POSTGRES_PASSWORD=$POSTGRES_PASSWORD
|
||
POSTGRES_DB=flnxi
|
||
|
||
# MinIO 配置
|
||
MINIO_ROOT_USER=minioadmin
|
||
MINIO_ROOT_PASSWORD=$MINIO_ROOT_PASSWORD
|
||
MINIO_API_PORT=9000
|
||
MINIO_CONSOLE_PORT=9001
|
||
S3_BUCKET=flnxi-materials
|
||
|
||
# 应用安全配置
|
||
NEXTAUTH_SECRET=$NEXTAUTH_SECRET
|
||
NEXTAUTH_URL=http://$SERVER_IP:4320
|
||
APP_PUBLIC_URL=http://$SERVER_IP:4320
|
||
|
||
# 初始管理员账号
|
||
INIT_ADMIN_EMAIL=$INIT_ADMIN_EMAIL
|
||
INIT_ADMIN_PASSWORD=$INIT_ADMIN_PASSWORD
|
||
EOF
|
||
|
||
echo -e "${GREEN}✓ 环境配置文件已创建${NC}"
|
||
|
||
# 保存重要信息
|
||
cat > 系统信息.txt << EOF
|
||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||
FLNXI素材库 - 系统信息
|
||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||
|
||
安装时间: $(date)
|
||
服务器IP: $SERVER_IP
|
||
|
||
访问地址:
|
||
应用首页: http://$SERVER_IP:4320
|
||
MinIO控制台: http://$SERVER_IP:9001
|
||
|
||
MinIO 管理员账号:
|
||
用户名: minioadmin
|
||
密码: $MINIO_ROOT_PASSWORD
|
||
|
||
数据库信息:
|
||
数据库名: flnxi
|
||
用户名: postgres
|
||
密码: $POSTGRES_PASSWORD
|
||
|
||
初始管理员账号:
|
||
邮箱: $INIT_ADMIN_EMAIL
|
||
密码: $INIT_ADMIN_PASSWORD
|
||
|
||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||
重要提示:请妥善保管此文件!
|
||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||
EOF
|
||
|
||
echo ""
|
||
echo -e "${YELLOW}重要信息已保存到: 系统信息.txt${NC}"
|
||
echo -e "${YELLOW}请妥善保管此文件!${NC}"
|
||
else
|
||
echo -e "${GREEN}✓ 检测到已存在的配置文件${NC}"
|
||
if [ -f .env.production ]; then
|
||
source .env.production
|
||
elif [ -f .env ]; then
|
||
source .env
|
||
fi
|
||
fi
|
||
|
||
# 创建必要的目录
|
||
mkdir -p uploads
|
||
chmod 755 uploads
|
||
echo -e "${GREEN}✓ 数据目录创建完成${NC}"
|
||
}
|
||
|
||
# 安装应用
|
||
install_application() {
|
||
echo ""
|
||
echo -e "${BLUE}[4/4]${NC} 安装应用..."
|
||
|
||
# 停止旧容器(如果存在)
|
||
echo "清理旧容器..."
|
||
$DOCKER_COMPOSE down 2>/dev/null || true
|
||
|
||
# 拉取镜像(从 Harbor)
|
||
echo "拉取 Docker 镜像..."
|
||
echo "这可能需要几分钟时间,请耐心等待..."
|
||
$DOCKER_COMPOSE -f docker-compose.prod.yml pull
|
||
|
||
# 启动服务
|
||
echo "启动服务..."
|
||
$DOCKER_COMPOSE -f docker-compose.prod.yml up -d
|
||
|
||
# 等待服务就绪
|
||
echo "等待服务启动..."
|
||
sleep 15
|
||
|
||
# 初始化数据库
|
||
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 -e "${GREEN}✓ 应用安装完成${NC}"
|
||
}
|
||
|
||
# 显示安装结果
|
||
show_result() {
|
||
source .env
|
||
|
||
echo ""
|
||
echo "========================================"
|
||
echo -e "${GREEN} 安装完成!${NC}"
|
||
echo "========================================"
|
||
echo ""
|
||
echo -e "${BLUE}访问地址:${NC}"
|
||
echo " 应用首页: http://$SERVER_IP:${APP_PORT:-4320}"
|
||
echo " MinIO控制台: http://$SERVER_IP:${MINIO_CONSOLE_PORT:-9001}"
|
||
echo ""
|
||
echo -e "${BLUE}MinIO 管理员账号:${NC}"
|
||
echo " 用户名: minioadmin"
|
||
echo " 密码: (查看 系统信息.txt)"
|
||
echo ""
|
||
echo -e "${BLUE}首次使用:${NC}"
|
||
echo " 1. 访问 http://$SERVER_IP:${APP_PORT:-4320}"
|
||
echo " 2. 使用初始管理员账号登录(查看 系统信息.txt)"
|
||
echo " 3. 登录后可在系统设置中修改密码"
|
||
echo ""
|
||
echo -e "${BLUE}常用命令:${NC}"
|
||
echo " 查看服务: $DOCKER_COMPOSE -f docker-compose.prod.yml ps"
|
||
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 ""
|
||
echo -e "${YELLOW}重要: 系统信息已保存到 系统信息.txt${NC}"
|
||
echo "========================================"
|
||
}
|
||
|
||
# 主流程
|
||
main() {
|
||
detect_os
|
||
install_docker
|
||
install_docker_compose
|
||
configure_environment
|
||
install_application
|
||
show_result
|
||
}
|
||
|
||
# 运行
|
||
main
|
||
|
||
|