Start nav-site in background when pm2 and systemd are unavailable.
Fall back to a pid-file background process after deploy, and detect running state via HTTP port checks in the management menu. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+50
-5
@@ -14,6 +14,14 @@ import sys
|
||||
import time
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
from nav_common import (
|
||||
get_nav_port,
|
||||
http_ready,
|
||||
is_process_running,
|
||||
pid_file_path,
|
||||
read_background_pid,
|
||||
stop_background_process,
|
||||
)
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
@@ -239,6 +247,40 @@ def wait_for_http(port: str, timeout: float = 15.0) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def start_background_process(port: str) -> str | None:
|
||||
"""无 pm2/systemd 时,用 venv python 后台启动并记录 pid。"""
|
||||
py = venv_python()
|
||||
if not Path(py).is_file():
|
||||
return None
|
||||
|
||||
old_pid = read_background_pid(ROOT)
|
||||
if old_pid and is_process_running(old_pid):
|
||||
if http_ready(port, timeout=3):
|
||||
return f"后台进程已在运行 pid={old_pid}"
|
||||
|
||||
if old_pid and is_process_running(old_pid):
|
||||
stop_background_process(ROOT)
|
||||
|
||||
ensure_logs_dir()
|
||||
log_file = ROOT / "logs" / "nav-site.log"
|
||||
pid_file = pid_file_path(ROOT)
|
||||
|
||||
with open(log_file, "ab") as log:
|
||||
proc = subprocess.Popen(
|
||||
[py, str(ROOT / "app.py")],
|
||||
cwd=ROOT,
|
||||
stdout=log,
|
||||
stderr=subprocess.STDOUT,
|
||||
start_new_session=True,
|
||||
)
|
||||
pid_file.write_text(str(proc.pid), encoding="utf-8")
|
||||
|
||||
if wait_for_http(port):
|
||||
return f"后台启动 pid={proc.pid}(日志 logs/nav-site.log)"
|
||||
_warn(f"后台进程已启动 pid={proc.pid},但 :{port} 暂未响应,请查看 logs/nav-site.log")
|
||||
return f"后台启动 pid={proc.pid}"
|
||||
|
||||
|
||||
def start_service(port: str) -> str | None:
|
||||
"""尝试自动启动服务,返回启动方式描述;失败返回 None。"""
|
||||
ensure_logs_dir()
|
||||
@@ -274,11 +316,11 @@ def start_service(port: str) -> str | None:
|
||||
_warn("systemd 已启动 nav-site,但健康检查未通过,请执行 journalctl -u nav-site 排查")
|
||||
return "systemctl enable --now nav-site"
|
||||
|
||||
return None
|
||||
return start_background_process(port)
|
||||
|
||||
|
||||
def print_summary(started_via: str | None = None) -> None:
|
||||
port = os.environ.get("NAV_PORT", "5070")
|
||||
port = get_nav_port(ROOT)
|
||||
print()
|
||||
print("=" * 50)
|
||||
print("部署完成")
|
||||
@@ -288,12 +330,15 @@ def print_summary(started_via: str | None = None) -> None:
|
||||
print()
|
||||
if started_via:
|
||||
print(f" 服务状态: 已自动启动({started_via})")
|
||||
if shutil.which("pm2"):
|
||||
if shutil.which("pm2") and "pm2" in started_via:
|
||||
print(" 查看状态: pm2 status")
|
||||
print(" 查看日志: pm2 logs nav-site")
|
||||
print(" 开机自启: pm2 save && pm2 startup # 按提示执行一次 sudo 命令")
|
||||
elif "后台" in started_via:
|
||||
print(" 查看日志: tail -f logs/nav-site.log")
|
||||
print(" 建议生产环境安装 pm2 以便守护与开机自启")
|
||||
else:
|
||||
print(" 服务状态: 未自动启动(未检测到 pm2 / systemd nav-site)")
|
||||
print(" 服务状态: 未自动启动")
|
||||
print(" 手动启动:")
|
||||
print(f" {venv_python()} app.py")
|
||||
if shutil.which("pm2"):
|
||||
@@ -333,7 +378,7 @@ def main() -> None:
|
||||
|
||||
started_via = None
|
||||
if not args.no_start:
|
||||
port = os.environ.get("NAV_PORT", "5070")
|
||||
port = get_nav_port(ROOT)
|
||||
try:
|
||||
started_via = start_service(port)
|
||||
if started_via:
|
||||
|
||||
Reference in New Issue
Block a user