Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes

Docker Images vs Containers

Understand the key differences between Docker images and containers: images are read-only blueprints, containers are running instances. This lesson clarifies the mental model with a practical walkthrough, troubleshooting tips, and next steps.

Focus: docker images vs containers

Sponsored

Have you ever run docker run and wondered whether you're working with an image or a container — or if there's even a difference? You're not alone. Even experienced developers sometimes blur the line between these two, leading to confusion about what gets saved, what gets reused, and what disappears when you stop a process. Let's clear it up once and for all.

The problem this lesson solves

When you start using Docker, commands like docker build, docker run, docker ps, and docker images come at you fast. You might run docker run and see a running application, then make changes and expect them to persist — only to find the next docker run starts from scratch. Or you might delete an image and panic because you think your running container is lost. These reactions happen because the mental boundary between an image and a container isn't obvious.

The core pain is this: you can't manage Docker effectively if you treat images and containers as the same thing. Every command you run, every Dockerfile you write, every troubleshooting session depends on understanding this distinction. Without it, you'll accidentally lose work, waste disk space, or struggle to debug production issues.

Core concept / mental model

Think of a Docker image as a read-only blueprint or a template. It's a snapshot of a filesystem, including your application code, runtime, libraries, and configuration — but it never runs on its own. An image is like a .iso file of an operating system installer: you can't use it until you boot it up.

A Docker container, on the other hand, is a running instance of that image. It's the actual process that executes your application. When you start a container, Docker takes the image — the blueprint — adds a thin read-write layer on top, and launches your application inside that environment. Think of a container as a house built from the blueprint: you can live in it, modify the interior (the writable layer), and even tear it down and rebuild it from the same blueprint.

Pro tip: The classic analogy is "image = class, container = instance" from object-oriented programming. An image defines the structure and defaults; a container is a concrete, running object with its own state.

Aspect Docker Image Docker Container
Nature Read-only template Running instance
Persistence Immutable (unless rebuilt) Ephemeral (state is in writable layer)
Lifecycle Stored on disk or registry Created, started, stopped, removed
Purpose Distribution, reuse Execution

How it works step by step

  1. Define an image with a Dockerfile — You write a set of instructions (like FROM, RUN, COPY) that describe exactly what goes into the image.
  2. Build the image — Run docker build -t my-app .. Docker executes the Dockerfile line by line, creating a read-only layer for each instruction. The result is a cached, reusable artifact.
  3. Start a container from that image — Run docker run my-app. Docker takes the image, creates a new read-write layer (the container layer) on top, and starts the process defined in the CMD or ENTRYPOINT.
  4. The container runs — changes happen in the writable layer — Your application writes logs, modifies files, or creates temporary data. These changes live only in the container layer, not in the image.
  5. Stop or remove the container — When you stop the container, the writable layer is preserved on disk (unless you pass --rm). When you remove the container, that writable layer is gone forever — but the image remains safe.
  6. Share or deploy the image — You push the image to a registry (e.g., Docker Hub). Someone else pulls it and runs their own containers. They start exactly where you started, not with your local modifications.

Common mental model: An image is the template; a container is the instance. You can have many containers from one image, each with different runtime state.

Hands-on walkthrough

Let's make this concrete. Fire up your terminal and follow along.

1. Pull a public image

docker pull alpine:latest

This downloads the image to your local cache. It does not create a container yet.

2. List images

docker images

Output (simplified):

REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
alpine       latest    04ee...f6b3    2 weeks ago    7.34MB

That's your blueprint.

3. Create and run a container

docker run --name my-first-container alpine echo "Hello from inside a container"

Output:

Hello from inside a container

What happened? Docker took the alpine:latest image, created a new container called my-first-container, ran the echo command, and exited.

4. See the container (even after it exits)

docker ps -a

Output:

CONTAINER ID   IMAGE           COMMAND                  CREATED          STATUS      PORTS     NAMES
0a1b...        04ee...f6b3     "echo 'Hello from i..."   1 minute ago     Exited (0)           my-first-container

Notice: status is "Exited" — the container exists but is not running.

5. Run another container from the same image

docker run alpine echo "Another container, clean slate"

This creates a brand-new container — it starts from the same image, not from any changes you made in the first container.

6. Clean up

docker rm my-first-container
docker rmi alpine:latest

The first removes the container (writable layer deleted). The second removes the image (blueprint deleted only after no container references it).

Compare options / when to choose what

Use Case Use Image Use Container
Distribution Push image to registry; others pull it Never push a container — it's volatile
Testing changes Rebuild image after Dockerfile edits Run container, test, then docker rm
Persisting data Image is read-only — use volumes or bind mounts Container's writable layer is ephemeral
Debugging Inspect image layers with docker history Get a shell in a running container (docker exec -it)
Saving state Commit a container to a new image (docker commit) only for quick snapshots Prefer volumes or Dockerfile for reproducibility

When should you rebuild the image versus modify a running container?

  • Rebuild the image — always, for production. This creates a reproducible, versioned artifact.
  • Modify a running container — only for quick experiments or debugging. Once you stop the container, changes are lost unless you commit or use volumes.

Troubleshooting & edge cases

"I deleted an image, but my container still runs!"

That's okay — the container uses a copy of the image's filesystem. The image can be deleted as long as no other containers reference it (by image ID or tag). The running container continues using its own snapshot of the layers.

"I modified a file inside a container, but when I start a new container, changes are gone"

Yes — that's expected. The writable layer is per-container. To persist changes, either: - Use a volume (docker run -v /host/path:/container/path ...) - Commit the container to a new image (docker commit CONTAINER_NAME new-image-name)

"I have multiple images with the same name but different tags — which does docker run use?"

If you don't specify a tag, Docker defaults to latest. Always use explicit tags (docker run my-app:1.0.0) to avoid confusion.

"docker image rm says 'image is being used by running container'"

Stop and remove the container first (docker stop <container> then docker rm <container>), or force removal (docker image rm -f IMAGE_NAME).

"My image is huge, but containers should be lightweight — what gives?"

The image size includes all layers. When you run a container, Docker mounts these layers as read-only and adds a thin read-write layer. The container overhead is just that thin layer (a few KB), but the total footprint on disk includes the underlying image layers. To reduce size, use multi-stage builds and slim base images.

What you learned & what's next

You now understand the fundamental distinction at the heart of Docker: images are read-only blueprints for building, sharing, and versioning your application, while containers are running instances of those blueprints — ephemeral, writable, and tied to a specific execution.

You learned: - How to pull, list, and remove images - How to create, run, stop, and remove containers - That changes inside a container live only in the writable layer (and are lost when the container is removed, unless committed) - When to choose an image vs a container for distribution, persistence, or debugging

What's next? In the next lesson, you'll learn how to manage container state and data — specifically, how to use volumes and bind mounts so that data survives container restarts and removals. You'll combine your understanding of images and containers with persistent storage to build real-world applications with confidence.

Practice recap

Try this mini exercise: Pull the nginx image (docker pull nginx), run a container (docker run --name nginx-test -d nginx), then create a small HTML file inside the container (docker exec -it nginx-test bash and echo '<h1>Hello</h1>' > /usr/share/nginx/html/index.html). Visit http://localhost to see your modified content. Now stop and remove that container (docker rm -f nginx-test). Run another container from the same image — notice the original nginx welcome page is back. The changes were in the container's writable layer, not the image.

Common mistakes

  • Thinking that stopping a container destroys its writable layer — actually, the container stays on disk (with its layer) until you docker rm it.
  • Confusing docker images (list of blueprints) with docker ps (list of running or stopped containers).
  • Expecting changes made inside a container to appear in a new container started from the same image — they don't; the writable layer is per-container.
  • Deleting an image while a container created from it is still running — Docker allows this, but it can confuse beginners when they later try to run matching containers.

Variations

  1. Use docker commit to save a container's modified state as a new image — useful for quick snapshots but not recommended for production pipelines.
  2. Alternative terminology: some resources call images 'build artifacts' and containers 'runtime environments'.
  3. In Kubernetes, the distinction blurs slightly because Pods wrap containers, but the image vs container concept remains the same.

Real-world use cases

  • Deploying microservices: each service is built as an image and pushed to a registry; production clusters pull the image and run hundreds of containers from it.
  • CI/CD pipelines: a build step creates an image with tests and application code; subsequent pipeline stages run containers from that image for integration tests.
  • Data science workflows: an image defines the environment (Python, libraries, Jupyter), and each data scientist runs their own container with unique notebooks.

Key takeaways

  • Docker images are read-only blueprints; containers are running instances of those blueprints with a thin writable layer.
  • You can have many containers from one image, each with its own state, and changes inside a container are lost upon removal unless committed or persisted via volumes.
  • Image lifecycle: build, store, share. Container lifecycle: create, start, stop, remove. They are distinct objects managed by separate Docker commands.
  • Use docker images to see locally stored images and docker ps -a to see all containers (running or stopped).
  • For production, always rebuild and redeploy an image rather than modifying a running container — this ensures reproducibility.
  • Deleting an image does not stop running containers; they continue using a copy of the image's filesystem.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.