Docker images / prepare-release (push) Successful in 12s
Docker images / backend-test (push) Successful in 4m9s
Docker images / frontend-image (push) Successful in 4m28s
Docker images / updater-image (push) Successful in 58s
Docker images / backend-image (push) Successful in 2m49s
Docker images / notify-webhook (push) Skipped
Docker images / publish-release (push) Successful in 11s
При старте backend накатывает схему PostgreSQL 18 и, если база пустая, один раз импортирует mikrotik.db с тома. Повторный старт не копирует данные. Бэкап в UI идёт через pg_dump. Co-authored-by: Cursor <[email protected]>
114 lines
4.0 KiB
TypeScript
114 lines
4.0 KiB
TypeScript
import { generateNativeConf } from "./wireguard-config.js"
|
|
import { getTrafficFlowSettingsRow, listHostPeers } from "./traffic-flow-settings.js"
|
|
import type { TrafficFlowHostFile } from "@mmapp/contracts/traffic-flow"
|
|
|
|
const COMPOSE_DIR = "/opt/cdn-mm"
|
|
|
|
export async function buildHostWgQuickConf(): Promise<string> {
|
|
const row = await getTrafficFlowSettingsRow()
|
|
const peers = await listHostPeers()
|
|
return generateNativeConf({
|
|
name: "wg-flow",
|
|
mtu: 1420,
|
|
privateKey: row.hostPrivateKey || undefined,
|
|
address: `${row.collectorIp}/24`,
|
|
comment: "MikrotikManager traffic-flow collector",
|
|
peers: peers.map((p) => ({
|
|
publicKey: p.publicKey,
|
|
allowedIps: p.allowedIps,
|
|
comment: p.name,
|
|
endpoint: p.endpoint,
|
|
persistentKeepalive: p.endpoint ? 25 : undefined,
|
|
})),
|
|
})
|
|
}
|
|
|
|
export async function buildHostComposeOverride(): Promise<string> {
|
|
const row = await getTrafficFlowSettingsRow()
|
|
return [
|
|
"# Docker Compose merge для /opt/cdn-mm",
|
|
"# Не править docker-compose.yml. Traefik не трогать.",
|
|
"# Сначала: wg-quick up wg-flow (адрес " + row.collectorIp + ")",
|
|
"# затем: docker compose up -d --force-recreate backend",
|
|
"# Docker userland-proxy может SNAT UDP source в 172.x — ingest сопоставит единственный JH.",
|
|
"",
|
|
"services:",
|
|
" backend:",
|
|
" environment:",
|
|
" FLOW_LISTEN_HOST: \"0.0.0.0\"",
|
|
" ports:",
|
|
` - "${row.collectorIp}:${row.flowListenPort}:${row.flowListenPort}/udp"`,
|
|
"",
|
|
].join("\n")
|
|
}
|
|
|
|
export async function buildHostLinuxInstallSh(): Promise<string> {
|
|
const row = await getTrafficFlowSettingsRow()
|
|
const conf = (await buildHostWgQuickConf()).replace(/\s+$/, "") + "\n"
|
|
const override = await buildHostComposeOverride()
|
|
const collector = row.collectorIp
|
|
const flowPort = row.flowListenPort
|
|
|
|
return `#!/usr/bin/env bash
|
|
# WG-клиент на хосте /opt/cdn-mm → JH:13232, IPFIX в контейнер backend.
|
|
# Запуск: sudo bash install-wg-flow.sh
|
|
set -euo pipefail
|
|
|
|
if [[ \${EUID:-$(id -u)} -ne 0 ]]; then
|
|
echo "Запустите от root: sudo bash $0" >&2
|
|
exit 1
|
|
fi
|
|
|
|
COLLECTOR_IP="${collector}"
|
|
FLOW_PORT="${flowPort}"
|
|
COMPOSE_DIR="${COMPOSE_DIR}"
|
|
|
|
if ! command -v wg >/dev/null 2>&1; then
|
|
apt-get update
|
|
DEBIAN_FRONTEND=noninteractive apt-get install -y wireguard
|
|
fi
|
|
|
|
install -d -m 700 /etc/wireguard
|
|
cat > /etc/wireguard/wg-flow.conf <<'WGEOF'
|
|
${conf}WGEOF
|
|
chmod 600 /etc/wireguard/wg-flow.conf
|
|
|
|
systemctl enable --now wg-quick@wg-flow
|
|
echo "=== wg show wg-flow ==="
|
|
wg show wg-flow
|
|
echo "=== адрес (ожидаем \${COLLECTOR_IP}/24) ==="
|
|
ip -4 addr show dev wg-flow
|
|
|
|
if [[ ! -d "\$COMPOSE_DIR" ]]; then
|
|
echo "Нет \$COMPOSE_DIR — положите override.yml туда вручную (вкладка compose)." >&2
|
|
exit 1
|
|
fi
|
|
|
|
cat > "\$COMPOSE_DIR/docker-compose.override.yml" <<'OVEOF'
|
|
${override}OVEOF
|
|
|
|
cd "\$COMPOSE_DIR"
|
|
docker compose up -d --force-recreate backend
|
|
|
|
echo "=== UDP \${FLOW_PORT} на хосте (ожидаем \${COLLECTOR_IP}:\${FLOW_PORT} docker-proxy) ==="
|
|
ss -ulnp | grep -E "\${FLOW_PORT}" || true
|
|
echo "=== PortBindings mmapp-backend ==="
|
|
docker inspect -f '{{json .HostConfig.PortBindings}}' mmapp-backend
|
|
echo "=== handshake (keepalive 25s к JH:13232) ==="
|
|
wg show wg-flow
|
|
|
|
# nft на хосте MM не трогаем. Bind только на COLLECTOR_IP, не 0.0.0.0.
|
|
# Если backend стартовал до wg-flow: docker compose up -d --force-recreate backend
|
|
|
|
echo "Готово. Traefik не трогали. UDP \${FLOW_PORT} только на \${COLLECTOR_IP}, не на 0.0.0.0."
|
|
`
|
|
}
|
|
|
|
export async function listTrafficFlowHostFiles(): Promise<TrafficFlowHostFile[]> {
|
|
return [
|
|
{ id: "linux", label: "Linux", filename: "install-wg-flow.sh", code: await buildHostLinuxInstallSh() },
|
|
{ id: "wg-quick", label: "wg-flow.conf", filename: "wg-flow.conf", code: await buildHostWgQuickConf() },
|
|
{ id: "compose", label: "compose", filename: "docker-compose.override.yml", code: await buildHostComposeOverride() },
|
|
]
|
|
}
|