246 lines
7.1 KiB
Bash
246 lines
7.1 KiB
Bash
#!/bin/bash
|
||
set -e
|
||
|
||
# ============================================================
|
||
# Weibo-HotSign Linux 安装运行脚本
|
||
# 使用方式: chmod +x setup_linux.sh && ./setup_linux.sh
|
||
# ============================================================
|
||
|
||
# ===================== 请在此处填写配置 =====================
|
||
|
||
MYSQL_HOST="127.0.0.1"
|
||
MYSQL_PORT="3306"
|
||
MYSQL_USER="root"
|
||
MYSQL_PASSWORD="" # ← 填写你的 MySQL 密码
|
||
|
||
REDIS_HOST="127.0.0.1"
|
||
REDIS_PORT="6379"
|
||
REDIS_PASSWORD="" # ← 填写你的 Redis 密码(没有密码留空)
|
||
|
||
# JWT 密钥(生产环境请改成随机长字符串)
|
||
JWT_SECRET="change-me-to-a-random-string-in-production"
|
||
|
||
# Cookie 加密密钥(32 字节)
|
||
COOKIE_KEY="change-me-to-a-32byte-key-prod!"
|
||
|
||
# 微信小程序(可选,暂时留空)
|
||
WX_APPID=""
|
||
WX_SECRET=""
|
||
|
||
# 服务端口
|
||
AUTH_PORT=8001
|
||
API_PORT=8000
|
||
FRONTEND_PORT=5000
|
||
|
||
# ===================== 配置结束 =====================
|
||
|
||
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||
DB_NAME="weibo_hotsign"
|
||
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
NC='\033[0m'
|
||
|
||
info() { echo -e "${GREEN}[✓]${NC} $1"; }
|
||
warn() { echo -e "${YELLOW}[!]${NC} $1"; }
|
||
error() { echo -e "${RED}[✗]${NC} $1"; exit 1; }
|
||
|
||
echo ""
|
||
echo "========================================"
|
||
echo " Weibo-HotSign Linux 安装脚本"
|
||
echo "========================================"
|
||
echo ""
|
||
|
||
# ------ 1. 检查系统依赖 ------
|
||
|
||
echo "--- 检查系统依赖 ---"
|
||
|
||
command -v python3 >/dev/null 2>&1 || error "未找到 python3,请先安装 Python 3.8+"
|
||
PYTHON_VER=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
|
||
info "Python $PYTHON_VER"
|
||
|
||
command -v pip3 >/dev/null 2>&1 || command -v pip >/dev/null 2>&1 || error "未找到 pip,请先安装 pip"
|
||
PIP_CMD=$(command -v pip3 || command -v pip)
|
||
info "pip: $PIP_CMD"
|
||
|
||
# ------ 2. 检查 MySQL ------
|
||
|
||
echo ""
|
||
echo "--- 检查 MySQL ---"
|
||
|
||
command -v mysql >/dev/null 2>&1 || error "未找到 mysql 客户端,请先安装 mysql-client"
|
||
|
||
MYSQL_CMD="mysql -h${MYSQL_HOST} -P${MYSQL_PORT} -u${MYSQL_USER}"
|
||
if [ -n "$MYSQL_PASSWORD" ]; then
|
||
MYSQL_CMD="$MYSQL_CMD -p${MYSQL_PASSWORD}"
|
||
fi
|
||
|
||
# 测试连接
|
||
if $MYSQL_CMD -e "SELECT 1" >/dev/null 2>&1; then
|
||
info "MySQL 连接成功 (${MYSQL_HOST}:${MYSQL_PORT})"
|
||
else
|
||
error "MySQL 连接失败,请检查地址、端口和密码"
|
||
fi
|
||
|
||
# ------ 3. 检查 Redis ------
|
||
|
||
echo ""
|
||
echo "--- 检查 Redis ---"
|
||
|
||
command -v redis-cli >/dev/null 2>&1 || error "未找到 redis-cli,请先安装 redis-tools"
|
||
|
||
REDIS_CLI="redis-cli -h ${REDIS_HOST} -p ${REDIS_PORT}"
|
||
if [ -n "$REDIS_PASSWORD" ]; then
|
||
REDIS_CLI="$REDIS_CLI -a ${REDIS_PASSWORD}"
|
||
fi
|
||
|
||
REDIS_PING=$($REDIS_CLI --no-auth-warning PING 2>/dev/null || true)
|
||
if [ "$REDIS_PING" = "PONG" ]; then
|
||
info "Redis 连接成功 (${REDIS_HOST}:${REDIS_PORT})"
|
||
else
|
||
error "Redis 连接失败,请检查地址、端口和密码"
|
||
fi
|
||
|
||
# ------ 4. 初始化 MySQL 数据库 ------
|
||
|
||
echo ""
|
||
echo "--- 初始化 MySQL 数据库 ---"
|
||
|
||
if $MYSQL_CMD -e "USE ${DB_NAME}" >/dev/null 2>&1; then
|
||
# 数据库已存在,检查是否需要加微信字段
|
||
HAS_WX=$($MYSQL_CMD -N -e "SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='${DB_NAME}' AND TABLE_NAME='users' AND COLUMN_NAME='wx_openid'" 2>/dev/null)
|
||
if [ "$HAS_WX" = "0" ]; then
|
||
warn "数据库已存在,正在添加微信登录字段..."
|
||
$MYSQL_CMD ${DB_NAME} -e "
|
||
ALTER TABLE users ADD COLUMN wx_openid VARCHAR(64) UNIQUE AFTER hashed_password;
|
||
ALTER TABLE users ADD COLUMN wx_nickname VARCHAR(100) AFTER wx_openid;
|
||
ALTER TABLE users ADD COLUMN wx_avatar VARCHAR(500) AFTER wx_nickname;
|
||
ALTER TABLE users MODIFY COLUMN email VARCHAR(255) NULL;
|
||
ALTER TABLE users MODIFY COLUMN hashed_password VARCHAR(255) NULL;
|
||
" 2>/dev/null || true
|
||
info "微信字段已添加"
|
||
else
|
||
info "数据库 ${DB_NAME} 已存在且结构完整"
|
||
fi
|
||
else
|
||
info "正在创建数据库和表..."
|
||
$MYSQL_CMD < "${PROJECT_DIR}/init-db.sql"
|
||
info "数据库 ${DB_NAME} 创建完成"
|
||
fi
|
||
|
||
# 创建测试用户(如果 users 表为空)
|
||
USER_COUNT=$($MYSQL_CMD -N -e "SELECT COUNT(*) FROM ${DB_NAME}.users" 2>/dev/null)
|
||
if [ "$USER_COUNT" = "0" ]; then
|
||
info "正在创建测试用户..."
|
||
# 用 python 生成 bcrypt 密码
|
||
HASHED_PW=$(python3 -c "import bcrypt; print(bcrypt.hashpw(b'Admin123!', bcrypt.gensalt(12)).decode())")
|
||
USER_ID=$(python3 -c "import uuid; print(str(uuid.uuid4()))")
|
||
$MYSQL_CMD ${DB_NAME} -e "
|
||
INSERT INTO users (id, username, email, hashed_password, is_active)
|
||
VALUES ('${USER_ID}', 'admin', 'admin@example.com', '${HASHED_PW}', 1);
|
||
"
|
||
info "测试用户: admin / Admin123!"
|
||
fi
|
||
|
||
# ------ 5. 构建 Redis URL ------
|
||
|
||
if [ -n "$REDIS_PASSWORD" ]; then
|
||
REDIS_URL="redis://:${REDIS_PASSWORD}@${REDIS_HOST}:${REDIS_PORT}/0"
|
||
else
|
||
REDIS_URL="redis://${REDIS_HOST}:${REDIS_PORT}/0"
|
||
fi
|
||
|
||
# ------ 6. 构建 MySQL URL ------
|
||
|
||
if [ -n "$MYSQL_PASSWORD" ]; then
|
||
MYSQL_URL="mysql+aiomysql://${MYSQL_USER}:${MYSQL_PASSWORD}@${MYSQL_HOST}:${MYSQL_PORT}/${DB_NAME}?charset=utf8mb4"
|
||
else
|
||
MYSQL_URL="mysql+aiomysql://${MYSQL_USER}@${MYSQL_HOST}:${MYSQL_PORT}/${DB_NAME}?charset=utf8mb4"
|
||
fi
|
||
|
||
# ------ 7. 生成 .env 文件 ------
|
||
|
||
echo ""
|
||
echo "--- 生成配置文件 ---"
|
||
|
||
cat > "${PROJECT_DIR}/backend/.env" << EOF
|
||
# ===== 由 setup_linux.sh 自动生成 =====
|
||
|
||
# MySQL
|
||
DATABASE_URL=${MYSQL_URL}
|
||
|
||
# Redis
|
||
USE_REDIS=true
|
||
REDIS_URL=${REDIS_URL}
|
||
|
||
# JWT
|
||
JWT_SECRET_KEY=${JWT_SECRET}
|
||
JWT_ALGORITHM=HS256
|
||
JWT_EXPIRATION_HOURS=24
|
||
|
||
# Cookie 加密
|
||
COOKIE_ENCRYPTION_KEY=${COOKIE_KEY}
|
||
|
||
# 微信小程序
|
||
WX_APPID=${WX_APPID}
|
||
WX_SECRET=${WX_SECRET}
|
||
|
||
# 环境
|
||
ENVIRONMENT=production
|
||
EOF
|
||
info "backend/.env 已生成"
|
||
|
||
cat > "${PROJECT_DIR}/frontend/.env" << EOF
|
||
# ===== 由 setup_linux.sh 自动生成 =====
|
||
|
||
FLASK_ENV=production
|
||
FLASK_DEBUG=False
|
||
SECRET_KEY=$(python3 -c "import secrets; print(secrets.token_hex(32))")
|
||
|
||
API_BASE_URL=http://127.0.0.1:${API_PORT}
|
||
AUTH_BASE_URL=http://127.0.0.1:${AUTH_PORT}
|
||
|
||
SESSION_TYPE=filesystem
|
||
EOF
|
||
info "frontend/.env 已生成"
|
||
|
||
# ------ 8. 创建虚拟环境并安装依赖 ------
|
||
|
||
echo ""
|
||
echo "--- 安装 Python 依赖 ---"
|
||
|
||
# 后端
|
||
if [ ! -d "${PROJECT_DIR}/backend/venv" ]; then
|
||
info "创建后端虚拟环境..."
|
||
python3 -m venv "${PROJECT_DIR}/backend/venv"
|
||
fi
|
||
source "${PROJECT_DIR}/backend/venv/bin/activate"
|
||
pip install -q --upgrade pip
|
||
pip install -q -r "${PROJECT_DIR}/backend/requirements.txt"
|
||
deactivate
|
||
info "后端依赖安装完成"
|
||
|
||
# 前端
|
||
if [ ! -d "${PROJECT_DIR}/frontend/venv" ]; then
|
||
info "创建前端虚拟环境..."
|
||
python3 -m venv "${PROJECT_DIR}/frontend/venv"
|
||
fi
|
||
source "${PROJECT_DIR}/frontend/venv/bin/activate"
|
||
pip install -q --upgrade pip
|
||
pip install -q -r "${PROJECT_DIR}/frontend/requirements.txt"
|
||
deactivate
|
||
info "前端依赖安装完成"
|
||
|
||
echo ""
|
||
echo "========================================"
|
||
echo " 安装完成!"
|
||
echo "========================================"
|
||
echo ""
|
||
echo " MySQL: ${MYSQL_HOST}:${MYSQL_PORT} / ${DB_NAME}"
|
||
echo " Redis: ${REDIS_HOST}:${REDIS_PORT}"
|
||
echo ""
|
||
echo " 启动服务: ./start_linux.sh"
|
||
echo " 停止服务: ./stop_linux.sh"
|
||
echo ""
|