Skip to content

A minimal Node.js API showcasing production-minded Docker and Kubernetes workflows, including dev vs prod images, Docker Compose for local development, and Kubernetes manifests with rolling updates, probes, resource limits, and ConfigMaps.

Notifications You must be signed in to change notification settings

dhairya49/docker-mastery

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Docker Mastery — sample app demonstrating best practices for Docker & Kubernetes

This repository demonstrates practical, production-minded Docker and Kubernetes patterns for a simple Node.js API. It's designed to show you that you can build and deploy containers the "right way" with separate development and production images, a local compose workflow, and Kubernetes manifests that include rolling updates, probes, resource limits, and ConfigMap usage.

Why this project

  • Clear dev / prod split: app/Dockerfile.dev for iterative local development (nodemon + volume mounts) and app/Dockerfile.prod for a lean production image (npm ci --only=production).
  • Compose-based local dev: compose.yaml shows how to run the app with a bind mount for fast feedback loops.
  • Kubernetes-ready: manifests in k8s/ show best practices like RollingUpdate strategy, liveness/readiness probes, resource requests/limits, and ConfigMap usage.
  • Health endpoint: /health is implemented to power probes and quick sanity checks.

Repo layout

docker-mastery
├─ 📁app
│  ├─ 📁node_modules
│  ├─ 📄Dockerfile.dev
│  ├─ 📄Dockerfile.prod
│  ├─ 📄package.json
│  └─ 📄server.js
├─ 📁k8s
│  ├─ 📄configmap.yaml
│  ├─ 📄deployment.yaml
│  └─ 📄service.yaml
├─ 📄.gitignore
├─ 📄README.md
└─ 📄compose.yaml

Key Kubernetes concepts demonstrated

  • manifests in k8s/ show best practices like RollingUpdate strategy, liveness/readiness probes, resource requests/limits, and ConfigMap usage.

  • replicas: 2 and RollingUpdate with maxSurge: 1 and maxUnavailable: 0 for zero-downtime updates

  • imagePullPolicy: Never (set for local-cluster development; change to IfNotPresent or Always for remote registries)

  • resource requests/limits for safer scheduling

  • livenessProbe and readinessProbe against /health

  • k8s/service.yaml exposes the app as a NodePort (suitable for local clusters). Change to LoadBalancer or add an Ingress for cloud deployments.

  • Kubernetes manifests include probes, resource constraints, and rolling update strategy — minimal yet production-relevant.

  • ConfigMap usage demonstrates how to pass non-sensitive config (k8s/configmap.yaml). Use Secrets for credentials.

Architecture (ASCII diagram)

Local development (Docker Compose):

Developer laptop
   └─ docker compose (compose.yaml)
	   └─ Container (Dockerfile.dev)
		   └─ Node.js app (nodemon, bind-mounted source)

Kubernetes deployment (k8s/):

			+----------------+
			|  Image registry |  <- (build/push) or local cluster image load
			+--------+-------+
					 |
	   +-------------v--------------+
	   | Kubernetes cluster (kind)   |
	   |  +------------------------+ |
	   |  | Deployment (replicas=2) | |
	   |  |  - Pod (container: api) | |
	   |  +-----------+------------+ |
	   |              |              |
	   |        Service (NodePort)   |
	   +-------------+--------------+
					 |
				 External
				 traffic / tests

Auxiliary: ConfigMap provides `APP_NAME`, `/health` used by liveness/readiness probes.

What this project does NOT try to solve

This repo is intentionally minimal and focused on demonstrating core container and Kubernetes patterns. It does NOT attempt to be a full production platform. Notable omissions:

  • CI/CD pipeline: no automated build/test/push pipeline is included (you can add GitHub Actions or similar).
  • Secrets management: sensitive values are not stored in Secrets or a vault; only a ConfigMap is shown.
  • Persistent storage: there is no PersistentVolume / database or migration strategy included.
  • Ingress + TLS: the example uses a NodePort service; no Ingress controller or TLS termination is configured.
  • Image registry best-practices: pushing, tagging, signing, and immutable tags for registries are left to the integrator.
  • Full security hardening: the Dockerfiles are basic examples; further hardening (non-root user, minimized layers, image scanning) is recommended.
  • Observability: logging aggregation, metrics, tracing, and alerting are out of scope.
  • Autoscaling & advanced K8s operators: HPA, custom controllers, and operator patterns are not covered.
  • Multi-region, high-availability, and cloud-provider networking specifics are not included.

Quick start — local development (Docker Compose)

  1. From the repository root, start the dev environment:
docker compose -f compose.yaml up --build
  1. Open http://localhost:3000 — the container runs with Dockerfile.dev and the host folder is mounted into the container for instant code changes.

Build and run the production image (locally)

# build the prod image
docker build -f app/Dockerfile.prod -t docker-mastery:1.0 ./app

# run the prod container
docker run --rm -p 3000:3000 docker-mastery:1.0

Deploy to Kubernetes (local cluster)

  1. Build the image and make it available to your cluster.
  • For kind:
docker build -f app/Dockerfile.prod -t docker-mastery:1.0 ./app
kind load docker-image docker-mastery:1.0 --name kind
kubectl apply -f k8s/
  • For minikube:
minikube image load docker-mastery:1.0
kubectl apply -f k8s/
  1. The k8s/deployment.yaml uses the image docker-mastery:1.0 and imagePullPolicy: Never for local-cluster development. Apply the manifests with kubectl apply -f k8s/ after loading the image into your cluster.

Notes & best-practice highlights in this repo

  • Lightweight base images: node:18-alpine keeps images small and fast.
  • Separate install steps: npm install (dev) vs npm ci --only=production (prod) to ensure reproducible production installs.
  • Volumes in compose enable live reloading with nodemon during development.
  • Kubernetes manifests include probes, resource constraints, and rolling update strategy — minimal yet production-relevant.
  • ConfigMap usage demonstrates how to pass non-sensitive config (k8s/configmap.yaml). Use Secrets for credentials.

Health & readiness

  • GET /health returns 200 OK and is used by Kubernetes probes.

What to add next (suggested improvements)

  • Add Ingress manifest and an Ingress controller (e.g., NGINX) for real HTTP routing
  • Add Secret resources for sensitive configuration
  • Add CI pipeline (GitHub Actions) to build, scan, and push images to a registry
  • Add multi-stage Dockerfile or explicit non-root user for improved security

If you'd like, I can:

  • add a sample GitHub Actions workflow to build and push images,
  • convert the k8s/service to Ingress with TLS,
  • or harden the Dockerfile to run as a non-root user.

Enjoy — this repo is a compact showcase of practical Docker + Kubernetes patterns you can point to in interviews or demos.

About

A minimal Node.js API showcasing production-minded Docker and Kubernetes workflows, including dev vs prod images, Docker Compose for local development, and Kubernetes manifests with rolling updates, probes, resource limits, and ConfigMaps.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors