feat: initial health-app with Express API and GitOps CI/CD
Node.js Express app with /health, /ready, / endpoints. Multi-stage Dockerfile, GitHub Actions pipeline for GHCR push and gitops-infra manifest auto-update. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
52
src/server.js
Normal file
52
src/server.js
Normal file
@@ -0,0 +1,52 @@
|
||||
"use strict";
|
||||
|
||||
const express = require("express");
|
||||
|
||||
const app = express();
|
||||
const PORT = parseInt(process.env.PORT, 10) || 3000;
|
||||
const startTime = Date.now();
|
||||
|
||||
app.disable("x-powered-by");
|
||||
|
||||
app.get("/", (_req, res) => {
|
||||
res.json({
|
||||
service: "health-app",
|
||||
version: process.env.APP_VERSION || "1.0.0",
|
||||
environment: process.env.NODE_ENV || "development",
|
||||
});
|
||||
});
|
||||
|
||||
app.get("/health", (_req, res) => {
|
||||
res.json({
|
||||
status: "healthy",
|
||||
uptime: Math.floor((Date.now() - startTime) / 1000),
|
||||
timestamp: new Date().toISOString(),
|
||||
memoryUsage: process.memoryUsage().rss,
|
||||
});
|
||||
});
|
||||
|
||||
app.get("/ready", (_req, res) => {
|
||||
res.json({ ready: true });
|
||||
});
|
||||
|
||||
app.use((_req, res) => {
|
||||
res.status(404).json({ error: "Not Found" });
|
||||
});
|
||||
|
||||
app.use((err, _req, res, _next) => {
|
||||
console.error("Unhandled error:", err.message);
|
||||
res.status(500).json({ error: "Internal Server Error" });
|
||||
});
|
||||
|
||||
const server = app.listen(PORT, "0.0.0.0", () => {
|
||||
console.log(`health-app listening on port ${PORT}`);
|
||||
});
|
||||
|
||||
function shutdown(signal) {
|
||||
console.log(`${signal} received, shutting down gracefully`);
|
||||
server.close(() => process.exit(0));
|
||||
setTimeout(() => process.exit(1), 10000);
|
||||
}
|
||||
|
||||
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
||||
process.on("SIGINT", () => shutdown("SIGINT"));
|
||||
Reference in New Issue
Block a user