Skip to main content
Now that Prometheus is monitoring the Kubernetes infrastructure and cluster endpoints are reachable, this lesson shows how to instrument and deploy a simple application so Prometheus (installed via the Prometheus Operator) can scrape its metrics. We’ll deploy a Node.js Express demo app that exposes a few HTTP endpoints and Prometheus-style metrics via the swagger-stats middleware. The app listens on port 3000 and serves metrics at /swagger-stats/metrics — the path Prometheus should scrape.
Prometheus scrapes an HTTP metrics endpoint. In this example the application exposes metrics at /swagger-stats/metrics. Configure Prometheus (or create a ServiceMonitor) to scrape that path on the Service that fronts this application.

Application code

Below is the Node.js application (index.js). It uses swagger-stats to expose Prometheus-compatible metrics and provides a few simple endpoints you can test.
Key points:
  • The app serves simple responses at /, /comments, /threads, and /replies.
  • Prometheus-style metrics are exposed at /swagger-stats/metrics.
  • The app listens on port 3000; ensure the container and Service route traffic to this container port.
Quick reference: endpoints and their purpose

Dockerfile

This Dockerfile builds the application image and exposes port 3000 to match the app.
Build and push the image to your container registry (replace with your own image name/repository):
Example push confirmation:
(Your digest and size will differ.)

Kubernetes manifests

Create a single manifest file api-deploy.yaml that includes both the Deployment and the Service. The Deployment runs two replicas of the container and exposes container port 3000. The Service is a ClusterIP Service that forwards port 3000 to pods labeled app: api. api-deploy.yaml:
Notes:
  • The Deployment’s selector.matchLabels: app: api must match the Pod template labels.
  • The Service selector: app: api must match the Pod labels so traffic reaches the pods.
  • ClusterIP keeps the Service internal to the cluster. To expose externally, change type to NodePort or LoadBalancer depending on your environment.
Ensure the container’s exposed port matches the Service targetPort. In this example both are 3000. Mismatched ports commonly cause “connection refused” errors.

Deploy to the cluster

Apply the manifest:
Expected output:
Verify the objects:
Example outputs (values will vary):
Once the Deployment is ready and the Service exists, the application is reachable from inside the cluster:
  • Service URL (cluster-internal): http://api-service:3000/swagger-stats/metrics
  • Pod URL (for a specific pod): http://<pod-ip>:3000/swagger-stats/metrics
Prometheus (or the Prometheus Operator via a ServiceMonitor) should be configured to scrape http://api-service:3000/swagger-stats/metrics. To complete monitoring, create or update your Prometheus scrape configuration (or a ServiceMonitor) so Prometheus discovers and scrapes this Service. If using the Prometheus Operator, a ServiceMonitor targeting api-service with the path /swagger-stats/metrics and port web (or 3000) is the recommended approach.

Watch Video