Ctrl K

Docker Image and Container Mental Model

Understand Docker Hub, images, containers, tags, mounts, ports, startup commands, and common docker run flags.

Use this note as a practical mental model for pulling and running containers. It explains what Docker downloads, what starts at runtime, where data lives, and how common docker run flags change the container.

Image vs container

ConceptMeaning
ImagePackaged application template with userland, app files, libraries, dependencies, startup scripts, and default ENTRYPOINT or CMD
ContainerA running instance created from an image
Disposable containerContainer removed after exit, usually with --rm
Persistent dataData kept outside the disposable container through bind mounts or named volumes

Registries and pull

docker pull downloads an image from a container registry. Docker Hub is the default registry when no registry hostname is provided.

docker pull owner/image-name

# Equivalent default form
docker pull docker.io/owner/image-name:latest

# General form
docker pull registry/namespace/image:tag
docker pull nginx
docker pull postgres:16
docker pull redis:7-alpine
docker pull docker.io/library/ubuntu:24.04
docker pull ghcr.io/owner/image:tag

Pull vs run

CommandEffect
docker pull image-nameDownloads or updates the image locally
docker run image-nameCreates and starts a new container from the image
docker run missing-imagePulls automatically first, then starts the container

Use explicit docker pull when you want to update the local image before running it.

Tags and layers

docker pull image-name:latest
docker pull image-name:1.2.3
  • latest is convenient but can change over time.
  • Fixed tags are better for stable deployments.
  • Images are built in layers such as base distro, system packages, language runtime, app code, and startup scripts.
  • docker pull downloads only missing or changed layers.

Container OS and host kernel

The image provides the container userland, such as Debian, Ubuntu, Alpine, or Fedora. The host provides the Linux kernel. An Ubuntu container on an Arch host runs Ubuntu binaries and libraries while sharing the Arch host kernel.

docker run --rm image-name cat /etc/os-release
docker run --rm image-name uname -a
  • /etc/os-release shows the container distro.
  • uname -a shows the host kernel because Linux containers share the host kernel.

Startup behavior

ENTRYPOINT and CMD define what starts by default when the container runs.

docker inspect image-name --format '
Entrypoint: {{json .Config.Entrypoint}}
Cmd:        {{json .Config.Cmd}}
WorkingDir: {{json .Config.WorkingDir}}
'
# Use the default image startup behavior
docker run image-name

# Start a shell instead of the default application
docker run -it --rm --entrypoint bash image-name
docker run -it --rm --entrypoint sh image-name

# Pass command arguments to the image's default entrypoint behavior
docker run --rm image-name command args

Interactive and disposable runs

FlagMeaning
-iKeep STDIN open
-tAllocate a terminal
-itUse for shells, CLIs, TUIs, REPLs, and interactive agents
--rmRemove the container automatically after it exits
docker run -it --rm image-name
docker run image-name

Bind mounts

A bind mount makes a host path appear inside the container. Reads and writes are bidirectional.

docker run -it --rm \
  -v "$HOME/my-data:/data" \
  image-name
Host pathContainer path
$HOME/my-data/data
$HOME/my-data/file.txt/data/file.txt
  • If the image already has files at /data, the bind mount hides those image files while the mount is active.
  • The mounted path is the host folder, not image contents plus host contents.

Named volumes

docker volume create app-data

docker run -it --rm \
  -v app-data:/data \
  image-name
Storage typeBest use
Bind mountExplicit host paths, projects, configs, and local files you want to inspect from the host
Named volumeDocker-managed persistent data for databases and app state

Workspace pattern

A common project pattern is to mount the current host folder into /workspace and start the container there.

docker run -it --rm \
  -v "$PWD:/workspace" \
  -w /workspace \
  image-name

Environment and user

docker run --rm \
  -e APP_ENV=development \
  -e API_KEY="$API_KEY" \
  image-name
docker run --rm \
  --user "$(id -u):$(id -g)" \
  -v "$PWD:/workspace" \
  image-name
  • -e passes environment variables into the container for config, credentials, runtime settings, and user IDs.
  • --user runs the process as the host UID and GID, which helps avoid root-owned files in bind-mounted folders.
  • Some images use APP_UID and APP_GID style environment variables instead of --user.

Ports and background services

# Host port 8080 maps to container port 80
docker run --rm \
  -p 8080:80 \
  image-name

# Localhost-only binding on the host
docker run --rm \
  -p 127.0.0.1:8080:80 \
  image-name
docker run -d \
  --name app-name \
  --restart unless-stopped \
  image-name
  • -d runs the container in the background.
  • --name gives the container a stable name.
  • --restart unless-stopped restarts the container after reboot or crash unless it was manually stopped.

Inspect containers

CommandUse
docker psShow running containers
docker ps -aShow running and stopped containers
docker logs -f container-nameFollow container logs
docker exec -it container-name bashEnter a running container with bash
docker exec -it container-name shEnter a running container with sh
docker inspect container-nameShow container metadata

Resolve name conflicts

Docker container names are unique across the Docker daemon. A stopped container can still hold a name.

docker ps -a --filter "name=test"
docker rm -f test

Inspect image contents

Start a temporary shell without mounts to inspect what the image ships by default.

docker run -it --rm \
  --entrypoint sh \
  image-name
cat /etc/os-release
pwd
ls -lah /
ls -lah /opt
find / -maxdepth 2 -type d 2>/dev/null | head

Add mounts when you want to compare raw image contents with runtime mounted contents.

docker run -it --rm \
  -v "$HOME/my-data:/data" \
  --entrypoint sh \
  image-name

Clean up

docker system prune

docker volume ls
docker volume rm volume-name
  • docker system prune removes unused containers, networks, images, and build cache.
  • It does not remove active containers.
  • Remove named volumes only when you are sure the stored data is no longer needed.

Mount safety

PatternRisk
-v "$PWD:/workspace"Safer project-scoped workspace
-v "$HOME/safe-folder:/data"Safer explicit data folder
-v "$HOME:/workspace"Risky because it exposes the whole home directory
-v "/:/host"Risky because it exposes the host root filesystem
-v "$HOME/.ssh:/root/.ssh"Risky because it exposes SSH credentials
-v "/var/run/docker.sock:/var/run/docker.sock"Risky because it gives host-level Docker control
--privilegedVery risky because it grants broad container privileges
--network hostVery risky because it removes normal network isolation

Mount only what the container should access.

Reusable run template

docker run -it --rm \
  --name app-test \
  -e APP_ENV=development \
  -v "$HOME/app-data:/data" \
  -v "$PWD:/workspace" \
  -w /workspace \
  image-name:tag
  • Replace app-test with the container name.
  • Replace APP_ENV with the environment variables the image needs.
  • Replace $HOME/app-data with a persistent data path if needed.
  • Replace $PWD with the project or workspace path.
  • Replace image-name:tag with the Docker Hub or registry image.