This repository provides a minimal end-to-end application for experimenting with core Kubernetes workload primitives:
- Python FastAPI backend packaged as a Docker image.
- React + Vite frontend built into a static site served by Nginx.
- Kubernetes manifests that demonstrate ConfigMaps, Secrets, ReplicaSets, Deployments, and Services.
Use it as a lab environment to explore how application components fit together inside a cluster.
backend/– FastAPI service exposing/api/healthand/api/message, reads values from environment variables.frontend/– React single-page app that loads configuration at runtime and calls the backend API.infra/– Kubernetes manifests grouped with akustomization.yamlfor easy apply/delete workflows.
- Docker or another container build tool.
- Node.js 18+ (only required if you plan to develop the frontend outside of Docker).
- Python 3.11+ (only required if you plan to run the backend outside of Docker).
- A Kubernetes cluster (Kind, Minikube, k3d, local Docker Desktop, or managed cloud cluster).
kubectlconfigured to talk to the target cluster.
From the repository root:
# Backend FastAPI image (listens on 32111)
docker build -t ajayverse404/k8s-learning-backend:latest ./backend
docker push ajayverse404/k8s-learning-backend:latest
# Frontend React image (served by Nginx on 32100)
docker build -t ajayverse404/k8s-learning-frontend:latest ./frontend
docker push ajayverse404/k8s-learning-frontend:latestTip: If you are using Kind or another local cluster, either push these images to a registry reachable by the cluster or load the images directly (e.g.
kind load docker-image ajayverse404/k8s-learning-backend:latest).
This repository includes a workflow at .github/workflows/docker-publish.yml that builds and publishes both images whenever you push to main or trigger the workflow manually.
- In your GitHub repository settings, create the following secrets using a Docker Hub access token:
DOCKERHUB_USERNAME: Your Docker Hub username.DOCKERHUB_TOKEN: A Docker Hub Personal Access Token withread,write, anddeletepermissions.
- Push to
mainor run the workflow with Run workflow → Run workflow. - Each run publishes two tags per image:
latest- An auto-incrementing version in the format
v1.<run_number>(derived from the GitHub Actions run number).
Update the Kubernetes manifests in infra/ to reference whichever tag you prefer (latest or the versioned tag).
Install an Ingress controller if your cluster does not already provide one. The examples below use the community ingress-nginx controller—choose the variant that matches your environment.
# For managed clouds or bare metal clusters
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml
# For Kind (uses NodePort under the hood)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
# For Minikube you can alternatively enable the addon
minikube addons enable ingressWait until the controller pods report Running:
kubectl get pods -n ingress-nginx-
Create the namespace, ConfigMaps, Secret, ReplicaSet, Deployment, and Services:
kubectl apply -k infra
The
kustomization.yamlapplies the resources in the correct order. -
Confirm that the ReplicaSet and Deployment created the expected Pods:
kubectl get pods -n k8s-learning kubectl describe rs backend-rs -n k8s-learning
-
Inspect ConfigMap and Secret consumption:
kubectl exec -n k8s-learning deploy/frontend-deployment -- \ ls /usr/share/nginx/html/config kubectl exec -n k8s-learning rs/backend-rs -- \ env | grep APP_
-
Access the frontend:
The frontend Service is configured as a
NodePorton32180. When running on a local cluster, openhttp://localhost:32180. Ensure your cluster allows NodePorts in this range (default Kubernetes NodePort range is 30000–32767). In managed clusters, adjust the Service type as needed. -
Check the backend health endpoint:
kubectl port-forward -n k8s-learning svc/backend-service 32111:32111 curl http://localhost:32111/api/health
-
Update
infra/argocd-application.yamlsospec.source.repoURLpoints at your Git repository. -
Apply the Application manifest into the Argo CD control plane namespace (defaults to
argocd):kubectl apply -f infra/argocd-application.yaml
-
In the Argo CD UI or CLI, observe the new application
k8s-learning-app; Argo CD will sync theinfra/kustomization into thek8s-learningnamespace. -
To force a sync via CLI:
argocd app sync k8s-learning-app
Add
--pruneif you disabled automated pruning in the manifest.
- Update
infra/backend-configmap.yamlto tweak the message and environment label surfaced by the API. - Replace the example token in
infra/backend-secret.yamlwith your own Secret values. - Modify the image references in
infra/backend-replicaset.yamlandinfra/frontend-deployment.yamlto match published image names in your container registry. - Adjust
infra/frontend-service.yamlto the appropriate Service type for your environment.
When you are done experimenting:
kubectl delete -k infraThis removes the namespace and all associated resources from the cluster.