Files
KCGL/deploy_code.sh
yueli ee64309151 deploy(deploy_code.sh): 脚本全量去 sudo 化,实现全程免密部署
/opt/inventory-app 属主为 dxc、docker 在 docker 组免 sudo,
脚本里所有 sudo 均为多余提权,且是手动/自动化部署卡住的主因:
- 第 1、4 步是独立 ssh 会话,每步都要重新输入 sudo 密码
- 非交互/自动化方式运行直接失败
- 去掉所有 sudo 与 ssh -t,无需 tty,手动与自动化通吃
- ssl 证书目录属主 root 不可读,备份那步保留 || 容错跳过
2026-08-31 16:45:39 +08:00

125 lines
5.3 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.

#!/bin/bash
# === 配置项 ===
SERVER="dxc@172.16.0.198"
REMOTE_DIR="/opt/inventory-app"
TIMESTAMP=$(date +%Y%m%d_%H%M)
REMOTE_BACKUP_BASE="$REMOTE_DIR/data_copy"
REMOTE_BACKUP_DIR="$REMOTE_BACKUP_BASE/$TIMESTAMP"
echo "==================================================="
echo "🚀 开始自动化增量部署 (含自我修复与依赖瘦身)"
echo "==================================================="
# 1. 远端备份与环境急救
echo "[1/4] 正在服务器上备份旧代码 (全程免密)..."
ssh $SERVER "mkdir -p $REMOTE_BACKUP_DIR && \
cd $REMOTE_DIR && \
echo '>> 检查并修复缺失目录 (防止 tar 崩溃)...' && \
mkdir -p inventory-backend inventory-web models_prod && \
echo '>> 执行代码备份...' && \
# ★ 排除大目录/模型(与本地打包一致)inventory-backend/models 含 605MB onnx不排除会导致 gzip 卡死
tar -czf $REMOTE_BACKUP_DIR/code_backup.tar.gz \
--exclude='inventory-backend/models' \
--exclude='inventory-backend/uploads' \
--exclude='inventory-backend/pgdata' \
--exclude='inventory-backend/pgdata_docker' \
inventory-backend inventory-web docker-compose.prod.yml && \
echo '>> 备份 SSL 证书...' && \
(tar -czf $REMOTE_BACKUP_DIR/ssl_backup.tar.gz ssl 2>/dev/null || echo '⚠️ ssl 目录不可读(属主 root)或不存在,跳过该备份') && \
echo '>> 检查 CLIP 模型文件...' && \
if [ ! -f models_prod/clip_vision.onnx ]; then \
echo '⚠️ 警告: models_prod/clip_vision.onnx 不存在!拍照识图功能将无法使用。'; \
echo '⚠️ 请手动上传: scp inventory-backend/models/clip_vision.onnx ${SERVER}:${REMOTE_DIR}/models_prod/'; \
else \
echo '✅ CLIP 模型文件已存在'; \
fi && \
echo '>> 执行清理:仅保留 data_copy 下最新的 2 个备份...' && \
cd $REMOTE_BACKUP_BASE && \
sh -c 'ls -dt */ 2>/dev/null | tail -n +3 | xargs -I {} rm -rf {} || true'"
if [ $? -ne 0 ]; then echo "❌ 服务器备份或清理失败,终止部署!"; exit 1; fi
# 2. 本地精准打包 (绝对屏蔽垃圾文件)
echo "[2/4] 正在本地打包新代码 (执行终极瘦身)..."
tar -czf deploy.tar.gz \
--exclude="*/node_modules" \
--exclude="*/venv" \
--exclude="*/.venv" \
--exclude="*/__pycache__" \
--exclude="*.pyc" \
--exclude="*/.git" \
--exclude="*/.idea" \
--exclude="*/.vscode" \
--exclude="inventory-backend/uploads" \
--exclude="inventory-backend/models" \
--exclude="inventory-backend/pgdata" \
--exclude="inventory-backend/pgdata_docker" \
--exclude="inventory-backend/test_*.py" \
--exclude="inventory-backend/fix_*.sql" \
--exclude="inventory-backend/*.sql" \
--exclude="inventory-backend/import_test_edge_cases.xlsx" \
--exclude="inventory-backend/import_edge_case_test.xlsx" \
--exclude="inventory-web/tsc-out.txt" \
--exclude="deploy.tar.gz" \
--exclude="data_copy" \
inventory-backend inventory-web docker-compose.prod.yml
# 检查压缩包大小是否正常 (如果超过 50MB 则发出警告)
FILESIZE=$(stat -c%s "deploy.tar.gz" 2>/dev/null || stat -f%z "deploy.tar.gz")
MB_SIZE=$((FILESIZE / 1024 / 1024))
echo ">> 打包完成,当前传输包大小: ${MB_SIZE} MB"
if [ "$MB_SIZE" -gt 50 ]; then
echo "⚠️ 警告:包体积仍大于 50MB可能存在未排除的大文件但继续执行..."
fi
# 3. 传输到生产环境的 /tmp 目录
echo "[3/4] 正在传输代码到服务器的临时目录..."
scp deploy.tar.gz $SERVER:/tmp/deploy.tar.gz
if [ $? -ne 0 ]; then
echo "❌ 传输失败!可能是网络中断,终止部署!"
rm -f deploy.tar.gz
exit 1
fi
# 4. 服务器执行替换与重启
echo "[4/4] 正在生产环境执行热更新 (全程免密)..."
ssh $SERVER "cd $REMOTE_DIR && \
echo '>> 移除历史旧目录...' && \
rm -rf inventory-backend_old inventory-web_old && \
echo '>> 备份当前目录为 old...' && \
(mv inventory-backend inventory-backend_old 2>/dev/null || true) && \
(mv inventory-web inventory-web_old 2>/dev/null || true) && \
echo '>> 部署新代码...' && \
mv /tmp/deploy.tar.gz . && \
tar -xzf deploy.tar.gz && \
echo '>> 重启 Docker 容器...' && \
docker compose -f docker-compose.prod.yml up -d --build backend frontend && \
echo '>> 验证 nginx 代理配置...' && \
sleep 5 && \
if docker exec inventory_ui_prod grep -q "inventory_api_prod" /etc/nginx/conf.d/default.conf; then \
echo '✅ nginx 代理已指向 inventory_api_prod'; \
else \
echo '⚠️ 警告: nginx 代理仍是 backend可能出现 /api/ 404请检查 nginx.conf'; \
fi && \
echo '>> 验证 API 连通性...' && \
API_CODE=$(curl -k -s -o /dev/null -w "%{http_code}" "https://localhost/api/inbound/base/units") && \
if [ "$API_CODE" = "404" ]; then \
echo '⚠️ 警告: API 返回 404代理可能指向了错误的容器'; \
else \
echo "✅ API 连通性正常 HTTP=$API_CODE"; \
fi && \
rm deploy.tar.gz"
if [ $? -ne 0 ]; then
echo "❌ 远端启动失败,请检查 Docker 日志!"
else
echo "==================================================="
echo "✅ 部署完美完成!请刷新网页查看效果。"
echo "==================================================="
fi
# 扫尾清理本地文件
rm -f deploy.tar.gz