const http = require("http"); const { spawn } = require("child_process"); const PORT = process.env.PORT || 3000; const DASH_PORT = 8000; // 1) Устанавливаем Python-зависимости (идемпотентно) function setupDeps() { return new Promise((resolve) => { const py = spawn("python3", ["-m", "pip", "install", "--break-system-packages", "-q", "-r", "requirements.txt"], { cwd: __dirname, stdio: "pipe" }); py.stdout.on("data", () => {}); py.stderr.on("data", (d) => console.error("[setup]", d.toString().trim())); py.on("close", (code) => { console.log(`[setup] pip exit ${code}`); resolve(); }); }); } setupDeps().then(startProxy); async function startProxy() { // 2) Запускаем Python-дашборд const py = spawn("python3", ["-m", "src.dashboard.run"], { cwd: __dirname, stdio: "inherit", env: { ...process.env, PORT: String(DASH_PORT), DASHBOARD_HOST: "0.0.0.0" } }); py.on("error", (e) => { console.error("[proxy]", e.message); process.exit(1); }); const proxy = http.createServer((req, res) => { const opts = { host: "127.0.0.1", port: DASH_PORT, path: req.url, method: req.method, headers: { ...req.headers, host: `127.0.0.1:${DASH_PORT}` } }; const up = http.request(opts, (upRes) => { res.writeHead(upRes.statusCode, upRes.headers); upRes.pipe(res); }); up.on("error", () => { res.writeHead(502); res.end("Dashboard booting… retry in 2s"); }); req.pipe(up); }); proxy.listen(PORT, () => console.log(`[proxy] ${PORT} → ${DASH_PORT}`)); function shutdown() { py.kill("SIGTERM"); proxy.close(() => process.exit(0)); setTimeout(() => process.exit(0), 2000).unref(); } process.on("SIGTERM", shutdown); process.on("SIGINT", shutdown); }