Files
senmesh-zc/deployment/scripts/build-package.sh

151 lines
7.0 KiB
Bash
Raw Permalink Normal View History

#!/usr/bin/env bash
# =============================================================================
# 出包脚本(我方构建机上执行,现场用不到)
#
# ./deployment/scripts/build-package.sh 1.0.1
# TARGET_PLATFORM=linux/arm64 ./deployment/scripts/build-package.sh 1.0.1 # 鲲鹏/飞腾
#
# 版本号与 git tag 对应:出 1.0.1 的包就打 tag v1.0.1。
# 把 deployment/iw 与 deployment/ow 刷成两个可直接带走的完整部署包:
# 1. 后端 jar(mvn package,SKIP_JAR=1 跳过)
# 2. sfile-app:<版本> 镜像
# 3. 前端内/外网静态包 -> iw/web、ow/web(现场可直接改文件替换页面)
# 4. sql/01、sql/02(来自 backend/db)
# 5. images/*.tar + SHA256SUMS.txt(存一份到暂存目录再拷两侧,省一次 docker save)
# 6. 两侧 VERSION.txt,并把 .env 的 APP_IMAGE tag 对齐
#
# 不动两侧 volumes/(那是现场运行时数据)与 .env 里的口令。
# =============================================================================
set -euo pipefail
VER="${1:?用法:build-package.sh <版本号>,如 1.1.0}"
PLATFORM="${TARGET_PLATFORM:-linux/amd64}"
PLATFORM_TAG="$(echo "$PLATFORM" | tr -d '/:')"
HERE="$(cd "$(dirname "$0")" && pwd)" # deployment/scripts
ROOT="$(cd "$HERE/../.." && pwd)" # 仓库根
DEP="$ROOT/deployment"
APP_IMAGE="sfile-app:$VER"
WEB_TMP="sfile-web:pkg-$VER" # 只为导出前端静态包,不交付这个镜像
NGINX_IMAGE="nginx:1.27-alpine"
PG_IMAGE="postgres:18"
REDIS_IMAGE="redis:8"
MQ_IMAGE="rabbitmq:3.13-management-alpine"
APP_JAR="$ROOT/backend/target/s-file.jar"
STAGE="$DEP/.stage-images-$PLATFORM_TAG"
say() { printf '\n\033[1;36m==> %s\033[0m\n' "$1"; }
die() { printf '\033[1;31m!!! %s\033[0m\n' "$1" >&2; exit 1; }
[ -d "$DEP/iw" ] && [ -d "$DEP/ow" ] || die "找不到 deployment/iw 或 deployment/ow"
# 只重跑某几步:SKIP_JAR=1 SKIP_WEB=1 SKIP_SAVE=1
[ "${SKIP_JAR:-0}" = "1" ] || {
say "1/6 构建后端 jar(JDK8)"
[ -n "${JAVA_HOME:-}" ] || JAVA_HOME="/d/dev/jdk8/jdk8u504-b01"
MVN="${MVN:-/d/dev/maven-tmp/apache-maven-3.8.8/bin/mvn}"
command -v "$MVN" >/dev/null 2>&1 || die "找不到 maven:$MVN(用 MVN=<路径> 覆盖)"
( cd "$ROOT/backend" && "$MVN" -s /d/dev/maven-conf/settings.xml -q package -Dmaven.test.skip=true )
}
[ -s "$APP_JAR" ] || die "$APP_JAR 不存在或为空,先构建后端"
say " 使用 jar:$(ls -la "$APP_JAR" | awk '{print $5" 字节,"$6" "$7" "$8}')"
say "2/6 构建 $APP_IMAGE(平台 $PLATFORM)"
[ "$PLATFORM" = "linux/amd64" ] || say " 非 amd64 需要 buildx/QEMU 模拟器,慢属正常"
docker build --platform "$PLATFORM" -f "$ROOT/deploy/docker/Dockerfile.app" -t "$APP_IMAGE" "$ROOT/backend/target"
# 前端不打进镜像:静态包放 deployment/<侧>/web/,现场改页面直接替换文件
[ "${SKIP_WEB:-0}" = "1" ] || {
say "3/6 构建前端并从临时镜像导出内/外网静态包"
docker build --platform "$PLATFORM" -f "$ROOT/deploy/docker/Dockerfile.web" -t "$WEB_TMP" "$ROOT/frontend"
cid="$(docker create "$WEB_TMP")"
for side in iw ow; do
src=/usr/share/nginx/$([ "$side" = iw ] && echo inside || echo outside)
rm -rf "$DEP/$side/web"
docker cp "$cid:$src" "$DEP/$side/web"
[ -s "$DEP/$side/web/index.html" ] || die "$side/web 导出不完整(缺 index.html)"
printf ' %-3s web/ %s\n' "$side" "$(du -sh "$DEP/$side/web" | cut -f1)"
done
docker rm "$cid" >/dev/null
docker image rm "$WEB_TMP" >/dev/null 2>&1 || true
}
say "4/6 刷新 sql/(来自 backend/db)"
for side in iw ow; do
cp "$ROOT/backend/db/init-table-postgres-full.sql" "$DEP/$side/sql/01-init-table.sql"
cp "$ROOT/backend/db/init-data.sql" "$DEP/$side/sql/02-init-data.sql"
for u in "$ROOT"/backend/db/upgrade-*.sql; do cp "$u" "$DEP/$side/sql/upgrade/$(basename "$u")"; done
done
# Windows 上编辑器/工具很容易写出 CRLF:install.sh 带 \r 在 Linux 上第一行就报错,
# .env 的值尾部带 \r 会让口令/JWT 对不上。出包前把随包文本统一成 LF。
say " 统一随包文本为 LF"
for side in iw ow; do
for f in $(find "$DEP/$side" -maxdepth 2 -type f \
\( -name '*.sh' -o -name '*.yml' -o -name '*.sql' -o -name '*.conf' \
-o -name '*.md' -o -name '*.txt' -o -name '.env' \) \
-not -path "*/images/*"); do
tr -d '\r' < "$f" > "$f.lf" && mv "$f.lf" "$f"
done
done
# ---------- 5. 镜像 tar ----------
for img in "$PG_IMAGE" "$REDIS_IMAGE" "$MQ_IMAGE" "$NGINX_IMAGE"; do
docker image inspect "$img" >/dev/null 2>&1 || {
say " 本机没有 $img,拉取 $PLATFORM 版本"
docker pull --platform "$PLATFORM" "$img"
}
done
[ "${SKIP_SAVE:-0}" = "1" ] || {
say "5/6 docker save(先存暂存目录再拷两侧,约 640M × 2)"
rm -rf "$STAGE"; mkdir -p "$STAGE"
docker save -o "$STAGE/sfile-app.tar" "$APP_IMAGE"
docker save -o "$STAGE/nginx.tar" "$NGINX_IMAGE"
docker save -o "$STAGE/postgres.tar" "$PG_IMAGE"
docker save -o "$STAGE/redis.tar" "$REDIS_IMAGE"
docker save -o "$STAGE/rabbitmq.tar" "$MQ_IMAGE"
( cd "$STAGE" && sha256sum *.tar > SHA256SUMS.txt )
for side in iw ow; do
mkdir -p "$DEP/$side/images"
rm -f "$DEP/$side/images"/*.tar "$DEP/$side/images/SHA256SUMS.txt"
cp "$STAGE"/*.tar "$STAGE/SHA256SUMS.txt" "$DEP/$side/images/"
done
rm -rf "$STAGE"
}
say "6/6 对齐 .env 的 APP_IMAGE tag 并写 VERSION.txt"
for side in iw ow; do
sed -i -E "s|^APP_IMAGE=.*|APP_IMAGE=$APP_IMAGE|" "$DEP/$side/.env"
{
echo "s-file 部署包 $VER($([ "$side" = iw ] && echo 内网机 iw || echo 外网机 ow))"
echo "构建平台: $PLATFORM"
echo "导出时间: $(date '+%F %T')"
echo "后端 jar: $(cd "$ROOT" && git rev-parse --short HEAD)(+ 未提交改动则与本仓库当前源码一致)"
echo
echo "镜像清单(sha256 见 images/SHA256SUMS.txt):"
for t in "$DEP/$side/images"/*.tar; do
tags="$(tar -xOf "$t" manifest.json | tr -d '\n' \
| { grep -oE '"RepoTags":\[[^]]*\]' || true; } | awk 'NR==1{print}')"
printf ' %-18s %-8s %s\n' "$(basename "$t")" "$(du -h "$t" | cut -f1)" "${tags:-?}"
done
echo
echo "前端静态包: web/(内网包/外网包已分别就位,改页面直接替换文件)"
echo "SQL: sql/01-init-table.sql sql/02-init-data.sql 老库增量: sql/upgrade/"
echo
echo "现场步骤(本机执行):"
echo " 1) 整目录拷到服务器,例如 /opt/sfile-$side && cd /opt/sfile-$side"
echo " 2) vi .env # 至少确认 MESHSAFE_ENABLED/SECRET、WEB_PORT、SFILE_DATA_ROOT、GATE_*"
echo " 3) ./scripts/install.sh"
} > "$DEP/$side/VERSION.txt"
done
say "完成"
for side in iw ow; do
printf ' deployment/%s %s(images %s)\n' "$side" "$(du -sh "$DEP/$side" | cut -f1)" "$(du -sh "$DEP/$side/images" | cut -f1)"
done
echo " 拷包即用:内网机拿 iw/,外网机拿 ow/,两份互不依赖"
echo " 提醒:images/*.tar 与 SHA256SUMS.txt 已被 .gitignore 排除,只走交付盘"