Start with the problem they solve
An application rarely runs on source code alone. It needs a runtime, libraries, configuration, and sometimes operating-system packages. When developers and servers have different environments, a program can work locally and fail after deployment.
Containers help package the application and its dependencies into a reproducible environment. Docker provides popular tools for building container images and running containers. Kubernetes coordinates containerized applications across a collection of machines. One focuses on packaging and execution; the other on managing a distributed runtime.
Image, container, and registry
A container image is a packaged filesystem plus metadata describing how the program should start. Images are built in layers and usually stored in a registry. A container is a running instance of an image, with process isolation and a writable layer.
A Dockerfile describes how to build an image:
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
USER node
CMD ["node", "server.js"]
This is a simplified example for an application that needs no build step. A production build should select maintained base images, pin dependencies, exclude secrets and unnecessary files with .dockerignore, and use a multistage build when compilation is required. Pinning an image digest improves reproducibility, but updates still need a deliberate security process.
A container is not a small virtual machine. On Linux, containers typically share the host kernel while using namespaces and control groups for isolation and resource management. This makes them relatively lightweight, but it also means kernel compatibility and security boundaries matter. Docker Desktop commonly uses a virtual machine to provide a Linux environment on other operating systems.
What Docker gives you
Docker can build an image, run it, expose ports, attach storage, and connect multiple containers. Docker Compose expresses a local or single-host application as several services:
services:
web:
image: example/web:1.0
ports:
- "8080:3000"
database:
image: postgres:17
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
secrets:
db_password:
file: ./secrets/db_password.txt
The secret file belongs outside source control. This sketch also omits persistent database storage and backups, which a real deployment must configure. Compose is valuable for development and can support straightforward single-server deployments. It does not automatically provide multi-machine failover or a distributed scheduler.
What Kubernetes adds
Suppose your application must run across several machines, replace failed instances, and deploy changes without stopping all traffic. Kubernetes lets you declare a desired state and continuously works toward it.
A Deployment might request three replicas of an application. A scheduler chooses machines with suitable resources. Controllers notice when replicas disappear and arrange replacements. A Service supplies a stable network identity while individual instances come and go.
The smallest schedulable unit is a Pod, which contains one or more closely related containers. Kubernetes uses container runtimes through the Container Runtime Interface; many clusters use containerd. Docker is not required on cluster nodes, although Docker-built OCI-compatible images work with these runtimes.
| Concept | Purpose |
|---|---|
| Pod | Runs one or more related containers together |
| Deployment | Manages replicas and application rollout |
| Service | Provides stable access to a changing set of Pods |
| ConfigMap / Secret | Supplies configuration and sensitive values |
| PersistentVolume | Represents storage with an independent lifecycle |
Automation has conditions
“Self-healing” does not mean Kubernetes repairs your code or recovers deleted business data. It can restart a failed process, but a bad release may continue to fail. Resource requests, limits, health checks, and application behavior determine whether the automation helps.
Readiness probes answer whether an instance should receive traffic. Liveness probes answer whether a stuck instance should be restarted. Mixing them up can create restart loops during temporary dependency outages. Startup probes can protect slow-starting processes from premature liveness failures.
Kubernetes Secrets are not a complete security strategy. Their values are base64-encoded in manifests, which is encoding rather than encryption. Protect them with access controls, encryption at rest where configured, restricted service accounts, and an appropriate secret-management workflow.
Which one should you choose?
Use Docker or another container tool when you need consistent packaging and a reliable way to run software. Consider Compose for a development environment or a small application on one server. A managed application platform may offer the deployment and scaling features you need with less operational work.
Choose Kubernetes when the requirements justify its complexity: multiple services, resilient scheduling across machines, sophisticated rollout policies, or an organization already equipped to operate clusters. Account for networking, upgrades, observability, storage, access control, and on-call ownership.
Containers do not make an application stateless. Keep important data outside disposable container filesystems, define backup and restore procedures, and handle graceful shutdown. A well-operated simple deployment is often more reliable than a cluster whose failure modes nobody understands.