Files
thebet365/docs/docker/build-and-export-images.ps1

145 lines
4.4 KiB
PowerShell
Raw Blame History

# 鏋勫缓 api / player / admin 鐢熶骇闀滃儚骞跺<E9AA9E>鍑轰负 tar
# 鐢ㄦ硶锛堝湪椤圭洰鏍圭洰褰曟垨鏈<E59EA8>洰褰曟墽琛屽潎鍙<E6BD8E>級:
# .\docs\docker\build-and-export-images.ps1
# .\docs\docker\build-and-export-images.ps1 -Service admin
# .\docs\docker\build-and-export-images.ps1 -Tag v1.2.3
# .\docs\docker\build-and-export-images.ps1 -UseCache
# .\docs\docker\build-and-export-images.ps1 -ExportOnly
#
# 四套主题玩家端一键打包(自动切分支,推荐):
# docs\docker\build-and-export-all-themes.bat
param(
[ValidateSet("all", "api", "player", "admin")]
[string]$Service = "all",
[string]$Tag = $env:IMAGE_TAG,
[switch]$UseCache,
[switch]$ExportOnly,
[string]$Output = ""
)
$ErrorActionPreference = "Stop"
$Root = (Resolve-Path (Join-Path $PSScriptRoot "../..")).Path
Set-Location $Root
$ComposeFile = "docker-compose.prod.yml"
$EnvFile = ".env.docker"
$AllServices = @("api", "player", "admin")
function Get-DefaultTag { "latest" }
function Get-DefaultOutput {
param([string]$Svc, [string]$ImageTag)
if ($Svc -eq "all") { return "thebet365-images-$ImageTag.tar" }
return "thebet365-$Svc-$ImageTag.tar"
}
function Assert-ImageTag {
param([string]$Value)
if ($Value -notmatch '^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$') {
throw "闀滃儚 tag 涓嶅悎娉? $Value"
}
}
if (-not (Test-Path $ComposeFile)) {
throw "<EFBFBD>壘鍒?$ComposeFile锛堝綋鍓嶇洰褰? $Root锛?
}
if (-not (Test-Path $EnvFile)) {
if (Test-Path ".env.docker.example") {
Write-Warning "<EFBFBD>壘鍒?.env.docker锛屼娇鐢?.env.docker.example锛堢敓浜ц<EFBFBD>澶嶅埗骞朵慨鏀瑰瘑閽ワ級"
$EnvFile = ".env.docker.example"
} else {
throw "<EFBFBD>壘鍒?.env.docker ?.env.docker.example"
}
}
if ([string]::IsNullOrWhiteSpace($Tag)) {
$Tag = Get-DefaultTag
}
Assert-ImageTag $Tag
$BuildServices = if ($Service -eq "all") { $AllServices } else { @($Service) }
$SaveImages = $BuildServices | ForEach-Object { "thebet365-${_}:${Tag}" }
if ([string]::IsNullOrWhiteSpace($Output)) {
$Output = Get-DefaultOutput -Svc $Service -ImageTag $Tag
}
if (-not $ExportOnly) {
Write-Host "==> 鏋勫缓闀滃儚: $($BuildServices -join ', ') (tag: $Tag)"
$buildArgs = @(
"compose", "-f", $ComposeFile, "--env-file", $EnvFile, "build"
)
if (-not $UseCache) {
$buildArgs += "--no-cache"
}
$buildArgs += $BuildServices
$oldImageTag = $env:IMAGE_TAG
try {
$env:IMAGE_TAG = $Tag
& docker @buildArgs
if ($LASTEXITCODE -ne 0) { throw "docker build 澶辫触锛岄鍑虹爜 $LASTEXITCODE" }
} finally {
$env:IMAGE_TAG = $oldImageTag
}
}
$OutputPath = if ([System.IO.Path]::IsPathRooted($Output)) { $Output } else { Join-Path $Root $Output }
Write-Host "==> 瀵煎嚭闀滃儚 ($Service) -> $OutputPath"
& docker save @SaveImages -o $OutputPath
if ($LASTEXITCODE -ne 0) { throw "docker save 澶辫触锛岄鍑虹爜 $LASTEXITCODE" }
$manifestPath = if ($OutputPath.EndsWith(".tar")) {
$OutputPath.Substring(0, $OutputPath.Length - 4) + ".manifest.txt"
} else {
"$OutputPath.manifest.txt"
}
$gitCommit = "unknown"
$gitDirty = "unknown"
try {
$gitCommit = (& git rev-parse HEAD 2>$null).Trim()
& git diff --quiet
$diffExit = $LASTEXITCODE
& git diff --cached --quiet
$cachedExit = $LASTEXITCODE
$gitDirty = if ($diffExit -eq 0 -and $cachedExit -eq 0) { "false" } else { "true" }
} catch {}
$tarHash = (Get-FileHash -Algorithm SHA256 $OutputPath).Hash.ToLowerInvariant()
$manifestLines = @(
"tag=$Tag"
"service=$Service"
"built_at=$((Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"))"
"git_commit=$gitCommit"
"git_dirty=$gitDirty"
"tar=$([System.IO.Path]::GetFileName($OutputPath))"
"tar_sha256=$tarHash"
)
foreach ($svc in $BuildServices) {
$imageId = (& docker image inspect "thebet365-${svc}:${Tag}" --format "{{.Id}}").Trim()
if ($Service -eq "all") {
$manifestLines += "${svc}_image=thebet365-${svc}:${Tag}"
$manifestLines += "${svc}_image_id=$imageId"
} else {
$manifestLines += "image=thebet365-${svc}:${Tag}"
$manifestLines += "image_id=$imageId"
}
}
$manifestLines | Set-Content -Encoding UTF8 $manifestPath
$sizeMb = [math]::Round((Get-Item $OutputPath).Length / 1MB, 2)
Write-Host "瀹屾垚: $OutputPath (${sizeMb} MB)"
Write-Host "Manifest: $manifestPath"
$recreate = if ($Service -eq "all") { "api player admin" } else { $Service }
Write-Host @"
鏈嶅姟鍣ㄥ<EFBFBD>鍏ュ苟閲嶅缓:
docker load -i $([System.IO.Path]::GetFileName($OutputPath))
docker compose -f docker-compose.prod.yml --env-file .env.docker up -d --force-recreate $recreate
"@