In short
A container packages an application with its libraries and runtime into one image that runs identically on a laptop, a test server and a cloud VM, while sharing the host operating system kernel instead of booting its own. Docker is the dominant tool for building and running single containers; Kubernetes is the orchestrator that runs thousands of them across a cluster, restarting, scaling and load-balancing them automatically. Together they are the standard deployment layer at Indian product companies and service firms alike (Flipkart, Swiggy, Zomato, Razorpay, PhonePe, Jio, Infosys, TCS, Wipro, Zoho), and Docker/Kubernetes questions appear in almost every DevOps, backend and SRE interview. University syllabi cover them under cloud computing, virtualisation and DevOps electives; GATE CS touches virtualisation concepts rather than Docker commands. Being able to write a Dockerfile, read a Kubernetes YAML manifest and explain why a pod is in CrashLoopBackOff is a practical hiring filter for freshers.
Explained
Virtualisation, containers and images
- Hypervisor (VM) virtualisation: a hypervisor (Type 1 bare-metal like ESXi/KVM, Type 2 hosted like VirtualBox) emulates hardware; each VM boots a full guest OS with its own kernel. Isolation is strong, but each VM costs hundreds of MB to GB of RAM and boots in tens of seconds.
- OS-level virtualisation (containers): all containers share the host kernel; only user-space (libraries, binaries, app) is packaged. A container starts in milliseconds and may take only tens of MB.
- Linux primitives that make containers work — standard exam answer:
- Namespaces provide isolation:
pid(own process tree, app sees itself as PID 1),net(own interfaces and ports),mnt(own filesystem view),uts(own hostname),ipc,user,cgroup. - cgroups (control groups) provide resource limits and accounting: CPU shares/quota, memory limit, block I/O, PIDs count.
- Union filesystem (OverlayFS) stacks read-only layers with one writable layer on top — this is copy-on-write.
- Capabilities, seccomp, AppArmor/SELinux restrict what syscalls and privileges a container has.
- Namespaces provide isolation:
- Image vs container: an image is an immutable, layered, read-only template (like a class); a container is a running instance of it with a thin writable layer (like an object). One image → many containers.
- Image layers: each Dockerfile instruction that changes the filesystem creates a layer, identified by a content hash (SHA-256 digest). Layers are cached and shared — ten images built
FROMthe same base share that base on disk and in the registry. - OCI standards: the Open Container Initiative defines the image spec and runtime spec, so images are portable across runtimes. Docker's engine uses containerd (high-level runtime) which calls runc (low-level, creates namespaces/cgroups). Alternatives: Podman (daemonless, rootless), CRI-O, Buildah.
- Container ≠ security boundary as strong as a VM: a shared kernel means a kernel exploit can escape. Multi-tenant hostile workloads use VMs, gVisor or Kata Containers.
Docker: architecture, Dockerfile and commands
- Architecture:
dockerCLI (client) → Docker daemon (dockerd) over a REST API/Unix socket → containerd → runc. Registry (Docker Hub, Amazon ECR, Azure ACR, Google Artifact Registry, Harbor, GitLab registry) stores images. Docker Desktop on Windows/macOS runs a small Linux VM, because containers need a Linux kernel. - Image naming:
registry/namespace/repository:tag— e.g.docker.io/library/node:20-alpine.:latestis just a default tag, not "newest"; production must pin a version or a digest (image@sha256:...). - Core Dockerfile instructions:
FROMbase image (first line;scratch= empty).WORKDIRsets the working directory.COPYcopies from build context;ADDalso untars and fetches URLs (preferCOPY).RUNexecutes at build time, creating a layer.CMDandENTRYPOINTrun at container start.ENVbuild+runtime variables,ARGbuild-time only,EXPOSEdocuments a port,VOLUMEdeclares a mount point,USERdrops root,HEALTHCHECKdefines a liveness command,LABELadds metadata.ENTRYPOINT= the fixed executable;CMD= default arguments thatdocker runoverrides. Use exec form["nginx","-g","daemon off;"]so the process is PID 1 and receives SIGTERM; shell form wraps it in/bin/sh -cand breaks signal handling.
- Build cache: layers are reused until the first changed instruction, after which everything below rebuilds. Hence copy
package.jsonand runnpm cibefore copying source code. - Multi-stage build: a
builderstage compiles; the final stage copies only the artefact, so compilers and dev dependencies never ship. This is the standard answer to "how do you reduce image size" (often 1 GB → 50 MB). - Essential commands:
docker build -t app:1.0 .,docker run -d -p 8080:80 --name web app:1.0,docker ps -a,docker logs -f web,docker exec -it web sh,docker stop/rm,docker images,docker rmi,docker pull/push,docker inspect,docker stats,docker system prune. - Storage: containers are ephemeral — the writable layer dies with the container.
- Volumes (
-v mydata:/var/lib/mysql) are Docker-managed, the recommended way to persist data. - Bind mounts (
-v $(pwd):/app) map a host path — used in development for live reload. - tmpfs keeps data in RAM only.
- Volumes (
- Networking drivers:
bridge(default; containers on a user-defined bridge resolve each other by container name via embedded DNS),host(shares host network namespace, no port mapping),none,overlay(multi-host, Swarm),macvlan. Port publishing is-p hostPort:containerPort. - Docker Compose: one
docker-compose.ymldefines multi-container apps (services,image/build,ports,environment,volumes,depends_on,networks);docker compose up -d/down. Ideal for local development and CI, not for multi-node production. - Docker Swarm is Docker's own orchestrator (simpler, built in) but the industry has standardised on Kubernetes.
- Limitations of plain Docker: no automatic rescheduling if a host dies, no built-in autoscaling, no declarative cluster-wide desired state, manual load balancing — exactly the gaps Kubernetes fills.
Kubernetes architecture and objects
- What it is: an open-source container orchestrator (from Google's Borg, open-sourced in 2014 and donated to the CNCF in 2015) that maintains a declarative desired state — you submit YAML saying "5 replicas of this image"; controllers continuously reconcile reality to it (the control loop / reconciliation).
- Control plane components:
- kube-apiserver — the only way in; validates and persists all objects (REST over HTTPS).
- etcd — distributed consistent key-value store holding all cluster state (the thing you back up).
- kube-scheduler — assigns pending pods to nodes using filters (resources, taints, node selectors, affinity) and scoring.
- kube-controller-manager — runs the controllers (Deployment, ReplicaSet, Node, Job, endpoint).
- cloud-controller-manager — talks to the cloud provider for load balancers, routes and volumes.
- Worker node components: kubelet (agent; starts containers via the CRI, reports health), container runtime (containerd or CRI-O — Docker's
dockershimwas removed in Kubernetes 1.24, so Docker is no longer a runtime although Docker-built images still run), kube-proxy (programs iptables/IPVS rules so Service IPs work). - Workload objects:
- Pod — the smallest deployable unit: one or more containers that share a network namespace (same IP, same localhost) and can share volumes. Sidecar, init-container and ambassador patterns live here. Pods are mortal and get a new IP on recreation.
- ReplicaSet — keeps N identical pods running (usually not written by hand).
- Deployment — manages ReplicaSets and gives rolling updates and rollback (
kubectl rollout status/undo); for stateless apps. - StatefulSet — stable ordered names (
db-0,db-1), stable storage per pod; for databases, Kafka, ZooKeeper. - DaemonSet — exactly one pod per node; for log shippers (Fluent Bit), monitoring agents (node-exporter), CNI plugins.
- Job / CronJob — run-to-completion and scheduled tasks (nightly report, data cleanup).
- Networking and exposure:
- Every pod gets a routable IP from a CNI plugin (Calico, Flannel, Cilium, AWS VPC CNI); all pods can reach all pods by default — restrict with NetworkPolicy.
- Service gives a stable virtual IP and DNS name in front of pods selected by labels: ClusterIP (internal, default), NodePort (opens a port 30000-32767 on every node), LoadBalancer (provisions a cloud LB), ExternalName (CNAME), and headless (
clusterIP: None, returns pod IPs — used by StatefulSets). - Ingress + an ingress controller (NGINX, Traefik, HAProxy) does host/path-based HTTP routing and TLS termination for many services behind one LB — far cheaper than one cloud LB per service. The newer Gateway API is replacing it gradually.
- Configuration and identity: ConfigMap (non-secret config as env vars or mounted files), Secret (base64-encoded, not encrypted by default — enable encryption at rest or use external KMS/Vault), Namespace (logical partition: dev/staging/prod), labels (selectors) vs annotations (metadata only), ServiceAccount + RBAC (Role, ClusterRole, RoleBinding) for authorisation, ResourceQuota and LimitRange per namespace.
- Scheduling and resilience:
requests(used for scheduling, guaranteed) vslimits(hard cap; exceeding memory limit → OOMKilled, exceeding CPU → throttled); QoS classes Guaranteed / Burstable / BestEffort; taints and tolerations, node affinity, pod affinity/anti-affinity, PodDisruptionBudget, topology spread. - Health probes: liveness (fail → container restarted), readiness (fail → pod removed from Service endpoints, no traffic), startup (protects slow-booting apps from the liveness probe).
- Scaling: HPA (Horizontal Pod Autoscaler — more pods, on CPU/memory/custom metrics), VPA (right-sizes requests), Cluster Autoscaler / Karpenter (adds nodes). Metrics come from the metrics-server.
- Storage: PersistentVolume (the actual disk), PersistentVolumeClaim (a pod's request), StorageClass (dynamic provisioning, e.g. EBS gp3, Azure Disk), CSI drivers; access modes ReadWriteOnce / ReadOnlyMany / ReadWriteMany.
- Operations:
kubectl apply -f,get,describe,logs,exec,port-forward,scale,rollout,top. Helm packages manifests as versioned, templated charts; Kustomize patches base YAML per environment; Operators/CRDs extend the API with custom resources; Argo CD/Flux do GitOps.
Build-to-deploy pipeline and deployment strategies
- Developer pushes code to Git (GitHub/GitLab/Bitbucket).
- CI (Jenkins, GitHub Actions, GitLab CI, Azure DevOps) runs tests, then
docker buildwith a tag = commit SHA. - Image is scanned (Trivy, Clair) and pushed to the registry (ECR/ACR/Harbor).
- CD updates the image tag in the manifest/Helm values;
kubectl applyor Argo CD syncs it. - The Deployment performs a rolling update bounded by
maxUnavailableandmaxSurge; readiness probes gate each new pod;kubectl rollout undoreverts. - Strategies: Rolling (default, zero downtime, two versions live briefly), Recreate (downtime, single version — needed for incompatible schema), Blue-Green (two full environments, switch the Service selector; instant rollback, double cost), Canary (5% → 25% → 100% traffic, needs a service mesh or weighted ingress), A/B (route by header/cookie).
- Observability: Prometheus + Grafana for metrics, Loki/ELK/EFK for logs (containers log to stdout/stderr; the platform collects them), Jaeger/OpenTelemetry for traces, Istio/Linkerd service mesh for mTLS, retries and traffic splitting.
- Managed services: Amazon EKS, Azure AKS, Google GKE, plus Indian/sovereign clouds — Jio Cloud, Zoho, E2E Networks, CtrlS and NIC's MeghRaj offer Kubernetes-based platforms. Exact prices change, so quote current provider pricing rather than memorised figures.
- Twelve-factor fit: config from the environment, stateless processes, logs as event streams, disposability — containers are the practical embodiment of these rules.
Best practices, security and India-specific compliance
- Small images: Alpine or
distrolessbases, multi-stage builds,.dockerignore(exclude.git,node_modules), combineRUNsteps,--no-install-recommends, clean apt lists in the same layer (deleting a file in a later layer does not shrink the image). - Never bake secrets into an image — layers are permanent and extractable; use BuildKit secret mounts, ConfigMaps/Secrets, or a vault.
- Run as non-root (
USER app),readOnlyRootFilesystem: true, drop capabilities, avoid--privilegedand mounting/var/run/docker.sock, enforce with Pod Security Admission or OPA/Gatekeeper/Kyverno. - Pin digests, scan images, sign them (Cosign), keep a private registry mirror.
- One concern per container; let the platform handle restarts rather than running supervisord inside.
- Set requests and limits on every container — without them a single pod can starve a node.
- Indian regulatory context: RBI's directions require regulated entities' payment-system data to be stored in India, so bank and fintech clusters run in Indian regions/zones; the Digital Personal Data Protection Act, 2023 governs personal data in these workloads; CERT-In's 2022 directions mandate logs retained 180 days within India and incident reporting within 6 hours, which drives log-shipping DaemonSets and retention settings; MeitY empanelment applies to government cloud (MeghRaj). Exact rule text and timelines are periodically amended — verify against the current circular.
Key points
- Container - OS-level virtualisation that shares the host kernel and isolates only user space; starts in milliseconds.
- Namespaces and cgroups - namespaces give isolation (what a process can see), cgroups give limits (how much it can use).
- Image vs container - immutable layered template vs a running instance with a thin writable copy-on-write layer.
- Layer caching - a change invalidates that layer and every layer below it; order Dockerfile steps least-changing first.
- Multi-stage build - compile in one stage, copy only the binary into a slim final stage; the main way to cut image size.
- ENTRYPOINT vs CMD - ENTRYPOINT is the executable, CMD the default overridable arguments; use exec form for correct signals.
- Volume vs bind mount - Docker-managed named volume for production data, host-path bind mount for development.
- Compose vs Kubernetes - Compose runs a multi-container app on one host; Kubernetes schedules across a cluster with self-healing.
- Pod - smallest Kubernetes unit; containers in a pod share IP, localhost and volumes, and are scheduled together.
- Deployment → ReplicaSet → Pod - the ownership chain that provides rolling updates and rollback for stateless apps.
- StatefulSet / DaemonSet / Job - stable identity + storage; one pod per node; run-to-completion work.
- Service types - ClusterIP (internal), NodePort (port on every node), LoadBalancer (cloud LB), ExternalName, headless.
- Ingress - one HTTP entry point with host/path routing and TLS for many services, instead of many load balancers.
- ConfigMap vs Secret - plain configuration vs sensitive values (base64, not encrypted unless encryption at rest is enabled).
- Liveness vs readiness probe - liveness failure restarts the container; readiness failure only stops traffic to it.
- Requests vs limits - requests drive scheduling; exceeding a memory limit gives OOMKilled, exceeding CPU gives throttling.
- Control plane - api-server, etcd, scheduler, controller-manager; workers run kubelet, container runtime, kube-proxy.
- Declarative reconciliation - you declare desired state in YAML; controllers continuously converge the cluster to it.
Formulas and examples
allocatable = node capacity − kube-reserved − system-reserved − eviction threshold.
Example 1 — Containers vs VMs on one 64 GB server. A service needs 512 MB RAM per instance. Each VM also needs ~1 GB for its guest OS; assume 4 GB is reserved for the host/hypervisor.
- VMs: usable 64 − 4 = 60 GB; per VM = 1 GB (OS) + 0.5 GB (app) = 1.5 GB → 60 / 1.5 = 40 instances.
- Containers: 60 GB / 0.5 GB = 120 instances — 3× the density, because the kernel is shared once instead of 40 times.
Example 2 — Pods per node and cluster size. A node of 4 vCPU / 16 GiB has allocatable ≈ 3.9 vCPU (3900m) and ≈ 14.5 GiB after reservations. A pod requests 250m CPU and 512 Mi RAM.
- By CPU: 3900 / 250 = 15.6 → 15 pods.
- By memory: 14.5 GiB = 14,848 Mi; 14,848 / 512 = 29 → 29 pods.
- Binding constraint = CPU → 15 pods per node.
- For 100 replicas: 100 / 15 = 6.67 → 7 nodes, plus one spare for failure tolerance = 8 nodes.
Example 3 — Rolling update timeline. A Deployment has 10 replicas, maxSurge: 2, maxUnavailable: 0, and each new pod takes 30 s to pass its readiness probe.
- Pods never fall below 10; at most 12 exist at once.
- New pods come up 2 at a time: ceil(10 / 2) = 5 batches.
- Time ≈ 5 × 30 s = 150 s (2.5 minutes) of zero-downtime rollout.
- With
maxUnavailable: 0and no spare node capacity for 2 extra pods, the rollout stalls — a very common interview trap.
Example 4 — HPA scaling arithmetic. Deployment runs 4 pods; CPU request 200m each; HPA target = 50% average CPU utilisation. Current average usage = 180m per pod.
- Current utilisation = 180 / 200 = 90%.
- Desired replicas = ceil(4 × 90 / 50) = ceil(7.2) = 8 pods.
- After scaling, expected usage per pod = (4 × 180) / 8 = 90m = 45% — below target, so it stabilises (the default scale-down stabilisation window is 5 minutes).
Example 5 — Image size from a multi-stage build. A Spring Boot service: maven:3.9-eclipse-temurin-21 build image = 780 MB, the fat JAR = 45 MB, runtime base eclipse-temurin:21-jre-alpine = 190 MB.
- Single-stage image ≈ 780 + 45 = 825 MB.
- Multi-stage final image ≈ 190 + 45 = 235 MB — a 72% reduction, and the Maven cache and source code are not shipped.
- Pulling to 50 nodes moves 50 × 235 MB ≈ 11.75 GB instead of 41.25 GB.
| Aspect | Virtual machine | Container |
|---|---|---|
| Isolation unit | Full guest OS + own kernel | Process group, shared host kernel |
| Start-up | Tens of seconds to minutes | Milliseconds to a few seconds |
| Size | GBs | Tens to hundreds of MB |
| Overhead per instance | ~0.5-1 GB RAM for the OS | Negligible |
| Isolation strength | Stronger (hardware-level) | Weaker (kernel shared) |
| Portability | OS image, hypervisor-specific | OCI image, runs on any Linux host |
| Typical use | Mixed/untrusted OS workloads, legacy | Microservices, CI, stateless scaling |
| Need | Docker alone | Docker Compose | Kubernetes |
|---|---|---|---|
| Scope | One container | Multi-container, one host | Multi-container, many nodes |
| Self-healing | No (restart policy only) | Restart policy | Reschedules pods, replaces nodes |
| Autoscaling | No | No | HPA / VPA / Cluster Autoscaler |
| Rolling update + rollback | Manual | Limited | Built into Deployment |
| Service discovery | Container name on a user network | Service name | Service DNS + kube-proxy |
| Best for | Local build/run | Development, CI | Production at scale |
# Multi-stage Node.js image
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci # cached unless package files change
COPY . .
RUN npm run build
FROM node:20-alpine
WORKDIR /app
ENV NODE_ENV=production
COPY package*.json ./
RUN npm ci --omit=dev && npm cache clean --force
COPY --from=build /app/dist ./dist
USER node
EXPOSE 3000
HEALTHCHECK CMD wget -qO- http://localhost:3000/health || exit 1
ENTRYPOINT ["node", "dist/server.js"]
# Deployment + Service: the two manifests every interviewer expects
apiVersion: apps/v1
kind: Deployment
metadata: { name: api, namespace: prod }
spec:
replicas: 3
strategy:
rollingUpdate: { maxSurge: 1, maxUnavailable: 0 }
selector:
matchLabels: { app: api }
template:
metadata:
labels: { app: api }
spec:
containers:
- name: api
image: registry.example.in/api@sha256:abc123
ports: [{ containerPort: 3000 }]
envFrom: [{ configMapRef: { name: api-config } }]
env:
- name: DB_PASSWORD
valueFrom: { secretKeyRef: { name: db-secret, key: password } }
resources:
requests: { cpu: "250m", memory: "512Mi" }
limits: { cpu: "500m", memory: "512Mi" }
readinessProbe:
httpGet: { path: /ready, port: 3000 }
initialDelaySeconds: 5
livenessProbe:
httpGet: { path: /healthz, port: 3000 }
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata: { name: api-svc, namespace: prod }
spec:
type: ClusterIP
selector: { app: api } # must match pod labels, not Deployment name
ports: [{ port: 80, targetPort: 3000 }]
Where it is used
- E-commerce and consumer internet: Flipkart, Myntra, Swiggy, Zomato, Meesho and Nykaa run microservices on Kubernetes, scaling pods for sale events and festive peaks and scaling back overnight.
- Fintech and banking: Razorpay, PhonePe, Paytm, Zerodha and private banks containerise payment and KYC services, with clusters in Indian cloud regions to satisfy RBI data-localisation and CERT-In logging rules.
- IT services and GCCs: TCS, Infosys, Wipro, HCLTech, Accenture and Capgemini modernise client monoliths into containers; "Docker + Kubernetes + Jenkins/GitHub Actions" is a standard fresher job description for DevOps and cloud roles.
- Telecom and media: Jio and Airtel use Kubernetes for 5G network functions (CNFs) and streaming back-ends; telcos were early adopters of containerised NFV.
- Data, ML and government: Spark/Airflow on Kubernetes, model serving with KServe; NIC/MeghRaj and state data centres host containerised citizen portals; UPI-scale systems depend on horizontal pod scaling.
- Job roles: DevOps engineer, SRE, platform engineer, cloud engineer, backend developer; certifications CKA/CKAD/CKS and AWS/Azure cloud associate exams test exactly this material.
Interview questions
- Q: What is the difference between a container and a virtual machine? A: A VM virtualises hardware and runs its own guest OS kernel; a container virtualises the OS, sharing the host kernel and isolating only user space — so containers are far smaller and start in milliseconds, but offer weaker isolation.
- Q: What is the difference between an image and a container? A: An image is an immutable, layered read-only template stored in a registry; a container is a running instance of that image with an added writable copy-on-write layer.
- Q: Which Linux features make containers possible? A: Namespaces for isolation (pid, net, mnt, uts, ipc, user), cgroups for resource limits and accounting, and a union filesystem such as OverlayFS for layered images.
- Q: ENTRYPOINT vs CMD? A: ENTRYPOINT defines the executable that always runs; CMD supplies default arguments that
docker runcan override. If both are given in exec form, CMD's values are appended to ENTRYPOINT. - Q: How do you reduce Docker image size? A: Use a multi-stage build, a slim/alpine or distroless base, a
.dockerignore, combine RUN layers and remove caches in the same layer — deleting files in a later layer does not shrink the image. - Q: Where does data go when a container is deleted, and how do you persist it? A: The writable layer is destroyed with the container; persist data in a named volume (production) or a bind mount (development), and in Kubernetes with a PersistentVolumeClaim.
- Q: What exactly is a pod and why not just a container? A: A pod is the smallest schedulable unit — one or more containers sharing a network namespace, IP and volumes — which lets tightly coupled helpers (sidecars, init containers) be co-scheduled and share localhost.
- Q: Difference between liveness and readiness probes? A: A failing liveness probe restarts the container; a failing readiness probe only removes the pod from its Service endpoints so it receives no traffic until healthy.
- Q: Difference between resource requests and limits? A: Requests are what the scheduler reserves and guarantees; limits are the hard ceiling — exceeding a memory limit causes an OOMKill, exceeding a CPU limit causes throttling, not a kill.
- Q: How does a Deployment achieve zero-downtime deployment? A: It creates a new ReplicaSet and shifts pods gradually within
maxSurge/maxUnavailable, admitting traffic only after readiness probes pass, andkubectl rollout undorestores the previous ReplicaSet. - Q: When would you use a StatefulSet instead of a Deployment? A: When pods need stable identities, ordered start-up/shutdown and their own persistent volume — databases, Kafka, ZooKeeper, Elasticsearch.
- Q: A pod is in
CrashLoopBackOff— how do you debug it? A:kubectl describe podfor events and exit codes,kubectl logs --previousfor the dead container's output, then check the command/entrypoint, missing ConfigMap/Secret, failed dependency, a too-aggressive liveness probe, or exit code 137 (OOMKilled) meaning the memory limit is too low. - Q: Is Docker still needed now that Kubernetes removed dockershim? A: Yes — Kubernetes dropped Docker as a *runtime* (it uses containerd/CRI-O) but Docker-built OCI images run unchanged, and Docker remains the common local build tool.
- Q: Are Kubernetes Secrets secure? A: By default they are only base64-encoded in etcd and readable by anyone with the right RBAC; they need encryption at rest, tight RBAC, and ideally an external KMS or Vault integration.
Common mistakes
- Saying "a container is a lightweight VM" — it has no guest OS or kernel of its own, which is the whole point.
- Putting
COPY . .beforenpm install/pip install, destroying the build cache so every code change reinstalls dependencies. - Relying on
:latest, then being unable to reproduce or roll back a deployment; also baking secrets or.envfiles into image layers. - Storing application data in the container filesystem instead of a volume or PVC, and losing it on the next restart.
- Mismatching a Service
selectorwith the pod labels (they must match the labels, not the Deployment's name), then wondering why endpoints are empty. - Omitting requests and limits, or setting a memory limit below real usage and getting repeated OOMKills (exit code 137).
- Using a liveness probe where a readiness probe is needed — a slow-starting app then restarts forever instead of simply waiting (use a startup probe).
- Running containers as root with
--privilegedor the Docker socket mounted, and forgetting thatEXPOSEalone publishes nothing without-por a Service.
Related topics
Cloud computing basics · AWS core services · System design basics for freshers · REST APIs · Back-end development with Node.js · Caching, queues and CDNs