255 lines
7.1 KiB
PowerShell
255 lines
7.1 KiB
PowerShell
|
|
# TYAPI 生产环境部署脚本 (PowerShell版本)
|
|||
|
|
# 使用方法: .\scripts\deploy.ps1 [版本号]
|
|||
|
|
|
|||
|
|
param(
|
|||
|
|
[string]$Version = "latest"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 配置
|
|||
|
|
$REGISTRY_URL = "docker-registry.tianyuanapi.com"
|
|||
|
|
$IMAGE_NAME = "tyapi-server"
|
|||
|
|
$APP_VERSION = $Version
|
|||
|
|
$BUILD_TIME = (Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ")
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
$GIT_COMMIT = git rev-parse --short HEAD 2>$null
|
|||
|
|
if (-not $GIT_COMMIT) { $GIT_COMMIT = "dev" }
|
|||
|
|
}
|
|||
|
|
catch {
|
|||
|
|
$GIT_COMMIT = "dev"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 颜色输出函数
|
|||
|
|
function Write-Info($message) {
|
|||
|
|
Write-Host "[INFO] $message" -ForegroundColor Blue
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Write-Success($message) {
|
|||
|
|
Write-Host "[SUCCESS] $message" -ForegroundColor Green
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Write-Warning($message) {
|
|||
|
|
Write-Host "[WARNING] $message" -ForegroundColor Yellow
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Write-Error($message) {
|
|||
|
|
Write-Host "[ERROR] $message" -ForegroundColor Red
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 检查必要工具
|
|||
|
|
function Test-Requirements {
|
|||
|
|
Write-Info "检查部署环境..."
|
|||
|
|
|
|||
|
|
if (-not (Get-Command docker -ErrorAction SilentlyContinue)) {
|
|||
|
|
Write-Error "Docker 未安装或不在 PATH 中"
|
|||
|
|
exit 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (-not (Get-Command docker-compose -ErrorAction SilentlyContinue)) {
|
|||
|
|
Write-Error "docker-compose 未安装或不在 PATH 中"
|
|||
|
|
exit 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
|
|||
|
|
Write-Warning "Git 未安装,将使用默认提交哈希"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Write-Success "环境检查通过"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 构建 Docker 镜像
|
|||
|
|
function Build-Image {
|
|||
|
|
Write-Info "开始构建 Docker 镜像..."
|
|||
|
|
|
|||
|
|
docker build `
|
|||
|
|
--build-arg VERSION="$APP_VERSION" `
|
|||
|
|
--build-arg COMMIT="$GIT_COMMIT" `
|
|||
|
|
--build-arg BUILD_TIME="$BUILD_TIME" `
|
|||
|
|
-t "$REGISTRY_URL/$IMAGE_NAME`:$APP_VERSION" `
|
|||
|
|
-t "$REGISTRY_URL/$IMAGE_NAME`:latest" `
|
|||
|
|
.
|
|||
|
|
|
|||
|
|
if ($LASTEXITCODE -ne 0) {
|
|||
|
|
Write-Error "Docker 镜像构建失败"
|
|||
|
|
exit 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Write-Success "Docker 镜像构建完成"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 推送镜像到私有仓库
|
|||
|
|
function Push-Image {
|
|||
|
|
Write-Info "推送镜像到私有仓库..."
|
|||
|
|
|
|||
|
|
# 推送版本标签
|
|||
|
|
docker push "$REGISTRY_URL/$IMAGE_NAME`:$APP_VERSION"
|
|||
|
|
if ($LASTEXITCODE -eq 0) {
|
|||
|
|
Write-Success "已推送版本标签: $APP_VERSION"
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
Write-Error "推送版本标签失败"
|
|||
|
|
exit 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 推送latest标签
|
|||
|
|
docker push "$REGISTRY_URL/$IMAGE_NAME`:latest"
|
|||
|
|
if ($LASTEXITCODE -eq 0) {
|
|||
|
|
Write-Success "已推送latest标签"
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
Write-Error "推送latest标签失败"
|
|||
|
|
exit 1
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 准备生产环境配置
|
|||
|
|
function Test-Config {
|
|||
|
|
Write-Info "准备生产环境配置..."
|
|||
|
|
|
|||
|
|
# 检查.env文件是否存在
|
|||
|
|
if (-not (Test-Path ".env")) {
|
|||
|
|
if (Test-Path ".env.production") {
|
|||
|
|
Write-Warning ".env文件不存在,正在复制模板..."
|
|||
|
|
Copy-Item ".env.production" ".env"
|
|||
|
|
Write-Warning "请编辑 .env 文件并设置正确的配置值"
|
|||
|
|
exit 1
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
Write-Error "配置文件 .env 和 .env.production 都不存在"
|
|||
|
|
exit 1
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 验证关键配置
|
|||
|
|
$envContent = Get-Content ".env" -Raw
|
|||
|
|
if (-not ($envContent -match "^DB_PASSWORD=" -and -not ($envContent -match "your_secure_database_password_here"))) {
|
|||
|
|
Write-Error "请在 .env 文件中设置安全的数据库密码"
|
|||
|
|
exit 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (-not ($envContent -match "^JWT_SECRET=" -and -not ($envContent -match "your_super_secure_jwt_secret"))) {
|
|||
|
|
Write-Error "请在 .env 文件中设置安全的JWT密钥"
|
|||
|
|
exit 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Write-Success "配置检查通过"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 部署到生产环境
|
|||
|
|
function Start-Deploy {
|
|||
|
|
Write-Info "开始部署到生产环境..."
|
|||
|
|
|
|||
|
|
# 设置版本环境变量
|
|||
|
|
$env:APP_VERSION = $APP_VERSION
|
|||
|
|
|
|||
|
|
# 停止现有服务
|
|||
|
|
Write-Info "停止现有服务..."
|
|||
|
|
docker-compose -f docker-compose.prod.yml down --remove-orphans
|
|||
|
|
|
|||
|
|
# 清理未使用的镜像
|
|||
|
|
Write-Info "清理未使用的Docker资源..."
|
|||
|
|
docker image prune -f
|
|||
|
|
|
|||
|
|
# 拉取最新镜像
|
|||
|
|
Write-Info "拉取最新镜像..."
|
|||
|
|
docker-compose -f docker-compose.prod.yml pull
|
|||
|
|
|
|||
|
|
# 启动服务
|
|||
|
|
Write-Info "启动生产环境服务..."
|
|||
|
|
docker-compose -f docker-compose.prod.yml up -d
|
|||
|
|
|
|||
|
|
if ($LASTEXITCODE -ne 0) {
|
|||
|
|
Write-Error "服务启动失败"
|
|||
|
|
exit 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 等待服务启动
|
|||
|
|
Write-Info "等待服务启动..."
|
|||
|
|
Start-Sleep -Seconds 30
|
|||
|
|
|
|||
|
|
# 检查服务状态
|
|||
|
|
Write-Info "检查服务状态..."
|
|||
|
|
docker-compose -f docker-compose.prod.yml ps
|
|||
|
|
|
|||
|
|
# 健康检查
|
|||
|
|
Write-Info "执行健康检查..."
|
|||
|
|
$maxAttempts = 10
|
|||
|
|
$attempt = 0
|
|||
|
|
|
|||
|
|
while ($attempt -lt $maxAttempts) {
|
|||
|
|
try {
|
|||
|
|
$response = Invoke-WebRequest -Uri "http://localhost:8080/health" -TimeoutSec 5 -ErrorAction Stop
|
|||
|
|
if ($response.StatusCode -eq 200) {
|
|||
|
|
Write-Success "应用健康检查通过"
|
|||
|
|
break
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch {
|
|||
|
|
$attempt++
|
|||
|
|
Write-Info "健康检查失败,重试 $attempt/$maxAttempts..."
|
|||
|
|
Start-Sleep -Seconds 10
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ($attempt -eq $maxAttempts) {
|
|||
|
|
Write-Error "应用健康检查失败,请检查日志"
|
|||
|
|
docker-compose -f docker-compose.prod.yml logs tyapi-app
|
|||
|
|
exit 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Write-Success "部署完成!"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 显示部署信息
|
|||
|
|
function Show-Info {
|
|||
|
|
Write-Info "部署信息:"
|
|||
|
|
Write-Host " 版本: $APP_VERSION"
|
|||
|
|
Write-Host " 提交: $GIT_COMMIT"
|
|||
|
|
Write-Host " 构建时间: $BUILD_TIME"
|
|||
|
|
Write-Host " 镜像: $REGISTRY_URL/$IMAGE_NAME`:$APP_VERSION"
|
|||
|
|
Write-Host ""
|
|||
|
|
Write-Host "🌐 服务访问地址:"
|
|||
|
|
Write-Host " 📱 API服务: http://localhost:8080"
|
|||
|
|
Write-Host " 📚 API文档: http://localhost:8080/swagger/index.html"
|
|||
|
|
Write-Host " 💚 健康检查: http://localhost:8080/health"
|
|||
|
|
Write-Host ""
|
|||
|
|
Write-Host "📊 监控和追踪:"
|
|||
|
|
Write-Host " 📈 Grafana仪表盘: http://localhost:3000"
|
|||
|
|
Write-Host " 🔍 Prometheus监控: http://localhost:9090"
|
|||
|
|
Write-Host " 🔗 Jaeger链路追踪: http://localhost:16686"
|
|||
|
|
Write-Host ""
|
|||
|
|
Write-Host "🛠 管理工具:"
|
|||
|
|
Write-Host " 🗄️ pgAdmin数据库: http://localhost:5050"
|
|||
|
|
Write-Host " 📦 MinIO对象存储: http://localhost:9000"
|
|||
|
|
Write-Host " 🎛️ MinIO控制台: http://localhost:9001"
|
|||
|
|
Write-Host ""
|
|||
|
|
Write-Host "🔧 管理命令:"
|
|||
|
|
Write-Host " 查看日志: docker-compose -f docker-compose.prod.yml logs -f"
|
|||
|
|
Write-Host " 停止服务: docker-compose -f docker-compose.prod.yml down"
|
|||
|
|
Write-Host " 查看状态: docker-compose -f docker-compose.prod.yml ps"
|
|||
|
|
Write-Host " 重启应用: docker-compose -f docker-compose.prod.yml restart tyapi-app"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 主函数
|
|||
|
|
function Main {
|
|||
|
|
Write-Info "开始 TYAPI 生产环境部署..."
|
|||
|
|
Write-Info "版本: $APP_VERSION"
|
|||
|
|
|
|||
|
|
Test-Requirements
|
|||
|
|
Test-Config
|
|||
|
|
Build-Image
|
|||
|
|
Push-Image
|
|||
|
|
Start-Deploy
|
|||
|
|
Show-Info
|
|||
|
|
|
|||
|
|
Write-Success "🎉 部署成功!"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 运行主函数
|
|||
|
|
try {
|
|||
|
|
Main
|
|||
|
|
}
|
|||
|
|
catch {
|
|||
|
|
Write-Error "部署过程中发生错误: $($_.Exception.Message)"
|
|||
|
|
exit 1
|
|||
|
|
}
|