176 lines
5.6 KiB
Python
176 lines
5.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
部署系统到远程服务器 159.75.81.121
|
|
"""
|
|
import os
|
|
import tarfile
|
|
import paramiko
|
|
import time
|
|
|
|
SERVER_IP = "159.75.81.121"
|
|
SSH_PORT = 22
|
|
SSH_USER = "root"
|
|
SSH_PASS = "sp-cc123"
|
|
REMOTE_DIR = "/opt/risk_system"
|
|
DOMAIN = "risk.aiformat.cn"
|
|
|
|
LOCAL_BASE = r"d:\code\XH-202626_科创企业特有风险的识别与管理"
|
|
ARCHIVE_NAME = os.path.join(LOCAL_BASE, "deploy_package.tar.gz")
|
|
|
|
def make_archive():
|
|
print("📦 正在打部署压缩包...")
|
|
includes = [
|
|
"🏠_系统首页.py",
|
|
"app.py",
|
|
"config.py",
|
|
"requirements.txt",
|
|
"agents",
|
|
"collectors",
|
|
"data",
|
|
"knowledge_graph",
|
|
"lib",
|
|
"pages",
|
|
"risk_engine",
|
|
"utils",
|
|
".streamlit"
|
|
]
|
|
|
|
with tarfile.open(ARCHIVE_NAME, "w:gz") as tar:
|
|
for item in includes:
|
|
full_path = os.path.join(LOCAL_BASE, item)
|
|
if os.path.exists(full_path):
|
|
print(f" + 打包: {item}")
|
|
tar.add(full_path, arcname=item)
|
|
else:
|
|
print(f" - 跳过(不存在): {item}")
|
|
print(f"✅ 压缩完成: {ARCHIVE_NAME}")
|
|
|
|
def run_remote_cmd(ssh, cmd):
|
|
print(f"\n🚀 [远程命令] {cmd}")
|
|
stdin, stdout, stderr = ssh.exec_command(cmd)
|
|
out = stdout.read().decode('utf-8', errors='ignore')
|
|
err = stderr.read().decode('utf-8', errors='ignore')
|
|
if out:
|
|
print(f"[STDOUT]\n{out.strip()}")
|
|
if err:
|
|
print(f"[STDERR]\n{err.strip()}")
|
|
return out, err
|
|
|
|
def deploy():
|
|
make_archive()
|
|
|
|
print(f"\n🔌 正在连接服务器 {SERVER_IP}...")
|
|
ssh = paramiko.SSHClient()
|
|
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
try:
|
|
ssh.connect(SERVER_IP, port=SSH_PORT, username=SSH_USER, password=SSH_PASS, timeout=15)
|
|
print("✅ SSH 连接成功!")
|
|
except Exception as e:
|
|
print(f"❌ SSH 连接失败: {e}")
|
|
return
|
|
|
|
sftp = ssh.open_sftp()
|
|
|
|
# 1. 创建远程目录
|
|
run_remote_cmd(ssh, f"mkdir -p {REMOTE_DIR}")
|
|
|
|
# 2. 上传压缩包
|
|
remote_archive = f"{REMOTE_DIR}/deploy_package.tar.gz"
|
|
print(f"📤 正在上传压缩包到 {remote_archive}...")
|
|
sftp.put(ARCHIVE_NAME, remote_archive)
|
|
print("✅ 压缩包上传成功!")
|
|
sftp.close()
|
|
|
|
# 3. 解压并配置 Python 环境与依赖
|
|
run_remote_cmd(ssh, f"cd {REMOTE_DIR} && tar -xzf deploy_package.tar.gz")
|
|
|
|
# 检查并安装系统依赖 (nginx, python3, python3-pip, python3-venv 等)
|
|
setup_env_cmd = """
|
|
if command -v apt-get &> /dev/null; then
|
|
apt-get update -y && apt-get install -y python3 python3-pip python3-venv nginx
|
|
elif command -v yum &> /dev/null; then
|
|
yum install -y python3 python3-pip nginx
|
|
fi
|
|
"""
|
|
run_remote_cmd(ssh, setup_env_cmd)
|
|
|
|
# 创建 virtualenv 并安装依赖
|
|
venv_cmd = f"""
|
|
cd {REMOTE_DIR}
|
|
python3 -m venv venv || python3 -m venv venv --without-pip
|
|
source venv/bin/activate
|
|
pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple
|
|
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
|
|
"""
|
|
run_remote_cmd(ssh, venv_cmd)
|
|
|
|
# 4. 配置 Systemd 服务
|
|
systemd_service = f"""[Unit]
|
|
Description=Risk Management Streamlit Web App
|
|
After=network.target
|
|
|
|
[Service]
|
|
User=root
|
|
WorkingDirectory={REMOTE_DIR}
|
|
ExecStart={REMOTE_DIR}/venv/bin/streamlit run {REMOTE_DIR}/🏠_系统首页.py --server.port 8501 --server.address 127.0.0.1 --server.headless true --server.enableCORS false --server.enableXsrfProtection false
|
|
Restart=always
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
"""
|
|
create_service_cmd = f"cat << 'EOF' > /etc/systemd/system/risk_app.service\n{systemd_service}\nEOF"
|
|
run_remote_cmd(ssh, create_service_cmd)
|
|
|
|
run_remote_cmd(ssh, "systemctl daemon-reload && systemctl enable risk_app && systemctl restart risk_app")
|
|
time.sleep(3)
|
|
run_remote_cmd(ssh, "systemctl status risk_app --no-pager")
|
|
|
|
# 5. 配置 Nginx 反向代理
|
|
nginx_conf = f"""server {{
|
|
listen 80;
|
|
server_name {DOMAIN};
|
|
|
|
location / {{
|
|
proxy_pass http://127.0.0.1:8501;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_read_timeout 86400;
|
|
}}
|
|
|
|
location /_stcore/stream {{
|
|
proxy_pass http://127.0.0.1:8501/_stcore/stream;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
}}
|
|
}}
|
|
"""
|
|
create_nginx_cmd = f"cat << 'EOF' > /etc/nginx/conf.d/risk.aiformat.cn.conf\n{nginx_conf}\nEOF"
|
|
run_remote_cmd(ssh, create_nginx_cmd)
|
|
|
|
# 兼容 Ubuntu/Debian sites-enabled
|
|
run_remote_cmd(ssh, f"mkdir -p /etc/nginx/sites-enabled && ln -sf /etc/nginx/conf.d/risk.aiformat.cn.conf /etc/nginx/sites-enabled/risk.aiformat.cn.conf")
|
|
|
|
run_remote_cmd(ssh, "nginx -t && systemctl restart nginx")
|
|
time.sleep(2)
|
|
run_remote_cmd(ssh, "systemctl status nginx --no-pager")
|
|
|
|
# 6. 测试应用连通性
|
|
run_remote_cmd(ssh, "curl -I http://127.0.0.1:8501")
|
|
run_remote_cmd(ssh, f"curl -H 'Host: {DOMAIN}' -I http://127.0.0.1/")
|
|
|
|
ssh.close()
|
|
print("\n🎉 部署完成!")
|
|
print(f"🌐 域名访问地址: http://{DOMAIN}")
|
|
print(f"🖥️ 服务器 IP 直连防护端口验证: http://{SERVER_IP}")
|
|
|
|
if __name__ == "__main__":
|
|
deploy()
|