topfans/docker/build.sh
2026-04-24 18:04:55 +08:00

265 lines
9.1 KiB
Bash
Executable File
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.

#!/bin/bash
# ===================================================================
# TopFans Docker 一键构建脚本
# 功能:编译并打包所有后端服务为 Docker 镜像
# ===================================================================
#
# 使用方式:
# ./build.sh # 构建所有服务(默认)
# ./build.sh --no-cache # 无缓存构建
# ./build.sh gateway # 仅构建 Gateway
# ./build.sh userService # 仅构建 UserService
# ./build.sh prod # 使用生产配置构建
#
# 示例:
# ./build.sh # 构建所有服务
# ./build.sh --no-cache # 清除缓存重新构建
# ./build.sh gateway userService # 仅构建指定服务
# ===================================================================
set -e # 遇到错误立即退出
# ==================== 颜色定义 ====================
# 用于终端输出彩色文字,提升可读性
RED='\033[0;31m' # 红色 - 错误信息
GREEN='\033[0;32m' # 绿色 - 成功信息
YELLOW='\033[1;33m' # 黄色 - 警告/进度信息
BLUE='\033[0;34m' # 蓝色 - 标题信息
NC='\033[0m' # 重置颜色
# ==================== 路径配置 ====================
# 获取脚本所在目录(支持从任意目录调用)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# ==================== 构建配置 ====================
# 镜像前缀,用于标记和组织镜像(必须小写)
IMAGE_PREFIX="topfans"
# Dockerfile 路径
DOCKERFILE="Dockerfile.services"
# 目标架构amd64 适用于大多数服务器)
TARGET_ARCH="linux/amd64"
# ==================== 默认设置 ====================
# 是否使用缓存(默认使用,构建更快)
NO_CACHE=""
# 构建配置文件local 或 prod
PROFILE="local"
# 要构建的服务列表(留空则构建全部)
SERVICES=()
# ==================== 解析命令行参数 ====================
# 支持多种使用方式
# --no-cache: 清除 Docker 缓存,强制重新构建
# --profile prod: 使用生产配置
# 服务名: 仅构建指定服务(如 gateway, userService 等)
while [[ $# -gt 0 ]]; do
case $1 in
--no-cache)
# 启用无缓存构建,适用于代码更新后确保完全重新编译
NO_CACHE="--no-cache"
echo -e "${YELLOW}警告: 无缓存模式,构建时间较长${NC}"
shift
;;
--profile)
# 指定构建配置local 或 prod
PROFILE="$2"
shift 2
;;
--help|-h)
# 显示帮助信息
echo "用法: $0 [选项] [服务名...]"
echo ""
echo "选项:"
echo " --no-cache 不使用 Docker 缓存,强制重新构建"
echo " --profile <env> 使用配置文件 (local/prod),默认 local"
echo " --help, -h 显示此帮助信息"
echo ""
echo "服务名 (可选):"
echo " gateway, userService, socialService, assetService,"
echo " galleryService, activityService, taskService, starbookService"
echo ""
echo "示例:"
echo " $0 # 构建所有服务"
echo " $0 --no-cache # 无缓存构建所有服务"
echo " $0 gateway # 仅构建 Gateway"
echo " $0 --profile prod # 使用生产配置构建"
exit 0
;;
*)
# 未知参数,假设是服务名
# 支持的服务名映射(别名 -> 实际 target 名)
case $1 in
gateway) SERVICES+=("gateway") ;;
user|userService) SERVICES+=("userService") ;;
social|socialService) SERVICES+=("socialService") ;;
asset|assetService) SERVICES+=("assetService") ;;
gallery|galleryService) SERVICES+=("galleryService") ;;
activity|activityService) SERVICES+=("activityService") ;;
task|taskService) SERVICES+=("taskService") ;;
starbook|starbookService) SERVICES+=("starbookService") ;;
all)
# all 关键字,构建所有服务
SERVICES=()
break
;;
*)
echo -e "${RED}错误: 未知服务 '$1'${NC}"
echo "使用 --help 查看可用服务列表"
exit 1
;;
esac
shift
;;
esac
done
# ==================== 服务列表 ====================
# 所有可用服务及其配置(使用小写 target 名)
ALL_SERVICES_NAME=("gateway" "userservice" "socialservice" "assetservice" "galleryservice" "activityservice" "taskservice" "starbookservice")
# 确定要构建的服务
if [ ${#SERVICES[@]} -eq 0 ]; then
# 未指定服务,构建全部
SERVICE_NAMES=("${ALL_SERVICES_NAME[@]}")
else
SERVICE_NAMES=("${SERVICES[@]}")
fi
# ==================== 构建函数 ====================
# 打印分隔线
print_line() {
echo -e "${BLUE}========================================${NC}"
}
# 打印带颜色的消息
print_msg() {
local color=$1
local msg=$2
echo -e "${color}${msg}${NC}"
}
# 构建单个服务的镜像
# 参数: service_name docker_target
build_service() {
local service_name=$1
local docker_target=$2
echo -e "\n${YELLOW}正在构建 ${service_name}...${NC}"
# 检查 Dockerfile 是否存在
if [ ! -f "$DOCKERFILE" ]; then
echo -e "${RED}错误: Dockerfile ($DOCKERFILE) 不存在${NC}"
return 1
fi
# 构建镜像
# 镜像命名: topfans/gateway:latest, topfans/userService:latest 等
# -f: 指定 Dockerfile
# --target: 指定构建阶段(对应 Dockerfile 中的 AS xxx
# --platform: 指定目标平台
# $NO_CACHE: 是否使用缓存
docker build \
$NO_CACHE \
-f "$DOCKERFILE" \
--target "$docker_target" \
--platform "$TARGET_ARCH" \
-t "${IMAGE_PREFIX}/${service_name}:latest" \
../
if [ $? -eq 0 ]; then
print_msg "$GREEN" "${service_name} 构建成功"
return 0
else
print_msg "$RED" "${service_name} 构建失败"
return 1
fi
}
# ==================== 主构建流程 ====================
main() {
print_line
print_msg "$BLUE" " TopFans Docker 构建脚本"
print_msg "$BLUE" " 配置: ${PROFILE}"
print_msg "$BLUE" " 架构: ${TARGET_ARCH}"
print_line
# 记录开始时间
START_TIME=$(date +%s)
# 统计构建结果
SUCCESS_COUNT=0
FAIL_COUNT=0
# 构建每个服务
for service in "${SERVICE_NAMES[@]}"; do
# 服务名到 target 的映射(统一使用小写 target
case $service in
gateway) docker_target="gateway" ;;
userservice) docker_target="userservice" ;;
socialservice) docker_target="socialservice" ;;
assetservice) docker_target="assetservice" ;;
galleryservice) docker_target="galleryservice" ;;
activityservice) docker_target="activityservice" ;;
taskservice) docker_target="taskservice" ;;
starbookservice) docker_target="starbookservice" ;;
# 兼容旧的大写服务名
userService) docker_target="userservice" ;;
socialService) docker_target="socialservice" ;;
assetService) docker_target="assetservice" ;;
galleryService) docker_target="galleryservice" ;;
activityService) docker_target="activityservice" ;;
taskService) docker_target="taskservice" ;;
starbookService) docker_target="starbookservice" ;;
*) docker_target="$service" ;;
esac
if build_service "$service" "$docker_target"; then
((SUCCESS_COUNT++))
else
((FAIL_COUNT++))
fi
done
# ==================== 构建结果 ====================
print_line
print_msg "$BLUE" " 构建完成"
# 计算耗时
END_TIME=$(date +%s)
ELAPSED=$((END_TIME - START_TIME))
MINUTES=$((ELAPSED / 60))
SECONDS=$((ELAPSED % 60))
echo ""
print_msg "$GREEN" "✅ 成功: ${SUCCESS_COUNT} 个服务"
if [ $FAIL_COUNT -gt 0 ]; then
print_msg "$RED" "❌ 失败: ${FAIL_COUNT} 个服务"
fi
echo -e "${YELLOW}⏱ 耗时: ${MINUTES}${SECONDS}${NC}"
print_line
# 显示构建的镜像
echo ""
print_msg "$BLUE" "构建的镜像列表:"
echo ""
for service in "${SERVICE_NAMES[@]}"; do
# 获取镜像大小
SIZE=$(docker images "${IMAGE_PREFIX}/${service}:latest" --format "{{.Size}}" 2>/dev/null || echo "未知")
echo -e " ${GREEN}${IMAGE_PREFIX}/${service}:latest${NC} (${SIZE})"
done
echo ""
print_msg "$GREEN" "🎉 构建完成!"
echo ""
echo "下一步:"
echo " 启动服务 (本地): docker-compose -f docker-compose.local.yml --profile local up -d"
echo " 启动服务 (生产): docker-compose -f docker-compose.prod.yml --profile prod up -d"
echo ""
}
# 执行主函数
main