Review container health-check configuration

Check service health as well as whether its process is running.

Description

A container process can keep running while the service cannot handle requests. Without suitable health checks, these failures can go unnoticed. Dockerfile HEALTHCHECK can be used to mark container health as healthy or unhealthy.

An unhealthy status does not make Docker automatically restart the container. Kubernetes requires its own liveness, readiness and startup probes as needed, rather than using the image HEALTHCHECK.

Potential impact

  • An unresponsive service can appear to be running normally when only process state is observed.
  • Poorly designed checks or overly short timeouts can classify a working service as unhealthy.

Remediation

  • Configure the health checks used by the deployment environment to test actual service readiness or operation.
  • Verify that the check command runs inside the image, and tune startup time, timeouts and failure thresholds. Separately verify traffic-control and recovery behavior based on health.

Examples

The build context needs package.json, a lockfile and server.js. The after example assumes that /health returns HTTP 200 when healthy and uses Node’s built-in HTTP module.

Before

dockerfile
FROM node:22-alpine

WORKDIR /app
COPY . .
RUN npm ci
EXPOSE 3000
CMD ["node", "server.js"]

After

dockerfile
FROM node:22-alpine

WORKDIR /app
COPY . .
RUN npm ci
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=5s CMD node -e "require('http').get('http://127.0.0.1:3000/health', r => process.exit(r.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"
CMD ["node", "server.js"]

Explanation:

  • Before: No health check is declared in this Dockerfile. Also review any checks configured by the deployment environment.
  • After: The check calls /health every 30 seconds and fails on a non-200 response or connection error. Docker applies a five-second command timeout.

References