Files
healthcheck/server.js
zyxd 0100619c72
All checks were successful
Build and push Docker image / build (push) Successful in 49s
Добавлен маршрут / с кодом 200
2025-10-03 13:38:15 +04:00

100 lines
2.4 KiB
JavaScript

import express from 'express'
import Docker from 'dockerode'
const app = express()
const PORT = 8080
const docker = new Docker({ socketPath: '/var/run/docker.sock' })
async function getServiceStatusCode(service, node_id_or_name = null) {
try {
await docker.getService(service).inspect()
const filters = { service: [service] }
if (node_id_or_name) {
filters.node = [node_id_or_name]
}
const tasks = await docker.listTasks({ filters: filters })
if (tasks.length === 0) {
return 503
}
const isHealthy = tasks.some(task => {
const state = task.Status.State
const healthStatus = task.Status.ContainerStatus?.Health?.Status
if (healthStatus === 'healthy') {
return true
}
if (state === 'running' && !healthStatus) {
return true
}
return false
})
return isHealthy ? 200 : 503
} catch (error) {
console.error(`Error checking service ${service} (Node: ${node_id_or_name || 'All'}): ${error.message}`)
if (error.statusCode === 404) {
return 404
}
return 503
}
}
app.get('/health/:service/:node', async (req, res) => {
const service = req.params.service
const node = req.params.node
if (!service || !/^[a-zA-Z0-9_-]+$/.test(service)) {
return res.sendStatus(400)
}
if (!node || !/^[a-zA-Z0-9_-]+$/.test(node)) {
return res.sendStatus(400)
}
const statusCode = await getServiceStatusCode(service, node)
res.sendStatus(statusCode)
})
app.get('/health/:service', async (req, res) => {
const service = req.params.service
if (!service || !/^[a-zA-Z0-9_-]+$/.test(service)) {
return res.sendStatus(400)
}
const statusCode = await getServiceStatusCode(service, null)
res.sendStatus(statusCode)
})
app.get('/', (_, res) => res.sendStatus(200))
app.use((_, response) => response.sendStatus(404))
const server = app.listen(PORT, () => {
console.log(`@syncraft/healthcheck listening on port ${PORT}`)
})
const shutdown_handler = (signal) => {
console.log(`${signal} received. Initiating graceful shutdown.`)
server.close((error) => {
if (error) {
console.error('Error during HTTP server close:', error)
process.exit(1)
}
console.log('HTTP server closed. Exiting process.')
process.exit(0)
});
}
process.on('SIGTERM', () => shutdown_handler('SIGTERM'))
process.on('SIGINT', () => shutdown_handler('SIGINT'))