#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 快速检查服务器上静态资源是否存在 用于排查管理端 404 问题 """ import os import sys try: import paramiko except ImportError: print("请安装: pip install paramiko") sys.exit(1) # 配置(与 devlop.py 一致) DEPLOY_PROJECT_PATH = os.environ.get("DEPLOY_PROJECT_PATH", "/www/wwwroot/soul") DEVLOP_DIST_PATH = "/www/wwwroot/auto-devlop/soul/dist" DEFAULT_SSH_PORT = int(os.environ.get("DEPLOY_SSH_PORT", "22022")) def get_cfg(): return { "host": os.environ.get("DEPLOY_HOST", "42.194.232.22"), "user": os.environ.get("DEPLOY_USER", "root"), "password": os.environ.get("DEPLOY_PASSWORD", "Zhiqun1984"), "ssh_key": os.environ.get("DEPLOY_SSH_KEY", ""), "project_path": os.environ.get("DEPLOY_PROJECT_PATH", DEPLOY_PROJECT_PATH), } def check_static_files(): cfg = get_cfg() client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: print("正在连接服务器...") if cfg.get("ssh_key") and os.path.isfile(cfg["ssh_key"]): client.connect(cfg["host"], port=DEFAULT_SSH_PORT, username=cfg["user"], key_filename=cfg["ssh_key"], timeout=15) else: client.connect(cfg["host"], port=DEFAULT_SSH_PORT, username=cfg["user"], password=cfg["password"], timeout=15) print("\n=== 检查静态资源目录 ===") # 检查多个可能的路径(deploy 模式和 devlop 模式) checks = [ ("%s/.next/static" % DEVLOP_DIST_PATH, "devlop 模式 dist 目录"), ("%s/.next/static" % DEPLOY_PROJECT_PATH, "deploy 模式项目目录"), ("%s/server.js" % DEVLOP_DIST_PATH, "devlop server.js"), ("%s/server.js" % DEPLOY_PROJECT_PATH, "deploy server.js"), ] for path, desc in checks: # 检查文件或目录是否存在 cmd = "test -e '%s' && echo 'EXISTS' || echo 'NOT_FOUND'" % path stdin, stdout, stderr = client.exec_command(cmd, timeout=10) result = stdout.read().decode("utf-8", errors="replace").strip() status = "[OK]" if "EXISTS" in result else "[X]" print("%s %s" % (status, desc)) print(" 路径: %s" % path) if "EXISTS" in result and "static" in path: # 列出文件数量 cmd2 = "find '%s' -type f 2>/dev/null | wc -l" % path stdin2, stdout2, stderr2 = client.exec_command(cmd2, timeout=10) file_count = stdout2.read().decode("utf-8", errors="replace").strip() print(" 文件数: %s" % file_count) print("\n=== 检查 PM2 项目配置 ===") cmd = "pm2 describe soul 2>/dev/null | grep -E 'cwd|script|status' | head -5 || echo 'PM2 soul 不存在'" stdin, stdout, stderr = client.exec_command(cmd, timeout=10) pm2_info = stdout.read().decode("utf-8", errors="replace").strip() print(pm2_info) print("\n=== 检查端口监听 ===") cmd = "ss -tlnp | grep 30006 || echo '端口 30006 未监听'" stdin, stdout, stderr = client.exec_command(cmd, timeout=10) port_info = stdout.read().decode("utf-8", errors="replace").strip() print(port_info) print("\n=== 检查 Nginx 反向代理 ===") cmd = "grep -r 'proxy_pass' /www/server/panel/vhost/nginx/*soul* 2>/dev/null | head -3 || echo '未找到 soul Nginx 配置'" stdin, stdout, stderr = client.exec_command(cmd, timeout=10) nginx_info = stdout.read().decode("utf-8", errors="replace").strip() print(nginx_info) print("\n" + "=" * 50) print("诊断建议:") print("1. devlop 模式部署后,PM2 的 cwd 应为: %s" % DEVLOP_DIST_PATH) print("2. .next/static 必须在 PM2 的 cwd 目录下") print("3. Nginx 必须整站反代(location /),不能只反代 /api") print("4. 浏览器强刷: Ctrl+Shift+R 清除缓存") except Exception as e: print("错误: %s" % str(e)) import traceback traceback.print_exc() finally: client.close() if __name__ == "__main__": check_static_files()