deploy(pay): pangolin1 部署脚手架(systemd/config/env/deploy,crypto+nezha 双渠道)
This commit is contained in:
Executable
+95
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env bash
|
||||
# pay v2 → pangolin1 专用部署脚本:交叉编译 → 传 pangolin1 → 首次装
|
||||
# 用户/目录/systemd unit/config.yaml → 备份旧二进制 → daemon-reload + enable --now →
|
||||
# 探活(失败自动回滚)。幂等:重复跑只刷新二进制,不覆盖 /etc/pay-v2/pay.env 或已存在的
|
||||
# /etc/pay-v2/config.yaml。
|
||||
#
|
||||
# 用法(pay 仓根目录执行):
|
||||
# ./deploy/pangolin1/deploy.sh
|
||||
#
|
||||
# 前提:
|
||||
# - ~/.ssh/config 有 pangolin1 别名(密钥登录);pangolin1 上以 root 身份操作
|
||||
# (systemctl / 装 unit / 建系统用户都需要)。
|
||||
# - 首次部署前,必须已在 pangolin1 上手工创建 /etc/pay-v2/pay.env
|
||||
# (参照 deploy/pangolin1/pay.env.example 填真值,真值一律走 Bitwarden/rbw)。
|
||||
# 本脚本刻意不生成/不覆盖这个文件——密钥不能经这条流水线过一遍。
|
||||
#
|
||||
# shellcheck disable=SC2029 # 下面 ssh 命令里的 $HOST/$DIR/$SVC 等都是本脚本的本地
|
||||
# 变量,故意要在客户端展开后再传给远端 shell(远端命令里没有任何"远端才存在的变量"),
|
||||
# 这正是想要的行为,不是需要转义的 bug。
|
||||
set -euo pipefail
|
||||
|
||||
HOST=pangolin1
|
||||
SVC=pay-v2
|
||||
SVC_USER=payv2
|
||||
DIR=/opt/pay-v2
|
||||
DATA_DIR=/var/lib/pay-v2
|
||||
ETC_DIR=/etc/pay-v2
|
||||
BIN=/tmp/pay-v2d-release
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
HERE="$REPO_ROOT/deploy/pangolin1"
|
||||
|
||||
log() { printf '\033[1;32m[deploy-pangolin1]\033[0m %s\n' "$*"; }
|
||||
warn() { printf '\033[1;33m[deploy-pangolin1]\033[0m %s\n' "$*" >&2; }
|
||||
|
||||
echo "[1/6] 交叉编译 linux/amd64 …"
|
||||
(
|
||||
cd "$REPO_ROOT"
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o "$BIN" .
|
||||
)
|
||||
|
||||
echo "[2/6] 首次初始化(幂等):系统用户 + 目录 …"
|
||||
ssh "$HOST" "
|
||||
set -e
|
||||
id -u '$SVC_USER' >/dev/null 2>&1 || useradd --system --no-create-home --shell /usr/sbin/nologin '$SVC_USER'
|
||||
mkdir -p '$DIR' '$DATA_DIR' '$ETC_DIR'
|
||||
chown -R '$SVC_USER:$SVC_USER' '$DATA_DIR'
|
||||
"
|
||||
|
||||
echo "[3/6] 装 systemd unit + config.yaml(不覆盖已存在的 config.yaml/pay.env)…"
|
||||
scp -q "$HERE/pay-v2.service" "$HOST:/etc/systemd/system/pay-v2.service"
|
||||
if ssh "$HOST" "[ -f '$ETC_DIR/config.yaml' ]"; then
|
||||
log "$ETC_DIR/config.yaml 已存在,跳过覆盖(改配置需手动: scp $HERE/config.yaml $HOST:$ETC_DIR/config.yaml)"
|
||||
else
|
||||
scp -q "$HERE/config.yaml" "$HOST:$ETC_DIR/config.yaml"
|
||||
log "已写入首个 $ETC_DIR/config.yaml"
|
||||
fi
|
||||
if ! ssh "$HOST" "[ -f '$ETC_DIR/pay.env' ]"; then
|
||||
warn "$ETC_DIR/pay.env 不存在!请先在 $HOST 上手工创建(参照 $HERE/pay.env.example,真值走 Bitwarden),"
|
||||
warn "否则 systemctl start 会因缺 env 报错或以空凭证跑起来。继续执行,但服务大概率起不来。"
|
||||
fi
|
||||
ssh "$HOST" "
|
||||
[ -f '$ETC_DIR/pay.env' ] && { chown root:'$SVC_USER' '$ETC_DIR/pay.env'; chmod 640 '$ETC_DIR/pay.env'; } || true
|
||||
chown root:root '$ETC_DIR/config.yaml' 2>/dev/null || true
|
||||
chmod 644 '$ETC_DIR/config.yaml' 2>/dev/null || true
|
||||
"
|
||||
|
||||
echo "[4/6] 上传二进制 + 备份旧版 + 切换 …"
|
||||
scp -q "$BIN" "$HOST:$DIR/payd-new"
|
||||
ssh "$HOST" "
|
||||
set -e
|
||||
[ -f '$DIR/payd' ] && cp '$DIR/payd' '$DIR/payd.bak' || true
|
||||
mv '$DIR/payd-new' '$DIR/payd'
|
||||
chmod +x '$DIR/payd'
|
||||
chown '$SVC_USER:$SVC_USER' '$DIR/payd'
|
||||
"
|
||||
|
||||
echo "[5/6] daemon-reload + enable --now …"
|
||||
ssh "$HOST" "systemctl daemon-reload && systemctl enable --now $SVC && systemctl restart $SVC"
|
||||
|
||||
echo "[6/6] 探活 …"
|
||||
if ssh "$HOST" "curl -fsS --retry 8 --retry-delay 1 --retry-connrefused -o /dev/null -w 'health %{http_code}\n' http://127.0.0.1:8090/health"; then
|
||||
echo "✅ 发布完成(上一版已备份在 $DIR/payd.bak,若存在)"
|
||||
else
|
||||
echo "❌ 探活失败,自动回滚 …"
|
||||
ssh "$HOST" "
|
||||
if [ -f '$DIR/payd.bak' ]; then
|
||||
cp '$DIR/payd.bak' '$DIR/payd' && systemctl restart '$SVC'
|
||||
else
|
||||
systemctl stop '$SVC'
|
||||
fi
|
||||
"
|
||||
echo "↩️ 已回滚/停止。请 ssh $HOST 'journalctl -u $SVC -n 100 --no-pager' 排查后重试。"
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user