Files
sub2api/build_docker.sh
yangjianbo 89b1b744f2 fix(构建): 支持配置基础镜像仓库
允许通过构建参数/脚本选项切换基础镜像来源,避免镜像源 403 影响构建
2025-12-29 12:00:33 +08:00

262 lines
7.2 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
# =============================================================================
# Sub2API Docker 镜像构建脚本
# =============================================================================
#
# 用法:
# ./build_docker.sh [选项]
#
# 选项:
# -t, --tag TAG 指定镜像标签 (默认: latest)
# -r, --registry REG 指定镜像仓库地址 (默认: 无)
# -b, --base-registry REG 指定基础镜像仓库地址 (默认: 使用 docker.io)
# -p, --push 构建后推送镜像到仓库
# --no-cache 不使用 Docker 构建缓存
# -h, --help 显示帮助信息
#
# 示例:
# ./build_docker.sh # 构建 sub2api:latest
# ./build_docker.sh -t v1.0.0 # 构建 sub2api:v1.0.0
# ./build_docker.sh -r ghcr.io/user -p # 构建并推送到 GitHub Container Registry
# ./build_docker.sh -t v1.0.0 --no-cache # 不使用缓存构建
#
# =============================================================================
set -e # 遇到错误立即退出
# =============================================================================
# 颜色定义
# =============================================================================
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# =============================================================================
# 默认配置
# =============================================================================
IMAGE_NAME="sub2api"
TAG="latest"
REGISTRY=""
BASE_IMAGE_REGISTRY="${BASE_IMAGE_REGISTRY:-}"
PUSH=false
NO_CACHE=""
# =============================================================================
# 辅助函数
# =============================================================================
# 打印带颜色的信息
info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
error() {
echo -e "${RED}[ERROR]${NC} $1"
exit 1
}
# 显示帮助信息
show_help() {
head -30 "$0" | tail -25
exit 0
}
# =============================================================================
# 参数解析
# =============================================================================
while [[ $# -gt 0 ]]; do
case $1 in
-t|--tag)
TAG="$2"
shift 2
;;
-r|--registry)
REGISTRY="$2"
shift 2
;;
-b|--base-registry)
BASE_IMAGE_REGISTRY="$2"
shift 2
;;
-p|--push)
PUSH=true
shift
;;
--no-cache)
NO_CACHE="--no-cache"
shift
;;
-h|--help)
show_help
;;
*)
error "未知选项: $1\n使用 -h 或 --help 查看帮助"
;;
esac
done
# =============================================================================
# 获取构建信息
# =============================================================================
# 获取 Git commit hash
get_commit() {
if git rev-parse --git-dir > /dev/null 2>&1; then
git rev-parse --short HEAD 2>/dev/null || echo "unknown"
else
echo "unknown"
fi
}
# 获取版本号 (优先使用 git tag)
get_version() {
if git rev-parse --git-dir > /dev/null 2>&1; then
# 尝试获取最近的 tag
local tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [[ -n "$tag" ]]; then
echo "$tag"
else
# 没有 tag使用 commit hash
echo "dev-$(get_commit)"
fi
else
echo "dev"
fi
}
# 获取构建日期 (ISO 8601 格式)
get_date() {
date -u +"%Y-%m-%dT%H:%M:%SZ"
}
# =============================================================================
# 主逻辑
# =============================================================================
# 切换到项目根目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# 检查 Dockerfile 是否存在
if [[ ! -f "Dockerfile" ]]; then
error "Dockerfile 不存在,请确保在项目根目录运行此脚本"
fi
# 获取构建参数
VERSION=$(get_version)
COMMIT=$(get_commit)
DATE=$(get_date)
# 解析基础镜像
NODE_IMAGE="node:24-alpine"
GOLANG_IMAGE="golang:1.25-alpine"
ALPINE_IMAGE="alpine:3.19"
if [[ -n "$BASE_IMAGE_REGISTRY" ]]; then
BASE_IMAGE_REGISTRY="${BASE_IMAGE_REGISTRY%/}"
NODE_IMAGE="${BASE_IMAGE_REGISTRY}/library/node:24-alpine"
GOLANG_IMAGE="${BASE_IMAGE_REGISTRY}/library/golang:1.25-alpine"
ALPINE_IMAGE="${BASE_IMAGE_REGISTRY}/library/alpine:3.19"
fi
# 构建完整镜像名称
if [[ -n "$REGISTRY" ]]; then
FULL_IMAGE_NAME="${REGISTRY}/${IMAGE_NAME}:${TAG}"
else
FULL_IMAGE_NAME="${IMAGE_NAME}:${TAG}"
fi
# 打印构建信息
echo ""
echo "=============================================="
echo " Sub2API Docker 镜像构建"
echo "=============================================="
info "镜像名称: ${FULL_IMAGE_NAME}"
info "版本: ${VERSION}"
info "Commit: ${COMMIT}"
info "构建时间: ${DATE}"
if [[ -n "$BASE_IMAGE_REGISTRY" ]]; then
info "基础镜像仓库: ${BASE_IMAGE_REGISTRY}"
fi
if [[ -n "$NO_CACHE" ]]; then
info "缓存: 禁用"
fi
echo "=============================================="
echo ""
# 执行构建
info "开始构建 Docker 镜像..."
docker build \
${NO_CACHE} \
--build-arg VERSION="${VERSION}" \
--build-arg COMMIT="${COMMIT}" \
--build-arg DATE="${DATE}" \
--build-arg NODE_IMAGE="${NODE_IMAGE}" \
--build-arg GOLANG_IMAGE="${GOLANG_IMAGE}" \
--build-arg ALPINE_IMAGE="${ALPINE_IMAGE}" \
-t "${FULL_IMAGE_NAME}" \
-f Dockerfile \
.
# 检查构建结果
if [[ $? -eq 0 ]]; then
success "镜像构建成功: ${FULL_IMAGE_NAME}"
else
error "镜像构建失败"
fi
# 如果指定了 latest 以外的 tag同时打上 latest 标签
if [[ "$TAG" != "latest" && -z "$REGISTRY" ]]; then
info "同时标记为 latest..."
docker tag "${FULL_IMAGE_NAME}" "${IMAGE_NAME}:latest"
fi
# 推送镜像
if [[ "$PUSH" == true ]]; then
if [[ -z "$REGISTRY" ]]; then
warn "未指定镜像仓库 (-r),跳过推送"
else
info "推送镜像到仓库..."
docker push "${FULL_IMAGE_NAME}"
# 如果不是 latest也推送 latest 标签
if [[ "$TAG" != "latest" ]]; then
LATEST_IMAGE="${REGISTRY}/${IMAGE_NAME}:latest"
docker tag "${FULL_IMAGE_NAME}" "${LATEST_IMAGE}"
docker push "${LATEST_IMAGE}"
fi
success "镜像推送成功"
fi
fi
# 显示镜像信息
echo ""
echo "=============================================="
info "构建完成!"
echo "=============================================="
echo ""
info "运行容器示例:"
echo " docker run -d \\"
echo " --name sub2api \\"
echo " -p 8080:8080 \\"
echo " -e AUTO_SETUP=true \\"
echo " -e DATABASE_HOST=your-db-host \\"
echo " -e DATABASE_PASSWORD=your-password \\"
echo " -e REDIS_HOST=your-redis-host \\"
echo " ${FULL_IMAGE_NAME}"
echo ""
info "查看镜像大小:"
docker images "${IMAGE_NAME}" --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
echo ""