You've already forked healthcheck
All checks were successful
Build and push Docker image / build (push) Successful in 31s
73 lines
1.7 KiB
JavaScript
73 lines
1.7 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_name) {
|
|
try {
|
|
const service = docker.getService(service_name)
|
|
await service.inspect()
|
|
const tasks = await docker.listTasks({ filters: { service: [service_name] } })
|
|
|
|
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' || (state === 'running' && !healthStatus)) {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
})
|
|
|
|
return isHealthy ? 200 : 503
|
|
} catch (error) {
|
|
console.error(error.message)
|
|
|
|
if (error.statusCode === 404) {
|
|
return 404
|
|
}
|
|
|
|
return 503
|
|
}
|
|
}
|
|
|
|
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)
|
|
res.sendStatus(statusCode)
|
|
})
|
|
|
|
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')) |