Files
soul/开发文档/服务器管理/scripts/一键部署.py

139 lines
5.0 KiB
Python
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 python3
# -*- coding: utf-8 -*-
"""
一键部署脚本
============
用途根据配置文件一键部署Node项目到宝塔服务器
使用方法:
python3 一键部署.py 项目名称 本地项目路径
示例:
python3 一键部署.py soul /Users/karuo/Documents/开发/3、自营项目/一场soul的创业实验
"""
import sys
import os
import subprocess
import time
# 默认服务器配置
默认配置 = {
"服务器IP": "42.194.232.22",
"SSH用户": "root",
"SSH密码": "Zhiqun1984",
"服务器根目录": "/www/wwwroot"
}
def 执行命令(命令: str, 显示输出: bool = True) -> tuple:
"""执行shell命令"""
result = subprocess.run(命令, shell=True, capture_output=True, text=True)
if 显示输出 and result.stdout:
print(result.stdout)
if result.stderr and "Warning" not in result.stderr:
print(f"错误: {result.stderr}")
return result.returncode, result.stdout
def 部署项目(项目名称: str, 本地路径: str):
"""执行部署流程"""
服务器路径 = f"{默认配置['服务器根目录']}/{项目名称}"
压缩文件 = f"/tmp/{项目名称}_update.tar.gz"
print(f"\n{'='*60}")
print(f"开始部署: {项目名称}")
print(f"本地路径: {本地路径}")
print(f"服务器路径: {服务器路径}")
print(f"{'='*60}\n")
# 步骤1: 压缩项目
print("📦 步骤1: 压缩项目文件...")
排除项 = "--exclude='node_modules' --exclude='.next' --exclude='.git' --exclude='android' --exclude='out'"
压缩命令 = f"cd '{本地路径}' && tar {排除项} -czf {压缩文件} ."
code, _ = 执行命令(压缩命令, False)
if code != 0:
print("❌ 压缩失败")
return False
# 获取文件大小
大小 = os.path.getsize(压缩文件) / 1024 / 1024
print(f" ✅ 压缩完成,大小: {大小:.2f} MB")
# 步骤2: 上传到服务器
print("\n📤 步骤2: 上传到服务器...")
上传命令 = f"sshpass -p '{默认配置['SSH密码']}' scp -o StrictHostKeyChecking=no {压缩文件} {默认配置['SSH用户']}@{默认配置['服务器IP']}:/tmp/"
code, _ = 执行命令(上传命令, False)
if code != 0:
print("❌ 上传失败")
return False
print(" ✅ 上传完成")
# 步骤3-6: SSH远程执行
print("\n🔧 步骤3-6: 服务器端操作...")
SSH前缀 = f"sshpass -p '{默认配置['SSH密码']}' ssh -o StrictHostKeyChecking=no {默认配置['SSH用户']}@{默认配置['服务器IP']}"
# 清理旧文件
清理命令 = f"{SSH前缀} 'cd {服务器路径} && rm -rf app components lib public styles *.json *.js *.ts *.mjs *.md .next 2>/dev/null || true'"
执行命令(清理命令, False)
print(" ✅ 清理旧文件")
# 解压
解压命令 = f"{SSH前缀} 'cd {服务器路径} && tar -xzf /tmp/{项目名称}_update.tar.gz'"
执行命令(解压命令, False)
print(" ✅ 解压新代码")
# 安装依赖
print("\n📚 安装依赖 (这可能需要几分钟)...")
安装命令 = f"{SSH前缀} 'export PATH=/www/server/nodejs/v22.14.0/bin:$PATH && cd {服务器路径} && npm install --legacy-peer-deps 2>&1'"
执行命令(安装命令, True)
# 构建
print("\n🏗️ 构建项目...")
构建命令 = f"{SSH前缀} 'export PATH=/www/server/nodejs/v22.14.0/bin:$PATH && cd {服务器路径} && npm run build 2>&1'"
执行命令(构建命令, True)
# 重启PM2
print("\n🔄 重启服务...")
重启命令 = f"{SSH前缀} 'export PATH=/www/server/nodejs/v22.14.0/bin:$PATH && pm2 restart {项目名称} 2>&1'"
执行命令(重启命令, True)
# 清理临时文件
清理临时命令 = f"{SSH前缀} 'rm -f /tmp/{项目名称}_update.tar.gz'"
执行命令(清理临时命令, False)
os.remove(压缩文件)
print(f"\n{'='*60}")
print("✅ 部署完成!")
print(f"{'='*60}")
print("\n⚠️ 请在宝塔面板手动重启项目:")
print(f" 1. 登录 https://42.194.232.22:9988/ckbpanel")
print(f" 2. 进入【网站】→【Node项目】")
print(f" 3. 找到 {项目名称},点击【重启】")
return True
def main():
if len(sys.argv) < 3:
print("用法: python3 一键部署.py <项目名称> <本地项目路径>")
print("\n示例:")
print(" python3 一键部署.py soul /Users/karuo/Documents/开发/3、自营项目/一场soul的创业实验")
print(" python3 一键部署.py kr_wb /Users/karuo/Documents/开发/4、小工具/whiteboard")
sys.exit(1)
项目名称 = sys.argv[1]
本地路径 = sys.argv[2]
if not os.path.exists(本地路径):
print(f"❌ 本地路径不存在: {本地路径}")
sys.exit(1)
确认 = input(f"\n确认部署 {项目名称} 到服务器? (y/n): ")
if 确认.lower() != 'y':
print("已取消部署")
sys.exit(0)
部署项目(项目名称, 本地路径)
if __name__ == "__main__":
main()