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
This commit is contained in:
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
# load-and-start.sh — 在【离线目标服务器】上运行
|
||||
# 加载镜像并启动所有服务
|
||||
#
|
||||
# 用法(解压部署包后):
|
||||
# bash deploy.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# 读取打包时记录的元数据
|
||||
if [[ -f "${SCRIPT_DIR}/.package-meta" ]]; then
|
||||
source "${SCRIPT_DIR}/.package-meta"
|
||||
fi
|
||||
IMAGE_TAG="${IMAGE_TAG:-latest}"
|
||||
LOCAL_PREFIX="${LOCAL_PREFIX:-geo-rankly}"
|
||||
|
||||
# ─── 检查 .env ────────────────────────────────────────────────────────────────
|
||||
if [[ ! -f "${SCRIPT_DIR}/.env" ]]; then
|
||||
echo "❌ 未找到 .env 文件,请先执行:"
|
||||
echo " cp .env.example .env && vi .env"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ─── Step 1: 加载镜像 ─────────────────────────────────────────────────────────
|
||||
echo "==> [1/3] 加载 Docker 镜像(可能需要几分钟)..."
|
||||
docker load -i "${SCRIPT_DIR}/images.tar"
|
||||
echo " 镜像加载完成"
|
||||
docker images | grep -E "geo-rankly|postgres|rabbitmq|redis|qdrant|minio" | head -20
|
||||
|
||||
# ─── Step 2: 设置 IMAGE_REGISTRY 为本地前缀 ──────────────────────────────────
|
||||
echo "==> [2/3] 配置离线镜像引用..."
|
||||
export IMAGE_REGISTRY="${LOCAL_PREFIX}"
|
||||
export IMAGE_TAG="${IMAGE_TAG}"
|
||||
|
||||
# ─── Step 3: 启动服务 ─────────────────────────────────────────────────────────
|
||||
echo "==> [3/3] 启动所有服务..."
|
||||
cd "${SCRIPT_DIR}"
|
||||
docker compose \
|
||||
-f docker-compose.yaml \
|
||||
-f docker-compose.offline.yaml \
|
||||
--env-file .env \
|
||||
up -d
|
||||
|
||||
echo ""
|
||||
echo "✅ 部署完成!"
|
||||
echo ""
|
||||
echo "服务状态:"
|
||||
docker compose -f docker-compose.yaml -f docker-compose.offline.yaml ps
|
||||
echo ""
|
||||
echo "查看日志: docker compose -f docker-compose.yaml logs -f tenant-api"
|
||||
echo "停止服务: docker compose -f docker-compose.yaml down"
|
||||
echo "管理界面:"
|
||||
echo " RabbitMQ: http://<server-ip>:15672 (geo / geo_dev)"
|
||||
echo " MinIO: http://<server-ip>:9001 (minioadmin / minioadmin)"
|
||||
Executable
+160
@@ -0,0 +1,160 @@
|
||||
#!/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"
|
||||
Reference in New Issue
Block a user