# 构建 api / player / admin 生产镜像并导出为 tar # 用法(在项目根目录或本目录执行均可): # .\docs\docker\build-and-export-images.ps1 # .\build-and-export-images.ps1 -UseCache # .\build-and-export-images.ps1 -ExportOnly param( [switch]$UseCache, [switch]$ExportOnly, [string]$Output = "thebet365-images.tar" ) $ErrorActionPreference = "Stop" $Root = (Resolve-Path (Join-Path $PSScriptRoot "../..")).Path Set-Location $Root $ComposeFile = "docker-compose.prod.yml" $EnvFile = ".env.docker" $Services = @("api", "player", "admin") if (-not (Test-Path $ComposeFile)) { throw "未找到 $ComposeFile(当前目录: $Root)" } if (-not (Test-Path $EnvFile)) { if (Test-Path ".env.docker.example") { Write-Warning "未找到 .env.docker,使用 .env.docker.example(生产请复制并修改密钥)" $EnvFile = ".env.docker.example" } else { throw "未找到 .env.docker 或 .env.docker.example" } } if (-not $ExportOnly) { Write-Host "==> 构建镜像: $($Services -join ', ')" $buildArgs = @( "compose", "-f", $ComposeFile, "--env-file", $EnvFile, "build" ) if (-not $UseCache) { $buildArgs += "--no-cache" } $buildArgs += $Services & docker @buildArgs if ($LASTEXITCODE -ne 0) { throw "docker build 失败,退出码 $LASTEXITCODE" } } $OutputPath = if ([System.IO.Path]::IsPathRooted($Output)) { $Output } else { Join-Path $Root $Output } Write-Host "==> 导出镜像 -> $OutputPath" & docker save ` thebet365-api:latest ` thebet365-player:latest ` thebet365-admin:latest ` -o $OutputPath if ($LASTEXITCODE -ne 0) { throw "docker save 失败,退出码 $LASTEXITCODE" } $sizeMb = [math]::Round((Get-Item $OutputPath).Length / 1MB, 2) Write-Host "完成: $OutputPath (${sizeMb} MB)" Write-Host @" 服务器加载: docker load -i thebet365-images.tar docker compose -f docker-compose.prod.yml --env-file .env.docker up -d "@