主要变更: - 添加完整的项目结构和模块(admin、articles、comments、users、session、oauth2、email、moderation、analytics、jobs 等) - 实现系统初始化 API(/init/status 和 /init/run) - 重写部署流程:迁移到 package.json scripts,删除 Makefile - 优化部署脚本:deploy.sh、healthcheck.sh、backup.sh、restore.sh、verify-env.sh - 更新 README.md:简化文档,整合部署指南 - 优化 AGENTS.md:精简到约 150 行,包含完整的代码规范和命令速查 - 配置 Docker Compose 自动化部署(prisma migrate deploy + seed) - 生成 OAuth2 RSA 密钥对支持 - 添加环境变量验证和数据库备份恢复功能
258 lines
6.7 KiB
Bash
258 lines
6.7 KiB
Bash
#!/bin/bash
|
|
|
|
# ============================================
|
|
# LinkShare Blog - 环境验证脚本
|
|
# ============================================
|
|
# 用途: 在生产环境部署前验证所有必需配置
|
|
# 用法: ./scripts/verify-env.sh
|
|
|
|
set -e # 遇到错误退出
|
|
|
|
# 颜色定义
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# 日志函数
|
|
log_info() {
|
|
echo -e "${GREEN}[INFO]${NC} $1"
|
|
}
|
|
|
|
log_warn() {
|
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
|
}
|
|
|
|
log_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
# 检查项计数
|
|
CHECKS_PASSED=0
|
|
CHECKS_FAILED=0
|
|
CHECKS_WARNING=0
|
|
|
|
# 检查函数
|
|
check_file_exists() {
|
|
local file=$1
|
|
local description=$2
|
|
if [ -f "$file" ]; then
|
|
log_info "$description: 存在 ($file)"
|
|
((CHECKS_PASSED++))
|
|
return 0
|
|
else
|
|
log_error "$description: 缺失 ($file)"
|
|
((CHECKS_FAILED++))
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
check_env_var() {
|
|
local var=$1
|
|
local description=$2
|
|
local required=${3:-true}
|
|
|
|
local value=$(eval echo "\$$var")
|
|
if [ -n "$value" ] && [ "$value" != "your-secret-here" ] && [ "$value" != "change_me" ]; then
|
|
log_info "$description ($var): 已设置"
|
|
((CHECKS_PASSED++))
|
|
return 0
|
|
else
|
|
if [ "$required" = "true" ]; then
|
|
log_error "$description ($var): 未设置或为默认值"
|
|
((CHECKS_FAILED++))
|
|
return 1
|
|
else
|
|
log_warn "$description ($var): 未设置或为默认值 (可选)"
|
|
((CHECKS_WARNING++))
|
|
return 0
|
|
fi
|
|
fi
|
|
}
|
|
|
|
check_command() {
|
|
local cmd=$1
|
|
local description=$2
|
|
if command -v "$cmd" &> /dev/null; then
|
|
local version=$($cmd --version 2>&1 | head -n1)
|
|
log_info "$description: 已安装 ($version)"
|
|
((CHECKS_PASSED++))
|
|
return 0
|
|
else
|
|
log_error "$description: 未安装"
|
|
((CHECKS_FAILED++))
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
check_port() {
|
|
local port=$1
|
|
local description=$2
|
|
if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1; then
|
|
log_info "$description (端口 $port): 已占用"
|
|
((CHECKS_WARNING++))
|
|
return 0
|
|
else
|
|
log_info "$description (端口 $port): 可用"
|
|
((CHECKS_PASSED++))
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
check_docker() {
|
|
if docker info >/dev/null 2>&1; then
|
|
log_info "Docker: 运行中"
|
|
((CHECKS_PASSED++))
|
|
return 0
|
|
else
|
|
log_error "Docker: 未运行或无权限"
|
|
((CHECKS_FAILED++))
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# ============================================
|
|
# 开始检查
|
|
# ============================================
|
|
|
|
echo "=========================================="
|
|
echo "LinkShare Blog 环境验证"
|
|
echo "=========================================="
|
|
echo ""
|
|
|
|
# 1. 检查必需文件
|
|
log_info "检查文件..."
|
|
check_file_exists ".env" "环境变量文件"
|
|
check_file_exists "docker-compose.yml" "Docker Compose 配置"
|
|
check_file_exists "Dockerfile.api" "Dockerfile"
|
|
check_file_exists "ecosystem.config.js" "PM2 配置"
|
|
check_file_exists "package.json" "Package.json"
|
|
echo ""
|
|
|
|
# 2. 检查环境变量
|
|
log_info "检查环境变量..."
|
|
check_env_var "DATABASE_URL" "数据库连接"
|
|
check_env_var "SESSION_COOKIE_SECRET" "Session 密钥"
|
|
check_env_var "AI_API_KEY" "AI API 密钥"
|
|
check_env_var "SMTP_HOST" "SMTP 主机"
|
|
check_env_var "SMTP_PORT" "SMTP 端口"
|
|
check_env_var "SMTP_USER" "SMTP 用户名"
|
|
check_env_var "SMTP_PASS" "SMTP 密码"
|
|
check_env_var "OAUTH2_TOKEN_SIGNING_PRIVATE_KEY" "OAuth2 私钥"
|
|
check_env_var "OAUTH2_TOKEN_SIGNING_PUBLIC_KEY" "OAuth2 公钥"
|
|
echo ""
|
|
|
|
# 3. 检查可选环境变量
|
|
log_info "检查可选环境变量..."
|
|
check_env_var "REDIS_HOST" "Redis 主机" "false"
|
|
check_env_var "THROTTLE_TTL" "限流配置" "false"
|
|
check_env_var "APP_BASE_URL" "应用基础 URL" "false"
|
|
echo ""
|
|
|
|
# 4. 检查命令行工具
|
|
log_info "检查命令行工具..."
|
|
check_command "docker" "Docker CLI"
|
|
check_command "docker-compose" "Docker Compose"
|
|
check_command "node" "Node.js"
|
|
check_command "pnpm" "PNPM"
|
|
check_command "git" "Git"
|
|
echo ""
|
|
|
|
# 5. 检查端口占用
|
|
log_info "检查端口占用..."
|
|
check_port "3001" "API 端口"
|
|
check_port "5432" "PostgreSQL 端口"
|
|
check_port "6379" "Redis 端口"
|
|
echo ""
|
|
|
|
# 6. 检查 Docker 状态
|
|
log_info "检查 Docker 状态..."
|
|
check_docker
|
|
echo ""
|
|
|
|
# 7. 检查 Docker 镜像
|
|
log_info "检查 Docker 镜像..."
|
|
if docker image inspect binglogyblog-api:latest >/dev/null 2>&1; then
|
|
log_info "API 镜像: 存在"
|
|
((CHECKS_PASSED++))
|
|
else
|
|
log_warn "API 镜像: 不存在 (需要运行 docker-compose build)"
|
|
((CHECKS_WARNING++))
|
|
fi
|
|
|
|
if docker image inspect postgres:16-alpine >/dev/null 2>&1; then
|
|
log_info "PostgreSQL 镜像: 存在"
|
|
((CHECKS_PASSED++))
|
|
else
|
|
log_warn "PostgreSQL 镜像: 不存在 (将自动拉取)"
|
|
((CHECKS_WARNING++))
|
|
fi
|
|
|
|
if docker image inspect redis:7-alpine >/dev/null 2>&1; then
|
|
log_info "Redis 镜像: 存在"
|
|
((CHECKS_PASSED++))
|
|
else
|
|
log_warn "Redis 镜像: 不存在 (将自动拉取)"
|
|
((CHECKS_WARNING++))
|
|
fi
|
|
echo ""
|
|
|
|
# 8. 检查磁盘空间
|
|
log_info "检查磁盘空间..."
|
|
AVAILABLE_SPACE=$(df -BG . | tail -1 | awk '{print $4}' | sed 's/G//')
|
|
if [ "$AVAILABLE_SPACE" -ge 10 ]; then
|
|
log_info "可用磁盘空间: ${AVAILABLE_SPACE}GB"
|
|
((CHECKS_PASSED++))
|
|
else
|
|
log_warn "可用磁盘空间: ${AVAILABLE_SPACE}GB (建议至少 10GB)"
|
|
((CHECKS_WARNING++))
|
|
fi
|
|
echo ""
|
|
|
|
# 9. 检查数据库迁移状态
|
|
log_info "检查数据库迁移..."
|
|
if [ -d "prisma/migrations" ]; then
|
|
MIGRATION_COUNT=$(ls -1 prisma/migrations | wc -l)
|
|
log_info "迁移文件数量: $MIGRATION_COUNT"
|
|
((CHECKS_PASSED++))
|
|
else
|
|
log_warn "未找到迁移文件"
|
|
((CHECKS_WARNING++))
|
|
fi
|
|
echo ""
|
|
|
|
# ============================================
|
|
# 输出总结
|
|
# ============================================
|
|
|
|
echo "=========================================="
|
|
echo "验证完成"
|
|
echo "=========================================="
|
|
echo -e "通过: ${GREEN}$CHECKS_PASSED${NC}"
|
|
echo -e "警告: ${YELLOW}$CHECKS_WARNING${NC}"
|
|
echo -e "失败: ${RED}$CHECKS_FAILED${NC}"
|
|
echo ""
|
|
|
|
if [ $CHECKS_FAILED -gt 0 ]; then
|
|
log_error "存在 $CHECKS_FAILED 个问题需要修复"
|
|
echo ""
|
|
echo "建议操作:"
|
|
echo "1. 复制 .env.example 为 .env"
|
|
echo "2. 填写所有必需的配置项"
|
|
echo "3. 生成 OAuth2 RSA 密钥对"
|
|
echo "4. 运行: docker-compose build"
|
|
exit 1
|
|
elif [ $CHECKS_WARNING -gt 0 ]; then
|
|
log_warn "存在 $CHECKS_WARNING 个警告"
|
|
echo "建议继续,但请注意上述警告"
|
|
exit 0
|
|
else
|
|
log_info "所有检查通过!可以开始部署。"
|
|
echo ""
|
|
echo "下一步:"
|
|
echo " docker-compose build # 构建镜像"
|
|
echo " docker-compose up -d # 启动服务"
|
|
echo " curl http://localhost:3001/health # 验证健康状态"
|
|
exit 0
|
|
fi
|