按 demo/ 的写法把交付包改成「角色由目录决定」:iw/ 拷内网机、ow/ 拷外网机, 各自含镜像 tar、SQL、配置与 install.sh,install.sh 不再收 iw/ow 参数。 前端不再打进镜像,改为静态包放在 <侧>/web/ 只读挂进 nginx:1.27-alpine, 现场临时改页面直接替换文件 + restart web 即可。数据仍全部挂宿主机, 子目录命名与 deploy/offline 一致(pgdata/redis/mq/upload/logs/gate), 默认根改为包内 ./volumes,放数据盘只改 .env 的 SFILE_DATA_ROOT。 后端镜像 sfile-app:1.0.1 含传输优化那一批(实测组包 11.4×、解包 9.9×)。 出包脚本 deployment/scripts/build-package.sh 负责 jar→镜像→前端双包→sql→tar→VERSION。
151 lines
7.0 KiB
Bash
Executable File
151 lines
7.0 KiB
Bash
Executable File
#!/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 排除,只走交付盘"
|