Files
backend_v2/scripts/push-build.sh
toom1996 2e76507d37 deploy: 本地预构建发布(push-build),对齐 1Panel 与 backend_v2 目录
- 新增 Dockerfile.prebuilt / scripts/push-build.sh:本机构建、只上传产物,服务器零编译
- deploy.sh 增加 --prebuilt(自动 --no-pull + 产物校验),并保留 --no-cache
- compose 支持 BACKEND_DOCKERFILE / WEB_DOCKERFILE 切换;预构建时用 prebuilt 变体
- init-db.sh / scripts/backup-db.sh 改为 docker exec 1Panel 的 Postgres 容器
- WEB_DIR 默认改为 ../frontend_v2;nginx 切换文件改到 .deploy/ 避免弄脏工作区
- 新增 .gitattributes 固定脚本与配置为 LF
2026-10-21 00:02:18 +08:00

106 lines
4.4 KiB
Bash
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
# 本地构建 + 上传 + 远程发布(前后端都走预构建,服务器不编译)
#
# SERVER=user@server ./scripts/push-build.sh
# SERVER=user@server REMOTE_DIR=/opt/fashion WEB_DIR=../test ./scripts/push-build.sh
#
# 流程:
# 1. 建 SSH 隧道(本地 18091 → 服务器回环 18091):前端构建期靠它读线上 SSG 数据
# 2. 本机 npm run build → 静态页内容与线上数据一致,且不占服务器资源
# 3. 本机交叉编译 linux/amd64 → 产出 server-linux-amd64
# 4. 上传 dist/ 与二进制
# 5. 远程 ./deploy.sh all --prebuilt → 服务器只打镜像 + 蓝绿切换
set -euo pipefail
cd "$(dirname "$0")/.." # 后端仓根
SERVER="${SERVER:-}"
if [ -z "$SERVER" ]; then
echo "用法: SERVER=user@host ./scripts/push-build.sh"
echo ""
echo "可选环境变量:"
echo " REMOTE_DIR 服务器上的项目根(默认 /opt/fashion)"
echo " WEB_DIR 本地前端仓(默认 ../test)"
echo " SSH_OPTS 额外 ssh 参数(默认 -o ConnectTimeout=10)"
exit 1
fi
REMOTE_DIR="${REMOTE_DIR:-/opt/fashion}"
REMOTE_BACKEND="${REMOTE_BACKEND:-${REMOTE_DIR}/backend_v2}"
REMOTE_FRONTEND="${REMOTE_FRONTEND:-${REMOTE_DIR}/frontend_v2}"
WEB_DIR="${WEB_DIR:-../frontend_v2}"
SSH_OPTS="${SSH_OPTS:--o ConnectTimeout=10}"
TUNNEL_PORT="${TUNNEL_PORT:-18091}"
# 本机也放一份 .env(复制服务器那份即可),用于取 SSG_TOKEN 等构建期密钥
SSG_TOKEN="${SSG_TOKEN:-}"
if [ -f .env ]; then
# shellcheck disable=SC1091
set -a; . ./.env; set +a
fi
TUNNEL_PID=""
cleanup() { [ -n "$TUNNEL_PID" ] && kill "$TUNNEL_PID" 2>/dev/null || true; }
trap cleanup EXIT
echo "==> 0/5 检查 SSH 免密登录"
# 隧道是后台起的(ssh -N ... &),一旦需要交互输密码就会静默卡住,所以必须免密。
if ! ssh $SSH_OPTS -o BatchMode=yes "$SERVER" true 2>/dev/null; then
echo "!! 无法免密登录 $SERVER"
echo ""
echo " Windows(PowerShell):"
echo " ssh-keygen -t ed25519 -C deploy@local"
echo " type \$env:USERPROFILE\\.ssh\\id_ed25519.pub | ssh $SERVER \"mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys\""
echo ""
echo " Linux / macOS / WSL:"
echo " ssh-keygen -t ed25519 -C deploy@local && ssh-copy-id $SERVER"
echo ""
echo " 配好后用这条确认:ssh $SERVER true && echo ok"
exit 1
fi
echo " 通过"
# 服务器若开了 SSG_TOKEN,构建期必须带同一个值。自动从服务器 .env 取,避免本机再维护一份密钥。
if [ -z "${SSG_TOKEN:-}" ]; then
SSG_TOKEN="$(ssh $SSH_OPTS -o BatchMode=yes "$SERVER" \
"grep -m1 '^SSG_TOKEN=' '${REMOTE_BACKEND}/.env' 2>/dev/null | cut -d= -f2-" 2>/dev/null || true)"
if [ -n "$SSG_TOKEN" ]; then
echo " 已从服务器读取 SSG_TOKEN(${#SSG_TOKEN} 字符)"
else
echo " 服务器未设置 SSG_TOKEN,构建期不带 token"
fi
fi
echo "==> 1/5 建立 SSH 隧道(本地 ${TUNNEL_PORT} → ${SERVER}:127.0.0.1:18091)"
ssh -N $SSH_OPTS -o ExitOnForwardFailure=yes \
-L "${TUNNEL_PORT}:127.0.0.1:18091" "$SERVER" &
TUNNEL_PID=$!
for i in $(seq 1 15); do
if (echo > "/dev/tcp/127.0.0.1/${TUNNEL_PORT}") >/dev/null 2>&1; then
break
fi
if [ "$i" -eq 15 ]; then
echo "!! 隧道 15 秒内没建起来(检查 SSH 连通性、服务器上 proxy 是否在跑)"
exit 1
fi
sleep 1
done
echo "==> 2/5 构建前端(构建期数据来自线上)"
(cd "$WEB_DIR" && BASE_API_SSG="http://127.0.0.1:${TUNNEL_PORT}" SSG_TOKEN="$SSG_TOKEN" npm run build)
[ -f "$WEB_DIR/dist/server/entry.mjs" ] || { echo "!! 前端产物缺失:$WEB_DIR/dist/server/entry.mjs"; exit 1; }
echo "==> 3/5 交叉编译后端(linux/amd64)"
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
go build -trimpath -ldflags "-s -w" -o server-linux-amd64 ./cmd/server
echo "==> 4/5 上传产物到 ${SERVER}:${REMOTE_DIR}"
ssh $SSH_OPTS "$SERVER" "mkdir -p '${REMOTE_BACKEND}' '${REMOTE_FRONTEND}'"
tar -C "$WEB_DIR" -czf - dist | ssh $SSH_OPTS "$SERVER" "tar -xzf - -C '${REMOTE_FRONTEND}'"
scp $SSH_OPTS server-linux-amd64 "${SERVER}:${REMOTE_BACKEND}/server-linux-amd64"
echo "==> 5/5 远程发布(预构建 + 蓝绿切换)"
RELEASE="$(date +%Y%m%d-%H%M%S)-$(git rev-parse --short HEAD 2>/dev/null || echo nogit)"
ssh $SSH_OPTS "$SERVER" "cd '${REMOTE_BACKEND}' && RELEASE='${RELEASE}' ./deploy.sh all --prebuilt"
echo "完成:$RELEASE"