What is Docker
Docker is a tool that packages an application together with everything it needs to run—code, runtime, system libraries, and configuration—into a container.
A container runs the same way on any machine with Docker installed. This removes “works on my machine” problems and makes development, testing, and deployment more predictable.
Why use Docker?
- Reproducible development environments
- Easy deployment across machines and clouds
- Isolation between projects (no dependency conflicts)
- Faster onboarding and CI/CD pipelines
Core concepts (explained simply)
-
Image A read-only blueprint for an application. Built once, reused many times.
-
Container A running instance of an image. Containers are isolated processes.
-
Dockerfile A text file that defines how an image is built (base image, files, commands).
-
Layers Images are built in layers. Docker caches layers to speed up rebuilds.
-
Volumes Persistent storage that survives container restarts and removal.
-
Networking Containers can expose ports and communicate over private networks.
An image is static. A container is running. You build images and run containers.
Step-by-step example
Minimal Node.js app
Dockerfile
FROM node:18-slim
WORKDIR /app
COPY app.js .
EXPOSE 3000
CMD ["node", "app.js"]
app.js
require("http")
.createServer((_, res) => res.end("Hello from Docker"))
.listen(3000);
Build and run
docker build -t hello-docker .
docker run -d -p 3000:3000 --name hello hello-docker
Check status and logs:
docker ps
docker logs hello
Stop and remove:
docker stop hello && docker rm hello
Useful everyday commands
- List containers:
docker ps -a - Enter a container shell:
docker exec -it <name> sh - Run interactively:
docker run -it <image> bash - Remove unused data:
docker system prune
Common pitfalls
- Forgetting
.dockerignore→ slow builds, huge images - Using
latesttags in production - Storing data inside the container instead of volumes
- Baking secrets into images
- Exposing ports unnecessarily
Best practices
- Use small base images (
slim,alpinewhen possible) - Pin image versions
- Use multi-stage builds for production
- Run containers as non-root users
- Use environment variables or secret stores
- Add health checks for long-running services
When to use Docker
- Local development parity with production
- CI/CD pipelines
- Multi-service apps (API + DB + cache)
- Moving to a PaaS or Kubernetes later
When not to use Docker
- Apps requiring custom kernel modules
- Extremely simple scripts where Docker adds overhead
- Hardware-bound workloads without container support
Key takeaways
- Docker standardizes how applications are built and run
- Images are templates; containers are running processes
- Dockerfiles define reproducible builds
- Volumes handle persistent data
- Docker Compose manages multi-service setups