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

331 lines
10 KiB
Batchfile
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@echo off
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
REM
REM 四套主题玩家端一键打包(自动切分支,推荐):
REM docs\docker\build-and-export-all-themes.bat
cd /d "%~dp0..\.."
set "COMPOSE_FILE=docker-compose.prod.yml"
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
if /i "%~1"=="-h" goto show_help
if /i "%~1"=="--help" goto show_help
if /i "%~1"=="/?" goto show_help
echo Unknown argument: %~1
goto show_help
:parse_tag
if "%~2"=="" (
echo ERROR: missing value for --tag
exit /b 1
)
set "TAG=%~2"
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
exit /b 1
)
set "OUTPUT=%~2"
shift
shift
goto parse_args
:show_help
echo.
echo Usage: docs\docker\build-and-export-images.bat [options]
echo.
echo --service SVC api ^| player ^| admin ^| api-admin ^| full-themes ^| 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.
echo 四套主题玩家端批量打包(自动切分支,推荐):
echo docs\docker\build-and-export-all-themes.bat
echo.
exit /b 0
:args_done
if not exist "%COMPOSE_FILE%" (
echo ERROR: missing %COMPOSE_FILE% in %CD%
exit /b 1
)
if not exist "%ENV_FILE%" (
if exist ".env.docker.example" (
echo WARN: using .env.docker.example instead of .env.docker
set "ENV_FILE=.env.docker.example"
) else (
echo ERROR: missing .env.docker and .env.docker.example
exit /b 1
)
)
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
exit /b 1
)
call :validate_tag
if errorlevel 1 exit /b 1
if not defined OUTPUT call :default_output
set "OUTPUT_PATH=%OUTPUT%"
if /i not "%OUTPUT:~1,1%"==":" set "OUTPUT_PATH=%CD%\%OUTPUT%"
where docker >nul 2>&1
if errorlevel 1 (
echo ERROR: docker not found. Start Docker Desktop first.
exit /b 1
)
if "%EXPORT_ONLY%"=="0" if /i not "%SERVICE%"=="full-themes" goto do_build
goto do_export
:do_build
echo ==^> Building %SERVICE% (tag: %TAG%)
set "IMAGE_TAG=%TAG%"
REM player 在 compose 里默认 PLAYER_IMAGE_TAG=main与 --tag 对齐以便导出/部署
set "PLAYER_IMAGE_TAG=%TAG%"
if "%NO_CACHE%"=="1" goto build_no_cache
if /i "%SERVICE%"=="all" (
docker compose -f "%COMPOSE_FILE%" --env-file "%ENV_FILE%" build api player admin
) else if /i "%SERVICE%"=="api-admin" (
docker compose -f "%COMPOSE_FILE%" --env-file "%ENV_FILE%" build api admin
) else (
docker compose -f "%COMPOSE_FILE%" --env-file "%ENV_FILE%" build %SERVICE%
)
goto build_done
:build_no_cache
if /i "%SERVICE%"=="all" (
docker compose -f "%COMPOSE_FILE%" --env-file "%ENV_FILE%" build --no-cache api player admin
) else if /i "%SERVICE%"=="api-admin" (
docker compose -f "%COMPOSE_FILE%" --env-file "%ENV_FILE%" build --no-cache api admin
) else (
docker compose -f "%COMPOSE_FILE%" --env-file "%ENV_FILE%" build --no-cache %SERVICE%
)
:build_done
if errorlevel 1 (
echo ERROR: docker build failed
exit /b 1
)
:do_export
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 if /i "%SERVICE%"=="api-admin" (
docker save thebet365-api:%TAG% thebet365-admin:%TAG% -o "%OUTPUT_PATH%"
) else if /i "%SERVICE%"=="full-themes" (
docker save thebet365-api:%TAG% thebet365-admin:%TAG% thebet365-player:main thebet365-player:theme-2 thebet365-player:theme-3 thebet365-player:theme-4 -o "%OUTPUT_PATH%"
) else (
docker save thebet365-%SERVICE%:%TAG% -o "%OUTPUT_PATH%"
)
if errorlevel 1 (
echo ERROR: docker save failed
exit /b 1
)
if /i "%OUTPUT_PATH:~-4%"==".tar" (
set "MANIFEST_PATH=%OUTPUT_PATH:~0,-4%.manifest.txt"
) else (
set "MANIFEST_PATH=%OUTPUT_PATH%.manifest.txt"
)
call :collect_git_info
call :collect_built_at
call :collect_tar_sha256
call :collect_image_ids
for %%F in ("%OUTPUT_PATH%") do set "TAR_NAME=%%~nxF"
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!
if /i "!SERVICE!"=="all" (
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!
) else if /i "!SERVICE!"=="api-admin" (
echo api_image=thebet365-api:%TAG%
echo api_image_id=!API_IMAGE_ID!
echo admin_image=thebet365-admin:%TAG%
echo admin_image_id=!ADMIN_IMAGE_ID!
) else if /i "!SERVICE!"=="full-themes" (
echo api_image=thebet365-api:%TAG%
echo api_image_id=!API_IMAGE_ID!
echo admin_image=thebet365-admin:%TAG%
echo admin_image_id=!ADMIN_IMAGE_ID!
echo player_main_image=thebet365-player:main
echo player_main_image_id=!PLAYER_MAIN_IMAGE_ID!
echo player_theme_2_image=thebet365-player:theme-2
echo player_theme_2_image_id=!PLAYER_THEME2_IMAGE_ID!
echo player_theme_3_image=thebet365-player:theme-3
echo player_theme_3_image_id=!PLAYER_THEME3_IMAGE_ID!
echo player_theme_4_image=thebet365-player:theme-4
echo player_theme_4_image_id=!PLAYER_THEME4_IMAGE_ID!
) else (
echo image=thebet365-!SERVICE!:%TAG%
echo image_id=!SVC_IMAGE_ID!
)
)
echo Done: %OUTPUT_PATH% ^(!SIZE_MB! MB^)
echo Manifest: %MANIFEST_PATH%
echo.
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 if /i "%SERVICE%"=="api-admin" (
echo docker load -i !TAR_NAME!
echo docker compose -f docker-compose.prod.yml --env-file .env.docker up -d --force-recreate api admin
) else if /i "%SERVICE%"=="full-themes" (
echo docker load -i !TAR_NAME!
echo docker compose -f docker-compose.prod.yml -f docker-compose.themes.yml --env-file .env.docker up -d
) 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
set "TAG=latest"
exit /b 0
:default_output
if /i "%SERVICE%"=="all" (
set "OUTPUT=thebet365-images-%TAG%.tar"
) else if /i "%SERVICE%"=="api-admin" (
set "OUTPUT=thebet365-images-%TAG%.tar"
) else if /i "%SERVICE%"=="full-themes" (
set "OUTPUT=thebet365-full-themes-%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-admin" exit /b 0
if /i "%SERVICE%"=="full-themes" 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, api-admin, full-themes, or all)
echo TIP: 四套主题一键打包请使用 docs\docker\build-and-export-all-themes.bat
exit /b 1
:validate_tag
echo %TAG%| findstr /r "^[A-Za-z0-9_][A-Za-z0-9_.-]*$" >nul
if errorlevel 1 (
echo ERROR: invalid image tag: %TAG%
exit /b 1
)
exit /b 0
:collect_git_info
set "GIT_COMMIT=unknown"
set "GIT_DIRTY=unknown"
for /f "delims=" %%C in ('git rev-parse HEAD 2^>nul') do set "GIT_COMMIT=%%C"
git diff --quiet 2>nul
set "DIFF_EXIT=!ERRORLEVEL!"
git diff --cached --quiet 2>nul
set "CACHED_EXIT=!ERRORLEVEL!"
if "!DIFF_EXIT!"=="0" if "!CACHED_EXIT!"=="0" set "GIT_DIRTY=false"
if not "!GIT_COMMIT!"=="unknown" if not "!GIT_DIRTY!"=="false" set "GIT_DIRTY=true"
exit /b 0
:collect_built_at
set "BUILT_AT=unknown"
for /f "delims=" %%T in ('powershell -NoProfile -Command "(Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ')"') do set "BUILT_AT=%%T"
exit /b 0
:collect_tar_sha256
set "TAR_SHA256=unavailable"
for /f "usebackq delims=" %%H in (`certutil -hashfile "%OUTPUT_PATH%" SHA256 ^| findstr /r "^[0-9a-fA-F][0-9a-fA-F]"`) do set "TAR_SHA256=%%H"
if defined TAR_SHA256 set "TAR_SHA256=!TAR_SHA256: =!"
exit /b 0
:collect_image_ids
set "API_IMAGE_ID="
set "PLAYER_IMAGE_ID="
set "ADMIN_IMAGE_ID="
set "SVC_IMAGE_ID="
set "PLAYER_MAIN_IMAGE_ID="
set "PLAYER_THEME2_IMAGE_ID="
set "PLAYER_THEME3_IMAGE_ID="
set "PLAYER_THEME4_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 "%SERVICE%"=="full-themes" (
for /f "delims=" %%I in ('docker image inspect thebet365-player:main --format "{{.Id}}" 2^>nul') do set "PLAYER_MAIN_IMAGE_ID=%%I"
for /f "delims=" %%I in ('docker image inspect thebet365-player:theme-2 --format "{{.Id}}" 2^>nul') do set "PLAYER_THEME2_IMAGE_ID=%%I"
for /f "delims=" %%I in ('docker image inspect thebet365-player:theme-3 --format "{{.Id}}" 2^>nul') do set "PLAYER_THEME3_IMAGE_ID=%%I"
for /f "delims=" %%I in ('docker image inspect thebet365-player:theme-4 --format "{{.Id}}" 2^>nul') do set "PLAYER_THEME4_IMAGE_ID=%%I"
) else 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