Skip to content

Add git_sha and build_timestamp to Next.js healthcheck endpoint and wire K8s probes #3197

@blarghmatey

Description

@blarghmatey

Description/Context

The Next.js frontend (frontends/main) already has a health endpoint at src/app/healthcheck/route.ts that returns { status, version, timestamp } using the NEXT_PUBLIC_VERSION build arg. However it is missing git_sha and build_timestamp fields, which are needed to:

  1. Align the response shape with the Django backend's ol_django.health endpoint (ol-django#436) so monitoring and release pipeline tooling can query either service with the same field names
  2. Enable the Concourse post-deploy verification step to confirm git_sha and build_timestamp in addition to the version string
  3. Give the release pipeline a more precise signal — version alone can collide if a release is re-built; git SHA is unambiguous

Additionally, the Dockerfile.web does not currently pass GIT_SHA or BUILD_TIMESTAMP as build args, and there is no K8s probe configuration pointing at /healthcheck in the deployment manifests.

Part of the release management modernization: mitodl/hq#7185.

Plan/Design

1. Update frontends/main/Dockerfile.web

Add GIT_SHA and BUILD_TIMESTAMP as build args alongside the existing NEXT_PUBLIC_VERSION:

ARG GIT_SHA
ENV GIT_SHA=$GIT_SHA

ARG BUILD_TIMESTAMP
ENV BUILD_TIMESTAMP=$BUILD_TIMESTAMP

Note: these do NOT use the NEXT_PUBLIC_ prefix — they are server-only values consumed only by the Route Handler, not exposed to the browser bundle.

2. Update src/app/healthcheck/route.ts

Extend the existing handler to include the new fields and align field names with the Django backend:

const VERSION = process.env.NEXT_PUBLIC_VERSION ?? "unknown"
const GIT_SHA = process.env.GIT_SHA ?? "unknown"
const BUILD_TIMESTAMP = process.env.BUILD_TIMESTAMP ?? "unknown"

export async function GET() {
  return Response.json(
    {
      status: "ok",
      version: VERSION,
      git_sha: GIT_SHA,
      build_timestamp: BUILD_TIMESTAMP,
      timestamp: new Date().toISOString(),
    },
    { status: 200 },
  )
}

3. Update Concourse build step (in ol-infrastructure)

The Concourse image build step for the Next.js image should pass the new args:

- put: oci-image-frontend
  params:
    build: source
    dockerfile: source/frontends/main/Dockerfile.web
    build_args:
      NEXT_PUBLIC_VERSION: ((.:version))
      GIT_SHA: ((.:git_sha))
      BUILD_TIMESTAMP: ((.:build_timestamp))

These values are written to the workspace by get: release (ol-concourse#13).

4. K8s probe configuration

Update the Next.js K8s Deployment manifest in ol-infrastructure to use /healthcheck for liveness and readiness probes:

livenessProbe:
  httpGet:
    path: /healthcheck
    port: 3000
  initialDelaySeconds: 10
  periodSeconds: 15
readinessProbe:
  httpGet:
    path: /healthcheck
    port: 3000
  initialDelaySeconds: 5
  periodSeconds: 10

Consistent response shape across both services

Field Django /health/?format=json Next.js /healthcheck
version "2025.04.14.1" "2025.04.14.1"
git_sha "a3f9c12" "a3f9c12"
build_timestamp "2025-04-14T10:22:00Z" "2025-04-14T10:22:00Z"
timestamp (not present) "2025-04-14T15:00:00Z" (response time)
HTTP status on healthy 200 200
HTTP status on degraded 500 200 (Next.js has no service deps to check)

The timestamp field (current response time) is unique to the Next.js endpoint and is already present — it helps confirm the response is live and not a cached CDN response.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions