优化 Docker 镜像打包脚本并修复管理端赛事操作列布局
- 打包脚本默认 tag 改为 latest,支持 --service 单服务构建/导出 - 新增 api/player/admin 三个独立 bat,更新文档与 manifest - 联赛赛事面板操作列加宽、横向滚动与按钮换行,避免操作按钮被裁切 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
8
docs/docker/build-and-export-admin.bat
Normal file
8
docs/docker/build-and-export-admin.bat
Normal file
@@ -0,0 +1,8 @@
|
||||
@echo off
|
||||
REM Build and export thebet365-admin image only (tag default: latest).
|
||||
REM Requires VITE_PLAYER_URL in .env.docker for correct invite links.
|
||||
REM Usage:
|
||||
REM docs\docker\build-and-export-admin.bat
|
||||
REM docs\docker\build-and-export-admin.bat --use-cache
|
||||
REM docs\docker\build-and-export-admin.bat --export-only
|
||||
"%~dp0build-and-export-images.bat" --service admin %*
|
||||
7
docs/docker/build-and-export-api.bat
Normal file
7
docs/docker/build-and-export-api.bat
Normal file
@@ -0,0 +1,7 @@
|
||||
@echo off
|
||||
REM Build and export thebet365-api image only (tag default: latest).
|
||||
REM Usage:
|
||||
REM docs\docker\build-and-export-api.bat
|
||||
REM docs\docker\build-and-export-api.bat --use-cache
|
||||
REM docs\docker\build-and-export-api.bat --export-only
|
||||
"%~dp0build-and-export-images.bat" --service api %*
|
||||
@@ -4,6 +4,7 @@ setlocal EnableDelayedExpansion
|
||||
REM Build api/player/admin images and export as tar (Windows CMD).
|
||||
REM Usage:
|
||||
REM docs\docker\build-and-export-images.bat
|
||||
REM docs\docker\build-and-export-images.bat --service admin
|
||||
REM docs\docker\build-and-export-images.bat --tag v1.2.3
|
||||
REM docs\docker\build-and-export-images.bat --use-cache
|
||||
REM docs\docker\build-and-export-images.bat --export-only
|
||||
@@ -15,11 +16,13 @@ set "ENV_FILE=.env.docker"
|
||||
set "OUTPUT="
|
||||
set "NO_CACHE=1"
|
||||
set "EXPORT_ONLY=0"
|
||||
set "SERVICE=all"
|
||||
if defined IMAGE_TAG (set "TAG=%IMAGE_TAG%") else (set "TAG=")
|
||||
|
||||
:parse_args
|
||||
if "%~1"=="" goto args_done
|
||||
if /i "%~1"=="--tag" goto parse_tag
|
||||
if /i "%~1"=="--service" goto parse_service
|
||||
if /i "%~1"=="--use-cache" set "NO_CACHE=0" & shift & goto parse_args
|
||||
if /i "%~1"=="--export-only" set "EXPORT_ONLY=1" & shift & goto parse_args
|
||||
if /i "%~1"=="--output" goto parse_output
|
||||
@@ -39,6 +42,16 @@ shift
|
||||
shift
|
||||
goto parse_args
|
||||
|
||||
:parse_service
|
||||
if "%~2"=="" (
|
||||
echo ERROR: missing value for --service
|
||||
exit /b 1
|
||||
)
|
||||
set "SERVICE=%~2"
|
||||
shift
|
||||
shift
|
||||
goto parse_args
|
||||
|
||||
:parse_output
|
||||
if "%~2"=="" (
|
||||
echo ERROR: missing value for --output
|
||||
@@ -53,12 +66,18 @@ goto parse_args
|
||||
echo.
|
||||
echo Usage: docs\docker\build-and-export-images.bat [options]
|
||||
echo.
|
||||
echo --tag TAG Image tag (default: git short commit)
|
||||
echo --service SVC api ^| player ^| admin ^| all (default: all)
|
||||
echo --tag TAG Image tag (default: latest)
|
||||
echo --use-cache Use Docker build cache
|
||||
echo --export-only Skip build, export existing images only
|
||||
echo --output PATH Output tar path
|
||||
echo -h, --help Show help
|
||||
echo.
|
||||
echo Examples:
|
||||
echo docs\docker\build-and-export-images.bat --service admin
|
||||
echo docs\docker\build-and-export-admin.bat
|
||||
echo docs\docker\build-and-export-admin.bat --export-only
|
||||
echo.
|
||||
exit /b 0
|
||||
|
||||
:args_done
|
||||
@@ -77,6 +96,9 @@ if not exist "%ENV_FILE%" (
|
||||
)
|
||||
)
|
||||
|
||||
call :validate_service
|
||||
if errorlevel 1 exit /b 1
|
||||
|
||||
if not defined TAG call :default_tag
|
||||
if not defined TAG (
|
||||
echo ERROR: unable to determine image tag
|
||||
@@ -86,7 +108,7 @@ if not defined TAG (
|
||||
call :validate_tag
|
||||
if errorlevel 1 exit /b 1
|
||||
|
||||
if not defined OUTPUT set "OUTPUT=thebet365-images-%TAG%.tar"
|
||||
if not defined OUTPUT call :default_output
|
||||
|
||||
set "OUTPUT_PATH=%OUTPUT%"
|
||||
echo %OUTPUT_PATH%| findstr /r "^[A-Za-z]:\\" >nul
|
||||
@@ -102,14 +124,22 @@ if "%EXPORT_ONLY%"=="0" goto do_build
|
||||
goto do_export
|
||||
|
||||
:do_build
|
||||
echo ==^> Building api, player, admin (tag: %TAG%)
|
||||
echo ==^> Building %SERVICE% (tag: %TAG%)
|
||||
set "IMAGE_TAG=%TAG%"
|
||||
if "%NO_CACHE%"=="1" goto build_no_cache
|
||||
docker compose -f "%COMPOSE_FILE%" --env-file "%ENV_FILE%" build api player admin
|
||||
if /i "%SERVICE%"=="all" (
|
||||
docker compose -f "%COMPOSE_FILE%" --env-file "%ENV_FILE%" build api player admin
|
||||
) else (
|
||||
docker compose -f "%COMPOSE_FILE%" --env-file "%ENV_FILE%" build %SERVICE%
|
||||
)
|
||||
goto build_done
|
||||
|
||||
:build_no_cache
|
||||
docker compose -f "%COMPOSE_FILE%" --env-file "%ENV_FILE%" build --no-cache api player admin
|
||||
if /i "%SERVICE%"=="all" (
|
||||
docker compose -f "%COMPOSE_FILE%" --env-file "%ENV_FILE%" build --no-cache api player admin
|
||||
) else (
|
||||
docker compose -f "%COMPOSE_FILE%" --env-file "%ENV_FILE%" build --no-cache %SERVICE%
|
||||
)
|
||||
|
||||
:build_done
|
||||
if errorlevel 1 (
|
||||
@@ -118,8 +148,12 @@ if errorlevel 1 (
|
||||
)
|
||||
|
||||
:do_export
|
||||
echo ==^> Exporting images to %OUTPUT_PATH%
|
||||
docker save thebet365-api:%TAG% thebet365-player:%TAG% thebet365-admin:%TAG% -o "%OUTPUT_PATH%"
|
||||
echo ==^> Exporting %SERVICE% to %OUTPUT_PATH%
|
||||
if /i "%SERVICE%"=="all" (
|
||||
docker save thebet365-api:%TAG% thebet365-player:%TAG% thebet365-admin:%TAG% -o "%OUTPUT_PATH%"
|
||||
) else (
|
||||
docker save thebet365-%SERVICE%:%TAG% -o "%OUTPUT_PATH%"
|
||||
)
|
||||
if errorlevel 1 (
|
||||
echo ERROR: docker save failed
|
||||
exit /b 1
|
||||
@@ -141,38 +175,61 @@ for %%F in ("%OUTPUT_PATH%") do set /a SIZE_MB=%%~zF/1048576
|
||||
|
||||
> "%MANIFEST_PATH%" (
|
||||
echo tag=%TAG%
|
||||
echo service=%SERVICE%
|
||||
echo built_at=!BUILT_AT!
|
||||
echo git_commit=!GIT_COMMIT!
|
||||
echo git_dirty=!GIT_DIRTY!
|
||||
echo tar=!TAR_NAME!
|
||||
echo tar_sha256=!TAR_SHA256!
|
||||
echo api_image=thebet365-api:%TAG%
|
||||
echo api_image_id=!API_IMAGE_ID!
|
||||
echo player_image=thebet365-player:%TAG%
|
||||
echo player_image_id=!PLAYER_IMAGE_ID!
|
||||
echo admin_image=thebet365-admin:%TAG%
|
||||
echo admin_image_id=!ADMIN_IMAGE_ID!
|
||||
if /i not "!SERVICE!"=="all" (
|
||||
echo image=thebet365-!SERVICE!:%TAG%
|
||||
echo image_id=!SVC_IMAGE_ID!
|
||||
) else (
|
||||
echo api_image=thebet365-api:%TAG%
|
||||
echo api_image_id=!API_IMAGE_ID!
|
||||
echo player_image=thebet365-player:%TAG%
|
||||
echo player_image_id=!PLAYER_IMAGE_ID!
|
||||
echo admin_image=thebet365-admin:%TAG%
|
||||
echo admin_image_id=!ADMIN_IMAGE_ID!
|
||||
)
|
||||
)
|
||||
|
||||
echo Done: %OUTPUT_PATH% ^(!SIZE_MB! MB^)
|
||||
echo Manifest: %MANIFEST_PATH%
|
||||
echo.
|
||||
echo Server first deploy:
|
||||
echo ./scripts/deploy-first.sh --images !TAR_NAME! --tag %TAG%
|
||||
echo.
|
||||
echo Server update:
|
||||
echo ./scripts/deploy-update.sh --images !TAR_NAME! --tag %TAG%
|
||||
echo Server load and recreate:
|
||||
if /i "%SERVICE%"=="all" (
|
||||
echo docker load -i !TAR_NAME!
|
||||
echo docker compose -f docker-compose.prod.yml --env-file .env.docker up -d --force-recreate api player admin
|
||||
) else (
|
||||
echo docker load -i !TAR_NAME!
|
||||
echo docker compose -f docker-compose.prod.yml --env-file .env.docker up -d --force-recreate %SERVICE%
|
||||
)
|
||||
echo.
|
||||
|
||||
endlocal
|
||||
exit /b 0
|
||||
|
||||
:default_tag
|
||||
for /f "delims=" %%T in ('git rev-parse --short HEAD 2^>nul') do set "TAG=%%T"
|
||||
if defined TAG exit /b 0
|
||||
for /f "delims=" %%T in ('powershell -NoProfile -Command "Get-Date -Format yyyyMMdd-HHmmss"') do set "TAG=%%T"
|
||||
set "TAG=latest"
|
||||
exit /b 0
|
||||
|
||||
:default_output
|
||||
if /i "%SERVICE%"=="all" (
|
||||
set "OUTPUT=thebet365-images-%TAG%.tar"
|
||||
) else (
|
||||
set "OUTPUT=thebet365-%SERVICE%-%TAG%.tar"
|
||||
)
|
||||
exit /b 0
|
||||
|
||||
:validate_service
|
||||
if /i "%SERVICE%"=="all" exit /b 0
|
||||
if /i "%SERVICE%"=="api" exit /b 0
|
||||
if /i "%SERVICE%"=="player" exit /b 0
|
||||
if /i "%SERVICE%"=="admin" exit /b 0
|
||||
echo ERROR: invalid --service: %SERVICE% (use api, player, admin, or all)
|
||||
exit /b 1
|
||||
|
||||
:validate_tag
|
||||
echo %TAG%| findstr /r "^[A-Za-z0-9_][A-Za-z0-9_.-]*$" >nul
|
||||
if errorlevel 1 (
|
||||
@@ -208,7 +265,11 @@ exit /b 0
|
||||
set "API_IMAGE_ID="
|
||||
set "PLAYER_IMAGE_ID="
|
||||
set "ADMIN_IMAGE_ID="
|
||||
set "SVC_IMAGE_ID="
|
||||
for /f "delims=" %%I in ('docker image inspect thebet365-api:%TAG% --format "{{.Id}}" 2^>nul') do set "API_IMAGE_ID=%%I"
|
||||
for /f "delims=" %%I in ('docker image inspect thebet365-player:%TAG% --format "{{.Id}}" 2^>nul') do set "PLAYER_IMAGE_ID=%%I"
|
||||
for /f "delims=" %%I in ('docker image inspect thebet365-admin:%TAG% --format "{{.Id}}" 2^>nul') do set "ADMIN_IMAGE_ID=%%I"
|
||||
if /i not "%SERVICE%"=="all" (
|
||||
for /f "delims=" %%I in ('docker image inspect thebet365-%SERVICE%:%TAG% --format "{{.Id}}" 2^>nul') do set "SVC_IMAGE_ID=%%I"
|
||||
)
|
||||
exit /b 0
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
# 构建 api / player / admin 生产镜像并导出为 tar
|
||||
# 用法(在项目根目录或本目录执行均可):
|
||||
# .\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
|
||||
# .\build-and-export-images.ps1 -UseCache
|
||||
# .\build-and-export-images.ps1 -ExportOnly
|
||||
# .\docs\docker\build-and-export-images.ps1 -UseCache
|
||||
# .\docs\docker\build-and-export-images.ps1 -ExportOnly
|
||||
|
||||
param(
|
||||
[ValidateSet("all", "api", "player", "admin")]
|
||||
[string]$Service = "all",
|
||||
[string]$Tag = $env:IMAGE_TAG,
|
||||
[switch]$UseCache,
|
||||
[switch]$ExportOnly,
|
||||
@@ -18,14 +21,14 @@ Set-Location $Root
|
||||
|
||||
$ComposeFile = "docker-compose.prod.yml"
|
||||
$EnvFile = ".env.docker"
|
||||
$Services = @("api", "player", "admin")
|
||||
$AllServices = @("api", "player", "admin")
|
||||
|
||||
function Get-DefaultTag {
|
||||
try {
|
||||
$short = (& git rev-parse --short HEAD 2>$null).Trim()
|
||||
if ($short) { return $short }
|
||||
} catch {}
|
||||
return Get-Date -Format "yyyyMMdd-HHmmss"
|
||||
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 {
|
||||
@@ -52,19 +55,23 @@ 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 = "thebet365-images-$Tag.tar"
|
||||
$Output = Get-DefaultOutput -Svc $Service -ImageTag $Tag
|
||||
}
|
||||
|
||||
if (-not $ExportOnly) {
|
||||
Write-Host "==> 构建镜像: $($Services -join ', ') (tag: $Tag)"
|
||||
Write-Host "==> 构建镜像: $($BuildServices -join ', ') (tag: $Tag)"
|
||||
$buildArgs = @(
|
||||
"compose", "-f", $ComposeFile, "--env-file", $EnvFile, "build"
|
||||
)
|
||||
if (-not $UseCache) {
|
||||
$buildArgs += "--no-cache"
|
||||
}
|
||||
$buildArgs += $Services
|
||||
$buildArgs += $BuildServices
|
||||
$oldImageTag = $env:IMAGE_TAG
|
||||
try {
|
||||
$env:IMAGE_TAG = $Tag
|
||||
@@ -77,12 +84,8 @@ if (-not $ExportOnly) {
|
||||
|
||||
$OutputPath = if ([System.IO.Path]::IsPathRooted($Output)) { $Output } else { Join-Path $Root $Output }
|
||||
|
||||
Write-Host "==> 导出镜像 -> $OutputPath"
|
||||
& docker save `
|
||||
"thebet365-api:${Tag}" `
|
||||
"thebet365-player:${Tag}" `
|
||||
"thebet365-admin:${Tag}" `
|
||||
-o $OutputPath
|
||||
Write-Host "==> 导出镜像 ($Service) -> $OutputPath"
|
||||
& docker save @SaveImages -o $OutputPath
|
||||
if ($LASTEXITCODE -ne 0) { throw "docker save 失败,退出码 $LASTEXITCODE" }
|
||||
|
||||
$manifestPath = if ($OutputPath.EndsWith(".tar")) {
|
||||
@@ -103,34 +106,35 @@ try {
|
||||
} catch {}
|
||||
|
||||
$tarHash = (Get-FileHash -Algorithm SHA256 $OutputPath).Hash.ToLowerInvariant()
|
||||
$apiImageId = (& docker image inspect "thebet365-api:${Tag}" --format "{{.Id}}").Trim()
|
||||
$playerImageId = (& docker image inspect "thebet365-player:${Tag}" --format "{{.Id}}").Trim()
|
||||
$adminImageId = (& docker image inspect "thebet365-admin:${Tag}" --format "{{.Id}}").Trim()
|
||||
|
||||
@(
|
||||
$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"
|
||||
"api_image=thebet365-api:${Tag}"
|
||||
"api_image_id=$apiImageId"
|
||||
"player_image=thebet365-player:${Tag}"
|
||||
"player_image_id=$playerImageId"
|
||||
"admin_image=thebet365-admin:${Tag}"
|
||||
"admin_image_id=$adminImageId"
|
||||
) | Set-Content -Encoding UTF8 $manifestPath
|
||||
)
|
||||
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 @"
|
||||
|
||||
服务器首次部署:
|
||||
./scripts/deploy-first.sh --images $([System.IO.Path]::GetFileName($OutputPath)) --tag $Tag
|
||||
|
||||
服务器后续更新:
|
||||
./scripts/deploy-update.sh --images $([System.IO.Path]::GetFileName($OutputPath)) --tag $Tag
|
||||
服务器导入并重建:
|
||||
docker load -i $([System.IO.Path]::GetFileName($OutputPath))
|
||||
docker compose -f docker-compose.prod.yml --env-file .env.docker up -d --force-recreate $recreate
|
||||
"@
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# 构建 api / player / admin 生产镜像并导出为 tar
|
||||
# 用法:
|
||||
# ./docs/docker/build-and-export-images.sh
|
||||
# ./docs/docker/build-and-export-images.sh --service admin
|
||||
# ./docs/docker/build-and-export-images.sh --tag v1.2.3
|
||||
# ./build-and-export-images.sh --use-cache
|
||||
# ./build-and-export-images.sh --export-only
|
||||
@@ -15,16 +16,19 @@ cd "$ROOT"
|
||||
COMPOSE_FILE="docker-compose.prod.yml"
|
||||
ENV_FILE=".env.docker"
|
||||
OUTPUT=""
|
||||
SERVICES=(api player admin)
|
||||
SERVICE="all"
|
||||
NO_CACHE=1
|
||||
EXPORT_ONLY=0
|
||||
TAG="${IMAGE_TAG:-}"
|
||||
|
||||
default_tag() {
|
||||
if command -v git >/dev/null 2>&1 && git rev-parse --short HEAD >/dev/null 2>&1; then
|
||||
git rev-parse --short HEAD
|
||||
default_tag() { echo "latest"; }
|
||||
|
||||
default_output() {
|
||||
local svc="$1" image_tag="$2"
|
||||
if [[ "$svc" == "all" ]]; then
|
||||
echo "thebet365-images-${image_tag}.tar"
|
||||
else
|
||||
date +%Y%m%d-%H%M%S
|
||||
echo "thebet365-${svc}-${image_tag}.tar"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -33,16 +37,28 @@ validate_tag() {
|
||||
{ echo "错误: 镜像 tag 不合法: $1" >&2; exit 1; }
|
||||
}
|
||||
|
||||
validate_service() {
|
||||
case "$1" in
|
||||
all|api|player|admin) ;;
|
||||
*) echo "错误: --service 无效: $1(可选 api / player / admin / all)" >&2; exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
用法: docs/docker/build-and-export-images.sh [选项]
|
||||
|
||||
选项:
|
||||
--tag TAG 镜像 tag(默认当前 git 短提交号;非 git 目录则用时间戳)
|
||||
--service SVC api | player | admin | all(默认 all)
|
||||
--tag TAG 镜像 tag(默认 latest)
|
||||
--use-cache 构建时使用 Docker 缓存(默认 --no-cache)
|
||||
--export-only 跳过构建,仅导出已有指定 tag 镜像
|
||||
--output PATH 导出文件路径(默认项目根目录 thebet365-images-<tag>.tar)
|
||||
--output PATH 导出文件路径
|
||||
-h, --help 显示帮助
|
||||
|
||||
示例:
|
||||
./docs/docker/build-and-export-images.sh --service admin
|
||||
./docs/docker/build-and-export-images.sh --service admin --export-only
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -52,6 +68,10 @@ while [[ $# -gt 0 ]]; do
|
||||
TAG="${2:?缺少 --tag 参数值}"
|
||||
shift 2
|
||||
;;
|
||||
--service)
|
||||
SERVICE="${2:?缺少 --service 参数值}"
|
||||
shift 2
|
||||
;;
|
||||
--use-cache) NO_CACHE=0; shift ;;
|
||||
--export-only) EXPORT_ONLY=1; shift ;;
|
||||
--output)
|
||||
@@ -78,17 +98,24 @@ if [[ ! -f "$ENV_FILE" ]]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
validate_service "$SERVICE"
|
||||
TAG="${TAG:-$(default_tag)}"
|
||||
validate_tag "$TAG"
|
||||
OUTPUT="${OUTPUT:-thebet365-images-$TAG.tar}"
|
||||
OUTPUT="${OUTPUT:-$(default_output "$SERVICE" "$TAG")}"
|
||||
|
||||
if [[ "$SERVICE" == "all" ]]; then
|
||||
BUILD_SERVICES=(api player admin)
|
||||
else
|
||||
BUILD_SERVICES=("$SERVICE")
|
||||
fi
|
||||
|
||||
if [[ "$EXPORT_ONLY" -eq 0 ]]; then
|
||||
echo "==> 构建镜像: ${SERVICES[*]} (tag: $TAG)"
|
||||
echo "==> 构建镜像: ${BUILD_SERVICES[*]} (tag: $TAG)"
|
||||
BUILD_ARGS=(compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" build)
|
||||
if [[ "$NO_CACHE" -eq 1 ]]; then
|
||||
BUILD_ARGS+=(--no-cache)
|
||||
fi
|
||||
BUILD_ARGS+=("${SERVICES[@]}")
|
||||
BUILD_ARGS+=("${BUILD_SERVICES[@]}")
|
||||
IMAGE_TAG="$TAG" docker "${BUILD_ARGS[@]}"
|
||||
fi
|
||||
|
||||
@@ -97,12 +124,13 @@ if [[ "$OUTPUT" != /* ]] && [[ "$OUTPUT" != [A-Za-z]:* ]]; then
|
||||
OUTPUT_PATH="$ROOT/$OUTPUT"
|
||||
fi
|
||||
|
||||
echo "==> 导出镜像 -> $OUTPUT_PATH"
|
||||
docker save \
|
||||
"thebet365-api:$TAG" \
|
||||
"thebet365-player:$TAG" \
|
||||
"thebet365-admin:$TAG" \
|
||||
-o "$OUTPUT_PATH"
|
||||
SAVE_ARGS=()
|
||||
for svc in "${BUILD_SERVICES[@]}"; do
|
||||
SAVE_ARGS+=("thebet365-${svc}:$TAG")
|
||||
done
|
||||
|
||||
echo "==> 导出镜像 ($SERVICE) -> $OUTPUT_PATH"
|
||||
docker save "${SAVE_ARGS[@]}" -o "$OUTPUT_PATH"
|
||||
|
||||
MANIFEST_PATH="${OUTPUT_PATH%.tar}.manifest.txt"
|
||||
BUILT_AT="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
@@ -126,17 +154,21 @@ fi
|
||||
|
||||
{
|
||||
echo "tag=$TAG"
|
||||
echo "service=$SERVICE"
|
||||
echo "built_at=$BUILT_AT"
|
||||
echo "git_commit=$GIT_COMMIT"
|
||||
echo "git_dirty=$GIT_DIRTY"
|
||||
echo "tar=$(basename "$OUTPUT_PATH")"
|
||||
echo "tar_sha256=$CHECKSUM"
|
||||
echo "api_image=thebet365-api:$TAG"
|
||||
echo "api_image_id=$(docker image inspect "thebet365-api:$TAG" --format '{{.Id}}')"
|
||||
echo "player_image=thebet365-player:$TAG"
|
||||
echo "player_image_id=$(docker image inspect "thebet365-player:$TAG" --format '{{.Id}}')"
|
||||
echo "admin_image=thebet365-admin:$TAG"
|
||||
echo "admin_image_id=$(docker image inspect "thebet365-admin:$TAG" --format '{{.Id}}')"
|
||||
for svc in "${BUILD_SERVICES[@]}"; do
|
||||
if [[ "$SERVICE" == "all" ]]; then
|
||||
echo "${svc}_image=thebet365-${svc}:$TAG"
|
||||
echo "${svc}_image_id=$(docker image inspect "thebet365-${svc}:$TAG" --format '{{.Id}}')"
|
||||
else
|
||||
echo "image=thebet365-${svc}:$TAG"
|
||||
echo "image_id=$(docker image inspect "thebet365-${svc}:$TAG" --format '{{.Id}}')"
|
||||
fi
|
||||
done
|
||||
} > "$MANIFEST_PATH"
|
||||
|
||||
if command -v du >/dev/null 2>&1; then
|
||||
@@ -147,11 +179,14 @@ else
|
||||
fi
|
||||
echo "Manifest: $MANIFEST_PATH"
|
||||
|
||||
RECREATE="$SERVICE"
|
||||
if [[ "$SERVICE" == "all" ]]; then
|
||||
RECREATE="api player admin"
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
|
||||
服务器首次部署:
|
||||
./scripts/deploy-first.sh --images $(basename "$OUTPUT_PATH") --tag $TAG
|
||||
|
||||
服务器后续更新:
|
||||
./scripts/deploy-update.sh --images $(basename "$OUTPUT_PATH") --tag $TAG
|
||||
服务器导入并重建:
|
||||
docker load -i $(basename "$OUTPUT_PATH")
|
||||
docker compose -f docker-compose.prod.yml --env-file .env.docker up -d --force-recreate $RECREATE
|
||||
EOF
|
||||
|
||||
7
docs/docker/build-and-export-player.bat
Normal file
7
docs/docker/build-and-export-player.bat
Normal file
@@ -0,0 +1,7 @@
|
||||
@echo off
|
||||
REM Build and export thebet365-player image only (tag default: latest).
|
||||
REM Usage:
|
||||
REM docs\docker\build-and-export-player.bat
|
||||
REM docs\docker\build-and-export-player.bat --use-cache
|
||||
REM docs\docker\build-and-export-player.bat --export-only
|
||||
"%~dp0build-and-export-images.bat" --service player %*
|
||||
@@ -12,11 +12,16 @@
|
||||
|
||||
| 文件 | 适用环境 |
|
||||
|------|----------|
|
||||
| `docs/docker/build-and-export-images.bat` | Windows(CMD,可双击) |
|
||||
| `docs/docker/build-and-export-images.bat` | Windows(CMD,构建全部) |
|
||||
| `docs/docker/build-and-export-api.bat` | Windows(仅 api,可双击) |
|
||||
| `docs/docker/build-and-export-player.bat` | Windows(仅 player,可双击) |
|
||||
| `docs/docker/build-and-export-admin.bat` | Windows(仅 admin,可双击) |
|
||||
| `docs/docker/build-and-export-images.ps1` | Windows(PowerShell) |
|
||||
| `docs/docker/build-and-export-images.sh` | Linux / macOS / Git Bash |
|
||||
|
||||
两个脚本行为一致:在**项目根目录**执行 compose 构建 → 导出为根目录下的 `thebet365-images-<tag>.tar`(默认),并生成同名 `.manifest.txt`。
|
||||
两个脚本行为一致:在**项目根目录**执行 compose 构建 → 导出 tar(默认 tag 为 **`latest`**),并生成同名 `.manifest.txt`。
|
||||
|
||||
**默认 tag 为 `latest`**,服务器 `docker load` 后可直接 `compose up`,无需再 `docker tag`。版本追溯见 manifest 里的 `git_commit`。若需保留多版本 tag,可传 `--tag v1.2.3`。
|
||||
|
||||
---
|
||||
|
||||
@@ -41,10 +46,19 @@
|
||||
|
||||
### Windows
|
||||
|
||||
**推荐(CMD / 双击):** 在项目根目录打开命令提示符,或直接双击 `docs\docker\build-and-export-images.bat`:
|
||||
**推荐(CMD / 双击):** 在项目根目录打开命令提示符,或直接双击对应 bat:
|
||||
|
||||
```bat
|
||||
docs\docker\build-and-export-images.bat
|
||||
docs\docker\build-and-export-api.bat
|
||||
docs\docker\build-and-export-player.bat
|
||||
docs\docker\build-and-export-admin.bat
|
||||
```
|
||||
|
||||
单服务 bat 等价于 `build-and-export-images.bat --service <name>`,其余参数(`--use-cache`、`--export-only`、`--tag` 等)照常追加即可,例如:
|
||||
|
||||
```bat
|
||||
docs\docker\build-and-export-admin.bat --use-cache
|
||||
```
|
||||
|
||||
PowerShell 也可用:
|
||||
@@ -66,12 +80,28 @@ chmod +x docs/docker/build-and-export-images.sh
|
||||
|
||||
| BAT / PowerShell | Bash | 说明 |
|
||||
|----------------|------|------|
|
||||
| `--tag v1.2.3` / `-Tag v1.2.3` | `--tag v1.2.3` | 指定镜像 tag;未指定时默认当前 Git 短提交号 |
|
||||
| `--service admin` / `-Service admin` | `--service admin` | 只构建/导出单个服务(`api` / `player` / `admin` / `all`) |
|
||||
| `--tag v1.2.3` / `-Tag v1.2.3` | `--tag v1.2.3` | 指定镜像 tag;**默认 `latest`** |
|
||||
| (默认) | (默认) | `--no-cache` 全量构建,适合发版 |
|
||||
| `--use-cache` / `-UseCache` | `--use-cache` | 使用 Docker 缓存,构建更快 |
|
||||
| `--export-only` / `-ExportOnly` | `--export-only` | 跳过构建,仅导出已有指定 tag 镜像 |
|
||||
| `--output my.tar` / `-Output my.tar` | `--output my.tar` | 自定义导出文件名 |
|
||||
|
||||
默认导出文件名:
|
||||
|
||||
| 范围 | 默认 tar |
|
||||
|------|----------|
|
||||
| 全部 | `thebet365-images-latest.tar` |
|
||||
| 仅 admin | `thebet365-admin-latest.tar` |
|
||||
| 仅 api | `thebet365-api-latest.tar` |
|
||||
| 仅 player | `thebet365-player-latest.tar` |
|
||||
|
||||
示例:只打包 admin(含邀请链接 `VITE_PLAYER_URL`)
|
||||
|
||||
```bat
|
||||
docs\docker\build-and-export-images.bat --service admin
|
||||
```
|
||||
|
||||
示例:仅重新导出已有镜像
|
||||
|
||||
```bat
|
||||
|
||||
Reference in New Issue
Block a user