Async SSH for parallel status checks; Kuma 2 --base-path via CLI arg

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-01 17:13:38 +00:00
parent 32b4a98160
commit 8fdf3c8e4e
2 changed files with 12 additions and 9 deletions

View file

@ -3,8 +3,7 @@ services:
image: louislam/uptime-kuma:2 image: louislam/uptime-kuma:2
security_opt: security_opt:
- apparmor=unconfined - apparmor=unconfined
environment: command: ["node", "server/server.js", "--base-path=/monitor"]
- UPTIME_KUMA_BASE_PATH=/monitor
volumes: volumes:
- kuma_data:/app/data - kuma_data:/app/data
ports: ports:

View file

@ -1,8 +1,11 @@
import Fastify from 'fastify' import Fastify from 'fastify'
import crypto from 'crypto' import crypto from 'crypto'
import { execSync } from 'child_process' import { exec, execSync } from 'child_process'
import { promisify } from 'util'
import { deployMap } from '../deploy-map.js' import { deployMap } from '../deploy-map.js'
const execAsync = promisify(exec)
const app = Fastify({ logger: true }) const app = Fastify({ logger: true })
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET || '' const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET || ''
const SSH_KEY = process.env.SSH_KEY_PATH || '/root/.ssh/id_ed25519' const SSH_KEY = process.env.SSH_KEY_PATH || '/root/.ssh/id_ed25519'
@ -20,12 +23,13 @@ function verifySignature(body, signature) {
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature || '')) return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature || ''))
} }
function sshGet(host, cmd) { async function sshGet(host, cmd) {
try { try {
return execSync( const { stdout } = await execAsync(
`ssh -i ${SSH_KEY} -o StrictHostKeyChecking=no -o ConnectTimeout=5 root@${host} "${cmd}"`, `ssh -i ${SSH_KEY} -o StrictHostKeyChecking=no -o ConnectTimeout=2 root@${host} "${cmd}"`,
{ timeout: 15_000, encoding: 'utf8' } { timeout: 8_000 }
).trim() )
return stdout.trim()
} catch { } catch {
return null return null
} }
@ -49,7 +53,7 @@ async function refreshStatus(repo) {
if (!target) return null if (!target) return null
const [current, latest] = await Promise.all([ const [current, latest] = await Promise.all([
Promise.resolve(sshGet(target.host, `git -C ${target.path} rev-parse HEAD 2>/dev/null || echo not-deployed`)), sshGet(target.host, `git -C ${target.path} rev-parse HEAD 2>/dev/null || echo not-deployed`),
getForgejoCommit(repo), getForgejoCommit(repo),
]) ])