Skip to content
Blog

Kubernetes for Frontend Teams: A Gentle Introduction

A beginner-friendly, code-first tour of Kubernetes for frontend engineers: core objects like Pods, Deployments, Services and Ingress, plus a complete YAML bundle to deploy a React SPA and API with health checks.

Published on August 12, 2026

AI Assistant

Dear frontend developer: Kubernetes is closer than you think

You own the UI, the bundler, the latest React release. Then standups start mentioning Kubernetes, or “k8s”, and your imagination conjures black terminals, endless YAML, and a mysterious thing called a Pod. Here is the secret: as a frontend engineer you almost never touch cluster machinery. You write declarative YAML describing what you want, and Kubernetes reconciles the cluster toward it. This is that gentle introduction, with runnable manifests.

Prerequisites

  • Docker fundamentals: know how to build and run an image, since Kubernetes orchestrates containers (see the Docker getting started guide).
  • kubectl, the Kubernetes CLI, plus a local cluster (Docker Desktop’s built-in Kubernetes or Minikube) or a managed one (GKE, EKS, AKS). Verify with kubectl get nodes.
  • A React SPA served by nginx and a minimal Node/Express API with a /health endpoint.

What Kubernetes Actually Solves

One container is one process on one machine. Production wants several copies across servers: auto-restarts on crash, DNS-based frontend-to-API discovery, zero-downtime rollouts, and horizontal scaling. Kubernetes provides exactly that. The frontend-friendly mental shift: stop specifying “how” and start specifying “what”. A Deployment that says “run 3 replicas of frontend:v2” is reconciled by a control loop: if a Pod dies it is replaced, and if the image changes a rollout begins.

The Core Objects You Need to Know

  • Pod: the smallest deployable unit, one or more containers sharing an IP. Ephemeral, so you rarely create Pods directly.
  • Deployment: declaratively manages Pods (replicas, rolling updates, rollbacks). The object you will write most.
  • Service: a stable DNS name and load balancer over the current healthy Pods matching its labels.
  • Ingress: the HTTP(S) front door, routing external traffic to Services by hostname and path.
  • ConfigMap and Secret: configuration and credentials injected as env vars or files, so you never rebuild an image to change config.

Deploying a Static Site and an API

The pattern is one Deployment plus one Service per app. Pod template labels must match the Deployment selector, and a Service finds those Pods through the same labels, exposing them behind a stable name like frontend; the API gets identical treatment with a Service named api, so your SPA reaches it by in-cluster DNS with no hardcoded IPs. The complete manifests live in the bundle below. Deploy declaratively — apply is idempotent, so re-running it is always safe:

kubectl apply -f frontend-deployment.yaml frontend-service.yaml api-deployment.yaml api-service.yaml
kubectl get pods,services

Scaling and Rolling Updates

Edit replicas and re-apply, or scale imperatively. The default RollingUpdate strategy replaces Pods gradually via maxUnavailable and maxSurge, so traffic never drops:

kubectl scale deployment frontend --replicas=5
kubectl rollout status deployment/frontend
kubectl rollout undo deployment/frontend

Health Checks for SPAs

Probes tell Kubernetes when a container is healthy: readiness gates traffic (the important one for SPAs), liveness restarts a stuck container. For a static site you probe nginx itself, so serve a lightweight /healthz that returns 200, then declare the probe:

readinessProbe:
  httpGet:
    path: /healthz
    port: 80
  initialDelaySeconds: 3
  periodSeconds: 5
livenessProbe:
  httpGet:
    path: /healthz
    port: 80
  periodSeconds: 10
  failureThreshold: 3

Avoid probing /: a broken JavaScript bundle still returns 200 from nginx, so probe server reality, and keep liveness shallow.

Putting It All Together

One file deploys the SPA, a minimal API, and an Ingress routing / to the frontend and /api to the backend:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
        - name: frontend
          image: your-registry/frontend:latest
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  selector:
    app: frontend
  ports:
    - port: 80
      targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 2
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
        - name: api
          image: your-registry/api:latest
          ports:
            - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: api
spec:
  selector:
    app: api
  ports:
    - port: 3000
      targetPort: 3000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp
spec:
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend
                port:
                  number: 80
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api
                port:
                  number: 3000

Apply it, then inspect results:

kubectl apply -f all-in-one.yaml
kubectl get pods,ingress
kubectl describe pod frontend-xxxxx

Conclusion and Next Steps

Five objects, declarative YAML, kubectl apply, and reading kubectl get/describe output are the whole surface area you need to ship and debug your app. From there: add TLS via cert-manager, wire a CI/CD pipeline that builds the image and re-applies the manifests, then explore GitOps with Argo CD or Flux. Containers solved “works on my machine”; Kubernetes makes that true in production.

References / Sources