fix(deploy): 支持 full-themes 六合一包部署并统一 shell 脚本 LF 换行
This commit is contained in:
@@ -22,4 +22,7 @@ apps/api/dist
|
|||||||
mcps
|
mcps
|
||||||
assets
|
assets
|
||||||
agent-transcripts
|
agent-transcripts
|
||||||
|
.agents
|
||||||
|
.cursor
|
||||||
|
.ui-ux-pro-max-skill
|
||||||
**/.vite
|
**/.vite
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ function Invoke-PlayerThemeBuild {
|
|||||||
Write-Host "[INFO] Switched to $Branch"
|
Write-Host "[INFO] Switched to $Branch"
|
||||||
|
|
||||||
Set-Location $Root
|
Set-Location $Root
|
||||||
|
$env:PLAYER_IMAGE_TAG = $Tag
|
||||||
if ((Invoke-BuildExport -Service "player" -Tag $Tag) -ne 0) {
|
if ((Invoke-BuildExport -Service "player" -Tag $Tag) -ne 0) {
|
||||||
Write-Host "[ERROR] Player build failed for $Branch"
|
Write-Host "[ERROR] Player build failed for $Branch"
|
||||||
$script:FailedThemes.Add($Branch) | Out-Null
|
$script:FailedThemes.Add($Branch) | Out-Null
|
||||||
|
|||||||
@@ -131,6 +131,8 @@ goto do_export
|
|||||||
:do_build
|
:do_build
|
||||||
echo ==^> Building %SERVICE% (tag: %TAG%)
|
echo ==^> Building %SERVICE% (tag: %TAG%)
|
||||||
set "IMAGE_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 "%NO_CACHE%"=="1" goto build_no_cache
|
||||||
if /i "%SERVICE%"=="all" (
|
if /i "%SERVICE%"=="all" (
|
||||||
docker compose -f "%COMPOSE_FILE%" --env-file "%ENV_FILE%" build api player admin
|
docker compose -f "%COMPOSE_FILE%" --env-file "%ENV_FILE%" build api player admin
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ INIT_DB=false
|
|||||||
SKIP_BACKUP=false
|
SKIP_BACKUP=false
|
||||||
ALLOW_DEFAULT_SECRETS=false
|
ALLOW_DEFAULT_SECRETS=false
|
||||||
IMAGE_TAR=""
|
IMAGE_TAR=""
|
||||||
|
WITH_THEMES=false
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
@@ -30,6 +31,7 @@ usage() {
|
|||||||
--no-build 不构建镜像,直接使用服务器已有镜像
|
--no-build 不构建镜像,直接使用服务器已有镜像
|
||||||
--images PATH 先 docker load 指定镜像 tar,并自动跳过本机构建
|
--images PATH 先 docker load 指定镜像 tar,并自动跳过本机构建
|
||||||
--tag TAG 使用指定镜像 tag,并写入 .env.docker 的 IMAGE_TAG
|
--tag TAG 使用指定镜像 tag,并写入 .env.docker 的 IMAGE_TAG
|
||||||
|
--themes 启用四套 player(player2/3/4);加载 thebet365-full-themes-*.tar 时自动开启
|
||||||
--no-seed 不执行生产 seed
|
--no-seed 不执行生产 seed
|
||||||
--init-db 调用 scripts/prod-init-db.sh 清空业务数据并初始化生产数据,仅限全新库或明确重置
|
--init-db 调用 scripts/prod-init-db.sh 清空业务数据并初始化生产数据,仅限全新库或明确重置
|
||||||
--skip-backup 与 --init-db 一起使用,跳过 prod-init-db 的备份
|
--skip-backup 与 --init-db 一起使用,跳过 prod-init-db 的备份
|
||||||
@@ -39,6 +41,7 @@ usage() {
|
|||||||
示例:
|
示例:
|
||||||
./scripts/deploy-first.sh
|
./scripts/deploy-first.sh
|
||||||
./scripts/deploy-first.sh --images thebet365-images-v1.2.3.tar --tag v1.2.3
|
./scripts/deploy-first.sh --images thebet365-images-v1.2.3.tar --tag v1.2.3
|
||||||
|
./scripts/deploy-first.sh --images thebet365-full-themes-latest.tar --tag latest
|
||||||
./scripts/deploy-first.sh --no-build
|
./scripts/deploy-first.sh --no-build
|
||||||
./scripts/deploy-first.sh --init-db
|
./scripts/deploy-first.sh --init-db
|
||||||
EOF
|
EOF
|
||||||
@@ -59,6 +62,10 @@ while [ $# -gt 0 ]; do
|
|||||||
set_deploy_image_tag "${2:?缺少 --tag 参数值}"
|
set_deploy_image_tag "${2:?缺少 --tag 参数值}"
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
|
--themes)
|
||||||
|
WITH_THEMES=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
--no-seed)
|
--no-seed)
|
||||||
RUN_SEED=false
|
RUN_SEED=false
|
||||||
shift
|
shift
|
||||||
@@ -99,6 +106,12 @@ if [ -n "$IMAGE_TAR" ] && [ -z "${DEPLOY_IMAGE_TAG:-}" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$WITH_THEMES" = true ]; then
|
||||||
|
enable_themes_deploy
|
||||||
|
elif [ -n "$IMAGE_TAR" ]; then
|
||||||
|
maybe_enable_themes_from_tar "$IMAGE_TAR"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -n "$IMAGE_TAR" ]; then
|
if [ -n "$IMAGE_TAR" ]; then
|
||||||
load_image_tar "$IMAGE_TAR"
|
load_image_tar "$IMAGE_TAR"
|
||||||
fi
|
fi
|
||||||
@@ -118,8 +131,9 @@ if [ "$INIT_DB" = false ] && [ "$RUN_SEED" = true ]; then
|
|||||||
seed_production_if_missing_admin
|
seed_production_if_missing_admin
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log "启动 api / player / admin"
|
log "启动 $(stack_app_services)"
|
||||||
compose up -d api player admin
|
# shellcheck disable=SC2046
|
||||||
|
compose up -d $(stack_app_services)
|
||||||
wait_for_stack_ready
|
wait_for_stack_ready
|
||||||
|
|
||||||
if [ "$INIT_DB" = true ]; then
|
if [ "$INIT_DB" = true ]; then
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
DEPLOY_LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
DEPLOY_LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
ROOT="$(cd "$DEPLOY_LIB_DIR/.." && pwd)"
|
ROOT="$(cd "$DEPLOY_LIB_DIR/.." && pwd)"
|
||||||
COMPOSE_FILE="$ROOT/docker-compose.prod.yml"
|
COMPOSE_FILE="$ROOT/docker-compose.prod.yml"
|
||||||
|
COMPOSE_THEMES_FILE="$ROOT/docker-compose.themes.yml"
|
||||||
ENV_FILE="$ROOT/.env.docker"
|
ENV_FILE="$ROOT/.env.docker"
|
||||||
ENV_EXAMPLE_FILE="$ROOT/.env.docker.example"
|
ENV_EXAMPLE_FILE="$ROOT/.env.docker.example"
|
||||||
BACKUP_DIR="$ROOT/backups"
|
BACKUP_DIR="$ROOT/backups"
|
||||||
@@ -12,6 +13,7 @@ CURRENT_RELEASE_FILE="$DEPLOY_STATE_DIR/current-release.env"
|
|||||||
PREVIOUS_RELEASE_FILE="$DEPLOY_STATE_DIR/previous-release.env"
|
PREVIOUS_RELEASE_FILE="$DEPLOY_STATE_DIR/previous-release.env"
|
||||||
|
|
||||||
DEPLOY_IMAGE_TAG="${DEPLOY_IMAGE_TAG:-}"
|
DEPLOY_IMAGE_TAG="${DEPLOY_IMAGE_TAG:-}"
|
||||||
|
DEPLOY_WITH_THEMES="${DEPLOY_WITH_THEMES:-false}"
|
||||||
LAST_DB_BACKUP=""
|
LAST_DB_BACKUP=""
|
||||||
LAST_UPLOADS_BACKUP=""
|
LAST_UPLOADS_BACKUP=""
|
||||||
|
|
||||||
@@ -55,18 +57,95 @@ infer_image_tag_from_tar() {
|
|||||||
local base tag
|
local base tag
|
||||||
|
|
||||||
base="$(basename "$image_tar")"
|
base="$(basename "$image_tar")"
|
||||||
|
tag="${base#thebet365-full-themes-}"
|
||||||
|
tag="${tag%.tar}"
|
||||||
|
if [ "$tag" != "$base" ] && [ -n "$tag" ]; then
|
||||||
|
printf '%s' "$tag"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
tag="${base#thebet365-images-}"
|
tag="${base#thebet365-images-}"
|
||||||
tag="${tag%.tar}"
|
tag="${tag%.tar}"
|
||||||
|
|
||||||
if [ "$tag" != "$base" ] && [ -n "$tag" ]; then
|
if [ "$tag" != "$base" ] && [ -n "$tag" ]; then
|
||||||
printf '%s' "$tag"
|
printf '%s' "$tag"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
compose() {
|
is_full_themes_tar() {
|
||||||
|
local image_tar="$1"
|
||||||
|
case "$(basename "$image_tar")" in
|
||||||
|
thebet365-full-themes-*.tar) return 0 ;;
|
||||||
|
*) return 1 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
themes_enabled() {
|
||||||
|
[ "$DEPLOY_WITH_THEMES" = true ]
|
||||||
|
}
|
||||||
|
|
||||||
|
player_image_tag() {
|
||||||
local tag
|
local tag
|
||||||
|
tag="$(env_value PLAYER_IMAGE_TAG)"
|
||||||
|
tag="${tag:-main}"
|
||||||
|
validate_image_tag "$tag"
|
||||||
|
printf '%s' "$tag"
|
||||||
|
}
|
||||||
|
|
||||||
|
theme_player_tag() {
|
||||||
|
local key="$1"
|
||||||
|
local default_tag="$2"
|
||||||
|
local tag
|
||||||
|
tag="$(env_value "$key")"
|
||||||
|
tag="${tag:-$default_tag}"
|
||||||
|
validate_image_tag "$tag"
|
||||||
|
printf '%s' "$tag"
|
||||||
|
}
|
||||||
|
|
||||||
|
compose() {
|
||||||
|
local tag player_tag compose_args=(-f "$COMPOSE_FILE")
|
||||||
tag="$(current_image_tag)"
|
tag="$(current_image_tag)"
|
||||||
IMAGE_TAG="$tag" docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" "$@"
|
player_tag="$(player_image_tag)"
|
||||||
|
|
||||||
|
if themes_enabled; then
|
||||||
|
[ -f "$COMPOSE_THEMES_FILE" ] || die "缺少 $COMPOSE_THEMES_FILE,无法启动四套 player"
|
||||||
|
compose_args+=(-f "$COMPOSE_THEMES_FILE")
|
||||||
|
fi
|
||||||
|
|
||||||
|
IMAGE_TAG="$tag" \
|
||||||
|
PLAYER_IMAGE_TAG="$player_tag" \
|
||||||
|
docker compose "${compose_args[@]}" --env-file "$ENV_FILE" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
stack_app_services() {
|
||||||
|
if themes_enabled; then
|
||||||
|
printf '%s' "api player player2 player3 player4 admin"
|
||||||
|
else
|
||||||
|
printf '%s' "api player admin"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_themes_deploy() {
|
||||||
|
DEPLOY_WITH_THEMES=true
|
||||||
|
export DEPLOY_WITH_THEMES
|
||||||
|
log "四套 player 主题部署已启用"
|
||||||
|
}
|
||||||
|
|
||||||
|
maybe_enable_themes_from_tar() {
|
||||||
|
local image_tar="$1"
|
||||||
|
if is_full_themes_tar "$image_tar"; then
|
||||||
|
enable_themes_deploy
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
load_themes_from_release() {
|
||||||
|
local val
|
||||||
|
[ -f "$CURRENT_RELEASE_FILE" ] || return 1
|
||||||
|
val="$(grep -E '^deploy_with_themes=' "$CURRENT_RELEASE_FILE" 2>/dev/null | tail -1 | cut -d= -f2- || true)"
|
||||||
|
if [ "$val" = true ]; then
|
||||||
|
enable_themes_deploy
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
ensure_env_file() {
|
ensure_env_file() {
|
||||||
@@ -203,6 +282,11 @@ wait_for_service_health() {
|
|||||||
wait_for_stack_ready() {
|
wait_for_stack_ready() {
|
||||||
wait_for_service_health api 180
|
wait_for_service_health api 180
|
||||||
wait_for_service_health player 120
|
wait_for_service_health player 120
|
||||||
|
if themes_enabled; then
|
||||||
|
wait_for_service_health player2 120
|
||||||
|
wait_for_service_health player3 120
|
||||||
|
wait_for_service_health player4 120
|
||||||
|
fi
|
||||||
wait_for_service_health admin 120
|
wait_for_service_health admin 120
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,8 +298,13 @@ start_infra() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
build_app_images() {
|
build_app_images() {
|
||||||
log "构建 api / player / admin 镜像: $(current_image_tag)"
|
if themes_enabled; then
|
||||||
compose build api player admin
|
log "构建 api / player / player2 / player3 / player4 / admin 镜像"
|
||||||
|
compose build api player player2 player3 player4 admin
|
||||||
|
else
|
||||||
|
log "构建 api / player / admin 镜像: $(current_image_tag)"
|
||||||
|
compose build api player admin
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
load_image_tar() {
|
load_image_tar() {
|
||||||
@@ -225,12 +314,28 @@ load_image_tar() {
|
|||||||
docker load -i "$image_tar"
|
docker load -i "$image_tar"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
require_image() {
|
||||||
|
local ref="$1"
|
||||||
|
docker image inspect "$ref" >/dev/null 2>&1 || die "缺少镜像: $ref"
|
||||||
|
}
|
||||||
|
|
||||||
require_images_for_current_tag() {
|
require_images_for_current_tag() {
|
||||||
local tag
|
local tag player_tag t2 t3 t4
|
||||||
tag="$(current_image_tag)"
|
tag="$(current_image_tag)"
|
||||||
docker image inspect "thebet365-api:$tag" >/dev/null 2>&1 || die "缺少镜像: thebet365-api:$tag"
|
player_tag="$(player_image_tag)"
|
||||||
docker image inspect "thebet365-player:$tag" >/dev/null 2>&1 || die "缺少镜像: thebet365-player:$tag"
|
|
||||||
docker image inspect "thebet365-admin:$tag" >/dev/null 2>&1 || die "缺少镜像: thebet365-admin:$tag"
|
require_image "thebet365-api:$tag"
|
||||||
|
require_image "thebet365-player:$player_tag"
|
||||||
|
require_image "thebet365-admin:$tag"
|
||||||
|
|
||||||
|
if themes_enabled; then
|
||||||
|
t2="$(theme_player_tag PLAYER2_IMAGE_TAG theme-2)"
|
||||||
|
t3="$(theme_player_tag PLAYER3_IMAGE_TAG theme-3)"
|
||||||
|
t4="$(theme_player_tag PLAYER4_IMAGE_TAG theme-4)"
|
||||||
|
require_image "thebet365-player:$t2"
|
||||||
|
require_image "thebet365-player:$t3"
|
||||||
|
require_image "thebet365-player:$t4"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
run_prisma_migrations() {
|
run_prisma_migrations() {
|
||||||
@@ -343,9 +448,10 @@ current_release_tag() {
|
|||||||
|
|
||||||
record_release_state() {
|
record_release_state() {
|
||||||
local source="${1:-deploy}"
|
local source="${1:-deploy}"
|
||||||
local tag stamp safe_tag manifest previous_tag
|
local tag player_tag t2 t3 t4 stamp safe_tag manifest previous_tag
|
||||||
|
|
||||||
tag="$(current_image_tag)"
|
tag="$(current_image_tag)"
|
||||||
|
player_tag="$(player_image_tag)"
|
||||||
stamp="$(date -u +%Y%m%dT%H%M%SZ)"
|
stamp="$(date -u +%Y%m%dT%H%M%SZ)"
|
||||||
safe_tag="$(printf '%s' "$tag" | tr -c 'A-Za-z0-9_.-' '-')"
|
safe_tag="$(printf '%s' "$tag" | tr -c 'A-Za-z0-9_.-' '-')"
|
||||||
manifest="$RELEASES_DIR/${stamp}-${safe_tag}.env"
|
manifest="$RELEASES_DIR/${stamp}-${safe_tag}.env"
|
||||||
@@ -361,9 +467,18 @@ record_release_state() {
|
|||||||
printf 'previous_tag=%s\n' "$previous_tag"
|
printf 'previous_tag=%s\n' "$previous_tag"
|
||||||
printf 'deployed_at=%s\n' "$stamp"
|
printf 'deployed_at=%s\n' "$stamp"
|
||||||
printf 'source=%s\n' "$source"
|
printf 'source=%s\n' "$source"
|
||||||
|
printf 'deploy_with_themes=%s\n' "$DEPLOY_WITH_THEMES"
|
||||||
printf 'api_image=thebet365-api:%s\n' "$tag"
|
printf 'api_image=thebet365-api:%s\n' "$tag"
|
||||||
printf 'player_image=thebet365-player:%s\n' "$tag"
|
printf 'player_image=thebet365-player:%s\n' "$player_tag"
|
||||||
printf 'admin_image=thebet365-admin:%s\n' "$tag"
|
printf 'admin_image=thebet365-admin:%s\n' "$tag"
|
||||||
|
if themes_enabled; then
|
||||||
|
t2="$(theme_player_tag PLAYER2_IMAGE_TAG theme-2)"
|
||||||
|
t3="$(theme_player_tag PLAYER3_IMAGE_TAG theme-3)"
|
||||||
|
t4="$(theme_player_tag PLAYER4_IMAGE_TAG theme-4)"
|
||||||
|
printf 'player2_image=thebet365-player:%s\n' "$t2"
|
||||||
|
printf 'player3_image=thebet365-player:%s\n' "$t3"
|
||||||
|
printf 'player4_image=thebet365-player:%s\n' "$t4"
|
||||||
|
fi
|
||||||
[ -n "$LAST_DB_BACKUP" ] && printf 'db_backup=%s\n' "$LAST_DB_BACKUP"
|
[ -n "$LAST_DB_BACKUP" ] && printf 'db_backup=%s\n' "$LAST_DB_BACKUP"
|
||||||
[ -n "$LAST_UPLOADS_BACKUP" ] && printf 'uploads_backup=%s\n' "$LAST_UPLOADS_BACKUP"
|
[ -n "$LAST_UPLOADS_BACKUP" ] && printf 'uploads_backup=%s\n' "$LAST_UPLOADS_BACKUP"
|
||||||
} > "$manifest"
|
} > "$manifest"
|
||||||
@@ -373,21 +488,40 @@ record_release_state() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print_stack_urls() {
|
print_stack_urls() {
|
||||||
local player_port admin_port bind_addr tag
|
local player_port player2_port player3_port player4_port admin_port bind_addr tag player_tag
|
||||||
player_port="$(env_value PLAYER_PORT)"
|
player_port="$(env_value PLAYER_PORT)"
|
||||||
|
player2_port="$(env_value PLAYER2_PORT)"
|
||||||
|
player3_port="$(env_value PLAYER3_PORT)"
|
||||||
|
player4_port="$(env_value PLAYER4_PORT)"
|
||||||
admin_port="$(env_value ADMIN_PORT)"
|
admin_port="$(env_value ADMIN_PORT)"
|
||||||
bind_addr="$(env_value BIND_ADDR)"
|
bind_addr="$(env_value BIND_ADDR)"
|
||||||
tag="$(current_image_tag)"
|
tag="$(current_image_tag)"
|
||||||
|
player_tag="$(player_image_tag)"
|
||||||
player_port="${player_port:-8082}"
|
player_port="${player_port:-8082}"
|
||||||
|
player2_port="${player2_port:-8083}"
|
||||||
|
player3_port="${player3_port:-8084}"
|
||||||
|
player4_port="${player4_port:-8085}"
|
||||||
admin_port="${admin_port:-8081}"
|
admin_port="${admin_port:-8081}"
|
||||||
bind_addr="${bind_addr:-127.0.0.1}"
|
bind_addr="${bind_addr:-127.0.0.1}"
|
||||||
|
|
||||||
printf '\n'
|
printf '\n'
|
||||||
printf '%s\n' "部署完成:"
|
printf '%s\n' "部署完成:"
|
||||||
printf '%s\n' " 镜像 tag: ${tag}"
|
printf '%s\n' " api/admin 镜像 tag: ${tag}"
|
||||||
printf '%s\n' " 玩家端: http://${bind_addr}:${player_port}"
|
printf '%s\n' " player 镜像 tag: ${player_tag}"
|
||||||
|
if themes_enabled; then
|
||||||
|
printf '%s\n' " 玩家端 main: http://${bind_addr}:${player_port}"
|
||||||
|
printf '%s\n' " 玩家端 theme-2: http://${bind_addr}:${player2_port}"
|
||||||
|
printf '%s\n' " 玩家端 theme-3: http://${bind_addr}:${player3_port}"
|
||||||
|
printf '%s\n' " 玩家端 theme-4: http://${bind_addr}:${player4_port}"
|
||||||
|
else
|
||||||
|
printf '%s\n' " 玩家端: http://${bind_addr}:${player_port}"
|
||||||
|
fi
|
||||||
printf '%s\n' " 管理端: http://${bind_addr}:${admin_port}"
|
printf '%s\n' " 管理端: http://${bind_addr}:${admin_port}"
|
||||||
printf '%s\n' " API: 仅在 Docker 网络内暴露,由 player/admin 容器和宝塔反代链路访问"
|
printf '%s\n' " API: 仅在 Docker 网络内暴露,由 player/admin 容器和宝塔反代链路访问"
|
||||||
printf '%s\n' " 状态: docker compose -f docker-compose.prod.yml --env-file .env.docker ps"
|
if themes_enabled; then
|
||||||
|
printf '%s\n' " 状态: docker compose -f docker-compose.prod.yml -f docker-compose.themes.yml --env-file .env.docker ps"
|
||||||
|
else
|
||||||
|
printf '%s\n' " 状态: docker compose -f docker-compose.prod.yml --env-file .env.docker ps"
|
||||||
|
fi
|
||||||
printf '%s\n' " 当前发布: .deploy/current-release.env"
|
printf '%s\n' " 当前发布: .deploy/current-release.env"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ NO_BUILD=false
|
|||||||
SKIP_BACKUP=false
|
SKIP_BACKUP=false
|
||||||
ALLOW_DEFAULT_SECRETS=false
|
ALLOW_DEFAULT_SECRETS=false
|
||||||
IMAGE_TAR=""
|
IMAGE_TAR=""
|
||||||
|
WITH_THEMES=false
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
@@ -30,6 +31,7 @@ usage() {
|
|||||||
--pull 先执行 git pull --ff-only
|
--pull 先执行 git pull --ff-only
|
||||||
--images PATH 先 docker load 指定镜像 tar,并自动跳过本机构建
|
--images PATH 先 docker load 指定镜像 tar,并自动跳过本机构建
|
||||||
--tag TAG 使用指定镜像 tag,并写入 .env.docker 的 IMAGE_TAG
|
--tag TAG 使用指定镜像 tag,并写入 .env.docker 的 IMAGE_TAG
|
||||||
|
--themes 启用四套 player(player2/3/4);加载 thebet365-full-themes-*.tar 时自动开启
|
||||||
--no-build 不构建镜像,直接使用服务器已有镜像
|
--no-build 不构建镜像,直接使用服务器已有镜像
|
||||||
--no-backup 跳过 PostgreSQL 与 uploads 备份
|
--no-backup 跳过 PostgreSQL 与 uploads 备份
|
||||||
--allow-default-secrets 允许 .env.docker 使用示例密钥,仅测试环境使用
|
--allow-default-secrets 允许 .env.docker 使用示例密钥,仅测试环境使用
|
||||||
@@ -38,6 +40,7 @@ usage() {
|
|||||||
示例:
|
示例:
|
||||||
./scripts/deploy-update.sh --pull
|
./scripts/deploy-update.sh --pull
|
||||||
./scripts/deploy-update.sh --images thebet365-images-v1.2.3.tar --tag v1.2.3
|
./scripts/deploy-update.sh --images thebet365-images-v1.2.3.tar --tag v1.2.3
|
||||||
|
./scripts/deploy-update.sh --images thebet365-full-themes-latest.tar --tag latest
|
||||||
./scripts/deploy-update.sh --no-build
|
./scripts/deploy-update.sh --no-build
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
@@ -57,6 +60,10 @@ while [ $# -gt 0 ]; do
|
|||||||
set_deploy_image_tag "${2:?缺少 --tag 参数值}"
|
set_deploy_image_tag "${2:?缺少 --tag 参数值}"
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
|
--themes)
|
||||||
|
WITH_THEMES=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
--no-build)
|
--no-build)
|
||||||
NO_BUILD=true
|
NO_BUILD=true
|
||||||
shift
|
shift
|
||||||
@@ -92,6 +99,12 @@ if [ -n "$IMAGE_TAR" ] && [ -z "${DEPLOY_IMAGE_TAG:-}" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$WITH_THEMES" = true ]; then
|
||||||
|
enable_themes_deploy
|
||||||
|
elif [ -n "$IMAGE_TAR" ]; then
|
||||||
|
maybe_enable_themes_from_tar "$IMAGE_TAR"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$PULL_CODE" = true ]; then
|
if [ "$PULL_CODE" = true ]; then
|
||||||
require_command git
|
require_command git
|
||||||
log "拉取代码: git pull --ff-only"
|
log "拉取代码: git pull --ff-only"
|
||||||
@@ -121,8 +134,9 @@ fi
|
|||||||
|
|
||||||
run_prisma_migrations
|
run_prisma_migrations
|
||||||
|
|
||||||
log "启动/更新 api / player / admin"
|
log "启动/更新 $(stack_app_services)"
|
||||||
compose up -d api player admin
|
# shellcheck disable=SC2046
|
||||||
|
compose up -d $(stack_app_services)
|
||||||
wait_for_stack_ready
|
wait_for_stack_ready
|
||||||
show_prisma_status
|
show_prisma_status
|
||||||
compose ps
|
compose ps
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ source "$SCRIPT_DIR/deploy-lib.sh"
|
|||||||
TARGET_TAG=""
|
TARGET_TAG=""
|
||||||
SKIP_BACKUP=false
|
SKIP_BACKUP=false
|
||||||
ALLOW_DEFAULT_SECRETS=false
|
ALLOW_DEFAULT_SECRETS=false
|
||||||
|
WITH_THEMES="auto"
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
@@ -25,9 +26,12 @@ usage() {
|
|||||||
注意:
|
注意:
|
||||||
本脚本只回滚镜像,不回滚数据库结构或数据。
|
本脚本只回滚镜像,不回滚数据库结构或数据。
|
||||||
如果目标版本涉及不可逆迁移,必须先按备份文件手工恢复数据库。
|
如果目标版本涉及不可逆迁移,必须先按备份文件手工恢复数据库。
|
||||||
|
若当前发布启用了四套 player,默认会一并回滚 player2/3/4;可用 --no-themes 仅回滚单套 player。
|
||||||
|
|
||||||
选项:
|
选项:
|
||||||
--to TAG 目标镜像 tag,必填
|
--to TAG 目标镜像 tag,必填
|
||||||
|
--themes 回滚时启用四套 player(player2/3/4)
|
||||||
|
--no-themes 仅回滚单套 player,忽略当前发布的 themes 状态
|
||||||
--no-backup 跳过 PostgreSQL 与 uploads 备份
|
--no-backup 跳过 PostgreSQL 与 uploads 备份
|
||||||
--allow-default-secrets 允许 .env.docker 使用示例密钥,仅测试环境使用
|
--allow-default-secrets 允许 .env.docker 使用示例密钥,仅测试环境使用
|
||||||
-h, --help 显示帮助
|
-h, --help 显示帮助
|
||||||
@@ -43,6 +47,14 @@ while [ $# -gt 0 ]; do
|
|||||||
TARGET_TAG="${2:?缺少 --to 参数值}"
|
TARGET_TAG="${2:?缺少 --to 参数值}"
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
|
--themes)
|
||||||
|
WITH_THEMES=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--no-themes)
|
||||||
|
WITH_THEMES=false
|
||||||
|
shift
|
||||||
|
;;
|
||||||
--no-backup)
|
--no-backup)
|
||||||
SKIP_BACKUP=true
|
SKIP_BACKUP=true
|
||||||
shift
|
shift
|
||||||
@@ -68,6 +80,16 @@ cd "$ROOT"
|
|||||||
require_docker
|
require_docker
|
||||||
ensure_env_file || exit 1
|
ensure_env_file || exit 1
|
||||||
validate_prod_env "$ALLOW_DEFAULT_SECRETS"
|
validate_prod_env "$ALLOW_DEFAULT_SECRETS"
|
||||||
|
|
||||||
|
if [ "$WITH_THEMES" = true ]; then
|
||||||
|
enable_themes_deploy
|
||||||
|
elif [ "$WITH_THEMES" = false ]; then
|
||||||
|
DEPLOY_WITH_THEMES=false
|
||||||
|
export DEPLOY_WITH_THEMES
|
||||||
|
else
|
||||||
|
load_themes_from_release || true
|
||||||
|
fi
|
||||||
|
|
||||||
require_images_for_current_tag
|
require_images_for_current_tag
|
||||||
|
|
||||||
start_infra
|
start_infra
|
||||||
@@ -80,8 +102,9 @@ else
|
|||||||
warn "已跳过 PostgreSQL 与 uploads 备份"
|
warn "已跳过 PostgreSQL 与 uploads 备份"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log "回滚 api / player / admin 到 tag: $(current_image_tag)"
|
log "回滚 $(stack_app_services) 到 tag: $(current_image_tag)"
|
||||||
compose up -d api player admin
|
# shellcheck disable=SC2046
|
||||||
|
compose up -d $(stack_app_services)
|
||||||
wait_for_stack_ready
|
wait_for_stack_ready
|
||||||
show_prisma_status
|
show_prisma_status
|
||||||
compose ps
|
compose ps
|
||||||
|
|||||||
Reference in New Issue
Block a user