fix(docker): Windows entrypoint CRLF and admin invite link VITE_PLAYER_URL
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -25,6 +25,9 @@ BIND_ADDR=127.0.0.1
|
|||||||
PLAYER_PORT=8082
|
PLAYER_PORT=8082
|
||||||
ADMIN_PORT=8081
|
ADMIN_PORT=8081
|
||||||
|
|
||||||
|
# 管理端构建时注入:生成邀请注册链接的玩家端公网地址(勿带末尾 /)
|
||||||
|
VITE_PLAYER_URL=https://www.thebet365.net
|
||||||
|
|
||||||
# 备份保留天数;留空表示不自动清理
|
# 备份保留天数;留空表示不自动清理
|
||||||
BACKUP_RETENTION_DAYS=
|
BACKUP_RETENTION_DAYS=
|
||||||
|
|
||||||
|
|||||||
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.sh text eol=lf
|
||||||
@@ -100,6 +100,8 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: docker/admin/Dockerfile
|
dockerfile: docker/admin/Dockerfile
|
||||||
|
args:
|
||||||
|
VITE_PLAYER_URL: ${VITE_PLAYER_URL:-}
|
||||||
container_name: thebet365-admin
|
container_name: thebet365-admin
|
||||||
depends_on:
|
depends_on:
|
||||||
api:
|
api:
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ COPY packages/shared/package.json packages/shared/
|
|||||||
RUN pnpm install --frozen-lockfile
|
RUN pnpm install --frozen-lockfile
|
||||||
|
|
||||||
FROM base AS builder
|
FROM base AS builder
|
||||||
|
ARG VITE_PLAYER_URL
|
||||||
|
ENV VITE_PLAYER_URL=${VITE_PLAYER_URL}
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=deps /app/node_modules ./node_modules
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
COPY --from=deps /app/apps/api/node_modules ./apps/api/node_modules
|
COPY --from=deps /app/apps/api/node_modules ./apps/api/node_modules
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ COPY --from=builder /app/apps/api/node_modules ./apps/api/node_modules
|
|||||||
|
|
||||||
COPY uploads/banners ./uploads-default/banners
|
COPY uploads/banners ./uploads-default/banners
|
||||||
COPY docker/api/entrypoint.sh /entrypoint.sh
|
COPY docker/api/entrypoint.sh /entrypoint.sh
|
||||||
RUN chmod +x /entrypoint.sh
|
# Windows checkouts may use CRLF; strip before chmod or Linux exec fails with "no such file".
|
||||||
|
RUN sed -i 's/\r$//' /entrypoint.sh && chmod +x /entrypoint.sh
|
||||||
|
|
||||||
WORKDIR /app/apps/api
|
WORKDIR /app/apps/api
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|||||||
214
docs/docker/build-and-export-images.bat
Normal file
214
docs/docker/build-and-export-images.bat
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
@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 --tag v1.2.3
|
||||||
|
REM docs\docker\build-and-export-images.bat --use-cache
|
||||||
|
REM docs\docker\build-and-export-images.bat --export-only
|
||||||
|
|
||||||
|
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"
|
||||||
|
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"=="--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_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 --tag TAG Image tag (default: git short commit)
|
||||||
|
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.
|
||||||
|
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
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
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 set "OUTPUT=thebet365-images-%TAG%.tar"
|
||||||
|
|
||||||
|
set "OUTPUT_PATH=%OUTPUT%"
|
||||||
|
echo %OUTPUT_PATH%| findstr /r "^[A-Za-z]:\\" >nul
|
||||||
|
if errorlevel 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" goto do_build
|
||||||
|
goto do_export
|
||||||
|
|
||||||
|
:do_build
|
||||||
|
echo ==^> Building api, player, admin (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
|
||||||
|
goto build_done
|
||||||
|
|
||||||
|
:build_no_cache
|
||||||
|
docker compose -f "%COMPOSE_FILE%" --env-file "%ENV_FILE%" build --no-cache api player admin
|
||||||
|
|
||||||
|
:build_done
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo ERROR: docker build failed
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
:do_export
|
||||||
|
echo ==^> Exporting images to %OUTPUT_PATH%
|
||||||
|
docker save thebet365-api:%TAG% thebet365-player:%TAG% thebet365-admin:%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 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!
|
||||||
|
)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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"
|
||||||
|
exit /b 0
|
||||||
|
|
||||||
|
: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="
|
||||||
|
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"
|
||||||
|
exit /b 0
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
| 文件 | 适用环境 |
|
| 文件 | 适用环境 |
|
||||||
|------|----------|
|
|------|----------|
|
||||||
|
| `docs/docker/build-and-export-images.bat` | Windows(CMD,可双击) |
|
||||||
| `docs/docker/build-and-export-images.ps1` | Windows(PowerShell) |
|
| `docs/docker/build-and-export-images.ps1` | Windows(PowerShell) |
|
||||||
| `docs/docker/build-and-export-images.sh` | Linux / macOS / Git Bash |
|
| `docs/docker/build-and-export-images.sh` | Linux / macOS / Git Bash |
|
||||||
|
|
||||||
@@ -40,7 +41,13 @@
|
|||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
在项目根目录打开 PowerShell:
|
**推荐(CMD / 双击):** 在项目根目录打开命令提示符,或直接双击 `docs\docker\build-and-export-images.bat`:
|
||||||
|
|
||||||
|
```bat
|
||||||
|
docs\docker\build-and-export-images.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
PowerShell 也可用:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
.\docs\docker\build-and-export-images.ps1
|
.\docs\docker\build-and-export-images.ps1
|
||||||
@@ -57,16 +64,20 @@ chmod +x docs/docker/build-and-export-images.sh
|
|||||||
|
|
||||||
### 可选参数
|
### 可选参数
|
||||||
|
|
||||||
| PowerShell | Bash | 说明 |
|
| BAT / PowerShell | Bash | 说明 |
|
||||||
|------------|------|------|
|
|----------------|------|------|
|
||||||
| `-Tag v1.2.3` | `--tag v1.2.3` | 指定镜像 tag;未指定时默认当前 Git 短提交号 |
|
| `--tag v1.2.3` / `-Tag v1.2.3` | `--tag v1.2.3` | 指定镜像 tag;未指定时默认当前 Git 短提交号 |
|
||||||
| (默认) | (默认) | `--no-cache` 全量构建,适合发版 |
|
| (默认) | (默认) | `--no-cache` 全量构建,适合发版 |
|
||||||
| `-UseCache` | `--use-cache` | 使用 Docker 缓存,构建更快 |
|
| `--use-cache` / `-UseCache` | `--use-cache` | 使用 Docker 缓存,构建更快 |
|
||||||
| `-ExportOnly` | `--export-only` | 跳过构建,仅导出已有指定 tag 镜像 |
|
| `--export-only` / `-ExportOnly` | `--export-only` | 跳过构建,仅导出已有指定 tag 镜像 |
|
||||||
| `-Output my.tar` | `--output my.tar` | 自定义导出文件名 |
|
| `--output my.tar` / `-Output my.tar` | `--output my.tar` | 自定义导出文件名 |
|
||||||
|
|
||||||
示例:仅重新导出已有镜像
|
示例:仅重新导出已有镜像
|
||||||
|
|
||||||
|
```bat
|
||||||
|
docs\docker\build-and-export-images.bat --export-only
|
||||||
|
```
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
.\docs\docker\build-and-export-images.ps1 -ExportOnly
|
.\docs\docker\build-and-export-images.ps1 -ExportOnly
|
||||||
```
|
```
|
||||||
@@ -197,6 +208,7 @@ thebet365/
|
|||||||
├── Docker部署指南.md
|
├── Docker部署指南.md
|
||||||
└── docker/
|
└── docker/
|
||||||
├── 镜像构建与导出.md # 本文档
|
├── 镜像构建与导出.md # 本文档
|
||||||
|
├── build-and-export-images.bat
|
||||||
├── build-and-export-images.ps1
|
├── build-and-export-images.ps1
|
||||||
└── build-and-export-images.sh
|
└── build-and-export-images.sh
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user