Think of containers like shipping containers in the real world. A shipping container is a standardized box: 20 feet or 40 feet long, built to a spec that works on trucks, ships, and trains. What's inside changes—steel coils, electronics, clothing—but the container itself is identical. You can move it anywhere, and the contents stay protected and organized.
Software containers work the same way. A container is a standardized package holding your application, its dependencies, and configuration. It runs identically on your laptop, a colleague's machine, or a cloud server. The operating system might be different, but the container guarantees consistency.
In this chapter, you'll explore the mechanics of containers by hands-on discovery: pulling actual images, running them, stopping them, and examining their internal structure. Through this exploration, you'll build the mental model that enables you to write and optimize containers effectively.
Here's the fundamental concept that unlocks everything: Images are templates. Containers are instances.
Just like a class in Python defines a blueprint (the image) and objects are instantiated from that class (the containers), Docker works the same way.
An image is a read-only template. It contains a minimal operating system, your application code, all dependencies, and instructions for how to start the application. Images live in registries (Docker Hub, etc.). You pull them to your machine.
A container is a running instance created from an image. It's what actually executes on your machine. Multiple containers can run from the same image simultaneously, each isolated from the others.
This is one of the most important concepts in Docker: images are immutable (unchangeable). Once an image is built, it is never modified.
Docker reconciles immutability with runtime changes by adding a thin writable layer on top of the immutable image layers.
When you delete the container, the writable layer is discarded, but the image remains pristine. Crucial rule: Don't store important data in containers; use volumes for persistence.
Let's pull real images and see them arrive on your system.
Great for tasks like debugging or using a REPL.
Best for background services like web servers.
Sometimes you need to run commands inside a running container without stopping it:
Images are built from layers, stacked like cake layers. Each instruction in your Dockerfile creates a new layer. This architecture enables: