Every developer has said it at some point: "it works on my machine." Someone else pulls your code, and something about their Java version, their OS, or a missing environment variable breaks it. Docker exists to make that excuse obsolete by packaging an application together with everything it needs β the runtime, libraries, configuration β into one portable unit called a container.
Containers vs virtual machines
A virtual machine emulates an entire computer, including its own full operating system kernel, which makes it heavy β often gigabytes in size and slow to start. A container shares the host machine's kernel and only packages the application and its dependencies, which makes containers dramatically lighter and faster to start, typically in under a second.
- Virtual machine: full OS per app, strong isolation, heavy, slow to boot.
- Container: shared host kernel, process-level isolation, lightweight, starts almost instantly.
The core vocabulary
- Image β a read-only blueprint: your application code plus everything needed to run it. Think of it as a snapshot or a class.
- Container β a running instance of an image. Think of it as an object created from that class. You can run many containers from one image.
- Dockerfile β a text file with step-by-step instructions for building an image.
- Registry β a place to store and share images, such as Docker Hub.
A tiny taste of the workflow
docker build -t my-app .
docker run -p 8080:8080 my-appThe first command reads a Dockerfile in the current directory and builds an image tagged my-app. The second starts a container from that image, mapping port 8080 inside the container to port 8080 on your machine so you can open it in a browser. That is genuinely most of what you will type day to day once a Dockerfile exists.
Why teams actually adopt it
- Consistency β the exact same image runs on a laptop, a CI pipeline, and production.
- Isolation β an app's dependencies never collide with another app's dependencies on the same machine.
- Portability β the same image runs on any machine with Docker installed, regardless of the underlying OS.
- Easy scaling β spinning up ten identical containers behind a load balancer is trivial once the image exists.
What is next
The rest of this series is hands-on: writing your first Dockerfile, learning the handful of commands you will use daily, wiring multiple containers together with Docker Compose, and finally two real projects β dockerizing a Node.js API, and a genuine multi-stage Dockerfile for a Spring Boot app, the same pattern used to containerize this very site.