feat: v0.4.0 — Apache service stack, shell access, log viewer, changelog
Service stack (backend): - webserver.ts rewritten: apache2/php-fpm routes replacing nginx; per-account Apache log endpoint; PHP-FPM reload per version; apache2ctl configtest/reload - accounts.ts: added PUT /:id/shell to toggle /bin/bash vs /usr/sbin/nologin, runs usermod -s and writes audit log New UI features (nixserver): - ShellAccess page: grant/revoke SSH access per account via AccountPicker - ApacheLogs page: live log viewer (access/error) per account; replaces stub - NginxLogs: re-exports ApacheLogs (NixPanel uses Apache, not NGINX) - WebServer page: shows apache2, php8.2-fpm, php8.3-fpm status with reload buttons; config test; Apache log viewer Bug fixes: - Accounts.tsx: Lucide icon size prop type widened (string|number); removed unused Users import; dropped duplicate NGINX log card - Removed soon badge from ShellAccess and ApacheLogs entries Project: - CHANGELOG.md created with full history from 0.2.x through 0.4.0 - All packages bumped from 0.3.2 to 0.4.0
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import cron from 'node-cron'
|
||||
import { checkAll } from './core/monitor.js'
|
||||
import { closePool } from './core/mariadb.js'
|
||||
|
||||
let started = false
|
||||
|
||||
export function startScheduler(): void {
|
||||
if (started) return
|
||||
started = true
|
||||
|
||||
// Service health monitor — every 5 minutes
|
||||
cron.schedule('*/5 * * * *', async () => {
|
||||
try {
|
||||
await checkAll()
|
||||
} catch (err) {
|
||||
console.error('[scheduler] monitor.checkAll error:', err)
|
||||
}
|
||||
})
|
||||
|
||||
// SSL renewal check — daily at 3am
|
||||
cron.schedule('0 3 * * *', async () => {
|
||||
try {
|
||||
const { renewExpiring } = await import('./core/ssl.js')
|
||||
await renewExpiring()
|
||||
} catch (err) {
|
||||
console.error('[scheduler] ssl.renewExpiring error:', err)
|
||||
}
|
||||
})
|
||||
|
||||
// Disk usage stats — every 15 minutes
|
||||
cron.schedule('*/15 * * * *', async () => {
|
||||
try {
|
||||
const { collectDiskUsage } = await import('./core/stats.js')
|
||||
await collectDiskUsage()
|
||||
} catch (err) {
|
||||
console.error('[scheduler] stats.collectDiskUsage error:', err)
|
||||
}
|
||||
})
|
||||
|
||||
// License heartbeat — every 6 hours
|
||||
cron.schedule('0 */6 * * *', async () => {
|
||||
try {
|
||||
const { heartbeat } = await import('./core/license.js')
|
||||
await heartbeat()
|
||||
} catch (err) {
|
||||
console.error('[scheduler] license.heartbeat error:', err)
|
||||
}
|
||||
})
|
||||
|
||||
// Bandwidth reset — 1st of every month at 00:05
|
||||
cron.schedule('5 0 1 * *', async () => {
|
||||
try {
|
||||
const { resetMonthlyBandwidth } = await import('./core/stats.js')
|
||||
await resetMonthlyBandwidth()
|
||||
} catch (err) {
|
||||
console.error('[scheduler] stats.resetMonthlyBandwidth error:', err)
|
||||
}
|
||||
})
|
||||
|
||||
console.log('[scheduler] Background jobs started')
|
||||
}
|
||||
|
||||
export async function stopScheduler(): Promise<void> {
|
||||
await closePool()
|
||||
}
|
||||
Reference in New Issue
Block a user