Files
geo/deploy/scripts/package.sh
T
root 0a3558fc51 feat(deploy): add containerized deployment configuration and scripts
- Add Dockerfile for frontend and server services
- Add Docker Compose configs (standard and offline mode)
- Add nginx.conf for admin-web service
- Add deploy scripts: package.sh (packaging) and load-and-start.sh (startup)
- Add deploy/config.yaml, .env.example, and prompts.yml configurations
- Add image management design specification doc
2026-04-15 21:27:15 +08:00

161 lines
6.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.
#!/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"