Skip to main content

Docker Images vs Containers

A Docker image is a read-only package (layers + metadata). A Docker container is a running (or stopped) instance of an image—a live process with a writable top layer.

Docker container vs image (quick difference)

  • Image: immutable blueprint, stored as name:tag (or digest). Built from a Dockerfile.
  • Container: runtime instance created from an image with its own ID, filesystem overlay, and networking.

One image → many containers.

What is a Docker image?

A Docker image contains:

  • OS/userland files (layered filesystem)
  • default command/entrypoint
  • environment metadata (EXPOSE, WORKDIR, etc.)

Common questions:

  • What are docker images? Versioned artifacts you build/pull and run.
  • What is in a docker image? Files + config, not “running state”.

What is a Docker container (and image)?

A container is:

  • an image + a writable layer
  • a process namespace (PID 1 inside the container)
  • networking and mounts (ports, volumes)

Inspect images and containers

# docker images (list local images)
docker images

# show docker containers running
docker ps

# list all containers (including stopped)
docker ps -a

Run a Docker container from an image

If you already have an image locally:

docker run --name myapp-01 -p 3000:3000 myapp:1.0

Run in the background (docker run background):

docker run -d --name myapp-01 -p 3000:3000 myapp:1.0

If the image is not local, Docker pulls it automatically:

docker run -d --name redis-01 redis:7

Step-by-step: build an image from a Dockerfile, then run it

Create package.json, app.js, and Dockerfile:

package.json

{
"name": "simple-app",
"version": "1.0.0",
"scripts": { "start": "node app.js" },
"dependencies": {}
}

app.js

const http = require("http");
const port = process.env.PORT || 3000;
http.createServer((req, res) => res.end("Hello from Docker!")).listen(port);

Dockerfile

FROM node:18-slim
WORKDIR /app
COPY package.json ./
COPY app.js ./
EXPOSE 3000
CMD ["npm", "start"]

Build (docker build image from dockerfile):

docker build -t myapp:1.0 .

Verify (docker images):

docker images myapp

Run (how to run a docker image / start docker from image):

docker run -d --name myapp-01 -p 3000:3000 myapp:1.0

Where is the Docker image stored?

Docker stores images in its local data directory (managed by the Docker Engine). You usually don’t touch it directly; you manage it with docker images, docker rmi, and docker system df.

Check disk usage:

docker system df

How to remove Docker images (and containers)

Stop and remove a container:

docker stop myapp-01
docker rm myapp-01

Remove an image:

docker rmi myapp:1.0

Remove all unused images/containers/networks:

docker system prune

If an image is “in use”, remove the containers that reference it first:

docker ps -a --filter ancestor=myapp:1.0

Docker make image from container (save container to image)

You can save a container’s current state as a new image:

docker commit myapp-01 myapp:1.1

This is sometimes useful for quick debugging or capturing a one-off change, but it’s not ideal for reproducible builds.

Preferred: change the Dockerfile and rebuild.

How to edit a Docker image (the practical way)

Images are immutable. To “edit” an image:

  1. change the Dockerfile (or app code)
  2. rebuild with docker build
  3. run a new container

If you need an interactive debug shell:

docker exec -it myapp-01 sh

Changes inside the container are not in the image unless you docker commit (not recommended for production workflows).

Docker image size tips

  • Use .dockerignore to avoid huge build contexts.
  • Prefer slim bases (or multi-stage builds).
  • Keep layers small and stable (copy dependency files first, then source).

Python Dockerfile: ubuntu image or python image?

If you’re building a Python app:

  • use python:3.x-slim for most cases (smaller, simpler)
  • use ubuntu only if you need OS-level packages or a very custom base

Example base choices:

  • FROM python:3.12-slim
  • FROM ubuntu:24.04 (then install Python yourself)

Key takeaways

  • Image = static blueprint. Container = running instance of that blueprint.
  • To run docker container from image, use docker run (add -d for background).
  • To build docker image from Dockerfile, use docker build -t name:tag .
  • To remove docker images, remove dependent containers first, then docker rmi.
  • Use volumes for persistent data; container filesystem changes are ephemeral.