A panel without VPN (e.g. after the move) can use a Prometheus that lives on a node, such as the one with history left on the old server (node #0). Both directions go through the agent's WSS: the node's Prometheus scrapes 127.0.0.1:AGENT_METRICS_PORT/metrics, the agent checks its token and asks core (metrics → metrics_res, the same exposition as /metrics, at most once per 5 s per connection); the monitor tab reads it back through the agent, which forwards only GET /-/ready and /api/v1/query[_range]. The panel finds it by itself (local first, then the lowest-id node), and the install/remove buttons work on a panel without VPN. `monitor install` on a node without its own panel picks AGENT_METRICS_PORT, writes it to cli.env and restarts the agent; on the old server it keeps the collected data. The panel works behind nginx in a subfolder: relative asset and API paths, relative directory redirects, and the client address from X-Forwarded-For / X-Real-IP only from trusted proxies (loopback, TRUST_PROXY). migrate import opens the moved SUB_PORT/NODE_PORT in UFW when it is active.
21 lines
943 B
TypeScript
21 lines
943 B
TypeScript
// Copyright (c) 2026 Ivan Vasilev
|
|
// This source code is licensed under the MIT license found in the
|
|
// LICENSE file in the root directory of this source tree.
|
|
import { StrictMode } from 'react';
|
|
import { createRoot } from 'react-dom/client';
|
|
import axios from 'axios';
|
|
import App from './App';
|
|
|
|
// Пути к API в коде пишутся от корня («/ui/nodes»), а уходят от адреса страницы («ui/nodes»):
|
|
// так панель за reverse-proxy в подпапке (example.com/forgetting/) ходит в свой префикс, а в корне
|
|
// всё как раньше. Одно место на все запросы, включая будущие.
|
|
axios.interceptors.request.use(c => {
|
|
if (c.url?.startsWith('/') && !c.url.startsWith('//')) c.url = c.url.slice(1);
|
|
return c;
|
|
});
|
|
|
|
createRoot(document.getElementById('root')!).render(
|
|
<StrictMode>
|
|
<App />
|
|
</StrictMode>
|
|
); |