Docker images are read-only templates used to create containers. Think of them as blueprints or snapshots that contain:
Containers are running instances of Docker images. They are:
graph TD
A[Docker Image] -->|docker run| B[Container 1]
A -->|docker run| C[Container 2]
A -->|docker run| D[Container 3]
E[Image: Ubuntu 20.04] -->|run| F[Container: Web Server]
E -->|run| G[Container: Database]
E -->|run| H[Container: Cache]
style A fill:#e1f5fe
style E fill:#e1f5fe
style B fill:#fff3e0
style C fill:#fff3e0
style D fill:#fff3e0
style F fill:#fff3e0
style G fill:#fff3e0
style H fill:#fff3e0
Images are built using a layered filesystem. Each layer represents a change or addition:
┌─────────────────────────┐ ← Container Layer (Read/Write)
├─────────────────────────┤
│ Application Code │ ← Layer 4 (Read-Only)
├─────────────────────────┤
│ Dependencies │ ← Layer 3 (Read-Only)
├─────────────────────────┤
│ Runtime Environment │ ← Layer 2 (Read-Only)
├─────────────────────────┤
│ Base OS │ ← Layer 1 (Read-Only)
└─────────────────────────┘
graph LR
A[Image] -->|docker create| B[Created]
B -->|docker start| C[Running]
C -->|docker stop| D[Stopped]
C -->|docker pause| E[Paused]
E -->|docker unpause| C
D -->|docker start| C
D -->|docker rm| F[Removed]
B -->|docker rm| F
State | Description | Commands |
---|---|---|
Created | Container exists but not started | docker create |
Running | Container is actively running | docker start , docker run |
Stopped | Container stopped but still exists | docker stop |
Paused | Container paused (processes frozen) | docker pause |
Removed | Container deleted from system | docker rm |
# Pull image from Docker Hub
docker pull ubuntu:20.04
docker pull nginx:latest
docker pull node:18-alpine
# Pull from specific registry
docker pull gcr.io/google-containers/nginx
# List all images
docker images
# List with specific format
docker images --format "table \t\t"
# List image IDs only
docker images -q
# Inspect image details
docker inspect ubuntu:20.04
# View image history (layers)
docker history ubuntu:20.04
# Check image size and usage
docker system df
# Remove specific image
docker rmi ubuntu:20.04
# Remove image by ID
docker rmi 1a2b3c4d5e6f
# Remove unused images
docker image prune
# Remove all images
docker rmi $(docker images -q)
# Run container from image
docker run ubuntu:20.04
# Run with interactive terminal
docker run -it ubuntu:20.04 /bin/bash
# Run in background (detached)
docker run -d nginx:latest
# Run with custom name
docker run --name my-nginx -d nginx:latest
# Run with port mapping
docker run -p 8080:80 -d nginx:latest
# List running containers
docker ps
# List all containers (including stopped)
docker ps -a
# Start stopped container
docker start container-name
# Stop running container
docker stop container-name
# Restart container
docker restart container-name
# Remove container
docker rm container-name
# Execute command in running container
docker exec -it container-name /bin/bash
# View container logs
docker logs container-name
# Follow logs in real-time
docker logs -f container-name
# Copy files to/from container
docker cp file.txt container-name:/path/
docker cp container-name:/path/file.txt ./
# Pull and run Nginx
docker run -d \
--name my-web-server \
-p 8080:80 \
nginx:latest
# Access the server
curl http://localhost:8080
# Run MySQL database
docker run -d \
--name my-database \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=myapp \
-p 3306:3306 \
mysql:8.0
# Run Node.js development environment
docker run -it \
--name node-dev \
-v $(pwd):/app \
-w /app \
-p 3000:3000 \
node:18 \
/bin/bash
[registry]/[namespace]/[repository]:[tag]
Examples:
# Official images
ubuntu:20.04
nginx:latest
node:18-alpine
# User/organization images
mycompany/webapp:v1.0
username/myapp:latest
# Private registry
registry.company.com/team/app:production
# Tag existing image
docker tag ubuntu:20.04 my-ubuntu:custom
# Tag for registry
docker tag myapp:latest registry.company.com/myapp:v1.0
# Multiple tags for same image
docker tag myapp:latest myapp:stable
docker tag myapp:latest myapp:v1.0.0
Container Layer (Read/Write)
├── /var/log/app.log ← New files
├── /etc/config.conf ← Modified files
└── /tmp/cache/ ← Temporary files
Image Layers (Read-Only)
├── Layer 3: Application
├── Layer 2: Dependencies
├── Layer 1: Base OS
└── Layer 0: Kernel (Host)
Containers are ephemeral by default. To persist data:
# Using volumes
docker run -v mydata:/data ubuntu:20.04
# Using bind mounts
docker run -v /host/path:/container/path ubuntu:20.04
# Using tmpfs mounts
docker run --tmpfs /tmp ubuntu:20.04
FROM node:18-alpine
FROM ubuntu:20.04 # Not ubuntu:latest
RUN apt-get update && apt-get install -y \
curl \
vim \
&& rm -rf /var/lib/apt/lists/*
node_modules
.git
*.log
USER appuser
docker stop container-name # Sends SIGTERM
docker run --memory=512m --cpus=1.0 myapp
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost/ || exit 1
graph LR
A[Write Code] --> B[Build Image]
B --> C[Test Container]
C --> D{Tests Pass?}
D -->|No| A
D -->|Yes| E[Push Image]
E --> F[Deploy Container]
# Development
docker run -v $(pwd):/app -it node:18 /bin/bash
# Testing
docker run --rm -v $(pwd):/app node:18 npm test
# Production
docker build -t myapp:prod .
docker run -d myapp:prod
# Container exits immediately
docker logs container-name
# Check container processes
docker exec container-name ps aux
# Inspect container configuration
docker inspect container-name
# Monitor resource usage
docker stats container-name
# Run container with override
docker run -it --entrypoint /bin/bash image-name
# Check container filesystem changes
docker diff container-name
# Export container as tar
docker export container-name > container.tar
Concept | Description | Key Commands |
---|---|---|
Image | Read-only template | docker pull , docker images , docker rmi |
Container | Running instance | docker run , docker ps , docker stop |
Layer | Filesystem change | docker history , docker inspect |
Registry | Image storage | docker push , docker pull |
Understanding images and containers is fundamental to working with Docker effectively. Images serve as the foundation, while containers provide the runtime environment where your applications actually execute.