161 lines
6.1 KiB
Bash
161 lines
6.1 KiB
Bash
|
|
#!/usr/bin/env bash
|
|||
|
|
# package.sh — 在【有网络的开发机】上运行
|
|||
|
|
# 构建所有镜像(支持跨平台),打包成可离线部署的压缩包
|
|||
|
|
#
|
|||
|
|
# 用法:
|
|||
|
|
# bash package.sh [IMAGE_TAG] [PLATFORM]
|
|||
|
|
#
|
|||
|
|
# 示例:
|
|||
|
|
# bash package.sh latest linux/amd64 # M1/M2 Mac 打包给 x86 服务器(默认)
|
|||
|
|
# bash package.sh v1.0.0 linux/arm64 # 打包给 ARM 服务器(如树莓派、飞腾)
|
|||
|
|
# bash package.sh latest linux/amd64,linux/arm64 # 暂不支持(save 不支持 multi-arch)
|
|||
|
|
#
|
|||
|
|
# 产物:
|
|||
|
|
# geo-rankly-deploy-<date>-<arch>.tar.gz
|
|||
|
|
|
|||
|
|
set -euo pipefail
|
|||
|
|
|
|||
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|||
|
|
DEPLOY_DIR="${REPO_ROOT}/deploy"
|
|||
|
|
IMAGE_TAG="${1:-latest}"
|
|||
|
|
PLATFORM="${2:-linux/amd64}"
|
|||
|
|
LOCAL_PREFIX="geo-rankly"
|
|||
|
|
DATE_TAG="$(date +%Y%m%d)"
|
|||
|
|
# 将 linux/amd64 → amd64,用于包名
|
|||
|
|
ARCH_LABEL="${PLATFORM##*/}"
|
|||
|
|
PACKAGE_NAME="geo-rankly-deploy-${DATE_TAG}-${ARCH_LABEL}"
|
|||
|
|
WORK_DIR="/tmp/${PACKAGE_NAME}"
|
|||
|
|
|
|||
|
|
echo "==> 目标平台: ${PLATFORM} | 镜像 tag: ${IMAGE_TAG}"
|
|||
|
|
echo ""
|
|||
|
|
|
|||
|
|
# ─── 确保 buildx builder 支持目标平台 ────────────────────────────────────────
|
|||
|
|
echo "==> [0/5] 检查 buildx builder"
|
|||
|
|
BUILDER_NAME="geo-cross-builder"
|
|||
|
|
|
|||
|
|
if ! docker buildx inspect "${BUILDER_NAME}" &>/dev/null; then
|
|||
|
|
echo " 创建多平台 builder: ${BUILDER_NAME}"
|
|||
|
|
docker buildx create \
|
|||
|
|
--name "${BUILDER_NAME}" \
|
|||
|
|
--driver docker-container \
|
|||
|
|
--driver-opt image=moby/buildkit:latest \
|
|||
|
|
--use
|
|||
|
|
else
|
|||
|
|
docker buildx use "${BUILDER_NAME}"
|
|||
|
|
echo " 使用已有 builder: ${BUILDER_NAME}"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 确保 builder 已启动(首次使用时需要)
|
|||
|
|
docker buildx inspect --bootstrap "${BUILDER_NAME}" > /dev/null
|
|||
|
|
|
|||
|
|
# ─── 构建自定义镜像 ────────────────────────────────────────────────────────────
|
|||
|
|
echo "==> [1/5] 构建自定义镜像 (platform: ${PLATFORM}, tag: ${IMAGE_TAG})"
|
|||
|
|
cd "${REPO_ROOT}"
|
|||
|
|
|
|||
|
|
# 注意:--load 仅支持单平台;交叉编译时 buildx 使用 QEMU 或 Go 交叉编译
|
|||
|
|
_build() {
|
|||
|
|
local target="$1" tag_suffix="$2"
|
|||
|
|
shift 2
|
|||
|
|
echo " building ${LOCAL_PREFIX}/${tag_suffix}:${IMAGE_TAG}"
|
|||
|
|
docker buildx build \
|
|||
|
|
--platform "${PLATFORM}" \
|
|||
|
|
--target "${target}" \
|
|||
|
|
"$@" \
|
|||
|
|
--tag "${LOCAL_PREFIX}/${tag_suffix}:${IMAGE_TAG}" \
|
|||
|
|
--load \
|
|||
|
|
-f server/Dockerfile \
|
|||
|
|
server/
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_build runtime tenant-api --build-arg SERVICE=tenant-api
|
|||
|
|
_build runtime worker-generate --build-arg SERVICE=worker-generate
|
|||
|
|
_build runtime scheduler --build-arg SERVICE=scheduler
|
|||
|
|
_build migrate migrate # migrate stage 不需要 SERVICE arg
|
|||
|
|
|
|||
|
|
echo " building ${LOCAL_PREFIX}/frontend:${IMAGE_TAG}"
|
|||
|
|
docker buildx build \
|
|||
|
|
--platform "${PLATFORM}" \
|
|||
|
|
--tag "${LOCAL_PREFIX}/frontend:${IMAGE_TAG}" \
|
|||
|
|
--load \
|
|||
|
|
-f Dockerfile.frontend \
|
|||
|
|
.
|
|||
|
|
|
|||
|
|
# ─── 拉取基础设施镜像(指定平台) ─────────────────────────────────────────────
|
|||
|
|
echo "==> [2/5] 拉取基础设施镜像 (platform: ${PLATFORM})"
|
|||
|
|
INFRA_IMAGES=(
|
|||
|
|
"postgres:16-alpine"
|
|||
|
|
"rabbitmq:3.13-management-alpine"
|
|||
|
|
"redis:7-alpine"
|
|||
|
|
"qdrant/qdrant:v1.13.2"
|
|||
|
|
"minio/minio:RELEASE.2025-03-12T18-04-18Z"
|
|||
|
|
"minio/mc:latest"
|
|||
|
|
)
|
|||
|
|
for img in "${INFRA_IMAGES[@]}"; do
|
|||
|
|
echo " pulling ${img}"
|
|||
|
|
# --platform 确保拉取目标架构,覆盖本机可能已缓存的 arm64 版本
|
|||
|
|
docker pull --platform "${PLATFORM}" "${img}"
|
|||
|
|
done
|
|||
|
|
|
|||
|
|
# ─── 保存所有镜像 ───────────────────────────────────────────────────────────
|
|||
|
|
echo "==> [3/5] 保存所有镜像到 images.tar"
|
|||
|
|
mkdir -p "${WORK_DIR}"
|
|||
|
|
|
|||
|
|
ALL_IMAGES=(
|
|||
|
|
"${LOCAL_PREFIX}/tenant-api:${IMAGE_TAG}"
|
|||
|
|
"${LOCAL_PREFIX}/worker-generate:${IMAGE_TAG}"
|
|||
|
|
"${LOCAL_PREFIX}/scheduler:${IMAGE_TAG}"
|
|||
|
|
"${LOCAL_PREFIX}/migrate:${IMAGE_TAG}"
|
|||
|
|
"${LOCAL_PREFIX}/frontend:${IMAGE_TAG}"
|
|||
|
|
"postgres:16-alpine"
|
|||
|
|
"rabbitmq:3.13-management-alpine"
|
|||
|
|
"redis:7-alpine"
|
|||
|
|
"qdrant/qdrant:v1.13.2"
|
|||
|
|
"minio/minio:RELEASE.2025-03-12T18-04-18Z"
|
|||
|
|
"minio/mc:latest"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
docker save "${ALL_IMAGES[@]}" -o "${WORK_DIR}/images.tar"
|
|||
|
|
|
|||
|
|
# 验证镜像架构
|
|||
|
|
echo " 验证镜像架构:"
|
|||
|
|
for img in "${LOCAL_PREFIX}/tenant-api:${IMAGE_TAG}" "postgres:16-alpine"; do
|
|||
|
|
arch="$(docker inspect --format '{{.Architecture}}' "${img}" 2>/dev/null || echo unknown)"
|
|||
|
|
echo " ${img} → ${arch}"
|
|||
|
|
done
|
|||
|
|
echo " 镜像包大小: $(du -sh "${WORK_DIR}/images.tar" | cut -f1)"
|
|||
|
|
|
|||
|
|
# ─── 打包部署文件 ───────────────────────────────────────────────────────────
|
|||
|
|
echo "==> [4/5] 打包部署文件"
|
|||
|
|
cp "${DEPLOY_DIR}/docker-compose.yaml" "${WORK_DIR}/"
|
|||
|
|
cp "${DEPLOY_DIR}/docker-compose.offline.yaml" "${WORK_DIR}/"
|
|||
|
|
cp "${DEPLOY_DIR}/config.yaml" "${WORK_DIR}/"
|
|||
|
|
cp "${DEPLOY_DIR}/prompts.yml" "${WORK_DIR}/"
|
|||
|
|
cp "${DEPLOY_DIR}/.env.example" "${WORK_DIR}/"
|
|||
|
|
cp "${DEPLOY_DIR}/scripts/load-and-start.sh" "${WORK_DIR}/deploy.sh"
|
|||
|
|
chmod +x "${WORK_DIR}/deploy.sh"
|
|||
|
|
|
|||
|
|
# 写入元数据,供 load 脚本读取
|
|||
|
|
cat > "${WORK_DIR}/.package-meta" <<EOF
|
|||
|
|
IMAGE_TAG=${IMAGE_TAG}
|
|||
|
|
LOCAL_PREFIX=${LOCAL_PREFIX}
|
|||
|
|
PLATFORM=${PLATFORM}
|
|||
|
|
BUILT_AT=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|||
|
|
BUILT_ON=$(uname -m)
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
# ─── 压缩 ──────────────────────────────────────────────────────────────────
|
|||
|
|
echo "==> [5/5] 压缩打包"
|
|||
|
|
cd /tmp
|
|||
|
|
tar -czf "${REPO_ROOT}/${PACKAGE_NAME}.tar.gz" "${PACKAGE_NAME}/"
|
|||
|
|
rm -rf "${WORK_DIR}"
|
|||
|
|
|
|||
|
|
echo ""
|
|||
|
|
echo "✅ 打包完成: ${REPO_ROOT}/${PACKAGE_NAME}.tar.gz"
|
|||
|
|
echo " 平台: ${PLATFORM} | 大小: $(du -sh "${REPO_ROOT}/${PACKAGE_NAME}.tar.gz" | cut -f1)"
|
|||
|
|
echo ""
|
|||
|
|
echo "传输到目标服务器后执行:"
|
|||
|
|
echo " tar xzf ${PACKAGE_NAME}.tar.gz"
|
|||
|
|
echo " cd ${PACKAGE_NAME}"
|
|||
|
|
echo " cp .env.example .env && vi .env"
|
|||
|
|
echo " bash deploy.sh"
|