Docker & Kubernetes Complete Guide Part 2: Docker Images and Container Management
Master Image Layers, Container Lifecycle, and Essential Docker Commands
Introduction: Mastering Docker Core Concepts
In Part 1, we learned the basic concepts and installation methods of Docker. In this Part 2, we will deeply cover the core concepts and management methods of Images and Containers that are essential for effectively using Docker in practice.
By accurately understanding the relationship between images and containers and learning various command options, you can utilize Docker much more efficiently. Especially the various options of docker run are very frequently used in practice, so you must master them.
1. Difference Between Images and Containers
1.1 What is an Image?
A Docker Image is a read-only template for creating containers. It includes everything needed to run an application (code, runtime, libraries, environment variables, configuration files, etc.).
Analogy: An image is similar to a program's "installation file" or "class definition". It's the state before execution.
1.2 What is a Container?
A Docker Container is a runnable instance of an image. It is created based on an image and has its own file system, network, and process space.
Analogy: A container is similar to a program's "running process" or "object instance". It's the state that is actually operating.
1.3 Relationship Between Images and Containers
+-------------------------------------------------------------+
| Docker Image |
| (Read-Only Template) |
| +----------------------------------------------------------+|
| | Application Code + Dependencies + Configuration ||
| +----------------------------------------------------------+|
+-------------------------------------------------------------+
|
| docker run
v
+-------------------------------------------------------------+
| Docker Container 1 |
| (Running Instance) |
| +-----------------------+ +---------------------------+ |
| | Image Layers (RO) | | Writable Layer (RW) | |
| | (Read-Only) | | (Writable) | |
| +-----------------------+ +---------------------------+ |
+-------------------------------------------------------------+
|
| docker run (with same image)
v
+-------------------------------------------------------------+
| Docker Container 2 |
| (Independent Instance) |
+-------------------------------------------------------------+
1.4 Key Differences Summary
| Aspect | Image | Container |
|---|---|---|
| State | Static | Dynamic |
| Modifiability | Read-Only (Immutable) | Writable (Mutable) |
| Storage Location | Local or Registry | Host Memory/Disk |
| Creation Method | Dockerfile build or pull | docker run/create |
| Relationship | One image = Multiple containers | One container = One image |
2. Image Layer Concept
2.1 What is a Layer?
Docker images are composed of multiple read-only layers. Each layer stores only the differences (delta) from the previous layer. This structure is implemented using Union File System (UnionFS).
+------------------------------------------+
| Container Layer (R/W) | <- Added when container runs
+------------------------------------------+
| Layer 4: CMD/ENTRYPOINT | <- Image layers
+------------------------------------------+
| Layer 3: Application Code |
+------------------------------------------+
| Layer 2: Dependencies |
+------------------------------------------+
| Layer 1: Base OS (Ubuntu) |
+------------------------------------------+
2.2 Advantages of Layers
- Storage Efficiency: Identical layers are shared across multiple images, preventing duplicate storage.
- Fast Builds: Only changed layers are rebuilt, reducing build time.
- Fast Deployment: Already existing layers are not downloaded again.
- Caching: Cache can be effectively utilized during the build process.
2.3 Checking Image Layers
# Check image layer history
docker history nginx
# Example output:
IMAGE CREATED CREATED BY SIZE
a6bd71f48f68 2 weeks ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon... 0B
<missing> 2 weeks ago /bin/sh -c #(nop) STOPSIGNAL SIGQUIT 0B
<missing> 2 weeks ago /bin/sh -c #(nop) EXPOSE 80 0B
...
# Check detailed image information (including layers)
docker inspect nginx
# Extract only layer list
docker inspect --format='{{range .RootFS.Layers}}{{println .}}{{end}}' nginx
3. Image Management Commands
3.1 docker pull - Download Images
Downloads images from Docker Hub or other registries.
# Basic usage (latest tag)
docker pull nginx
# Specify version (tag)
docker pull nginx:1.25.3
docker pull nginx:alpine # Alpine Linux based lightweight version
# Pull from specific registry
docker pull gcr.io/google-containers/nginx
# Pull all tags (Warning: uses a lot of space)
docker pull -a nginx
3.2 docker images - List Images
# List all images
docker images
docker image ls # Same command
# Example output:
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest a6bd71f48f68 2 weeks ago 187MB
nginx alpine 8e75cbc5b25c 2 weeks ago 41.1MB
ubuntu 22.04 174c8c134b2a 3 weeks ago 77.8MB
# Filter specific image
docker images nginx
# Output only image IDs
docker images -q
# Show dangling images (images without tags)
docker images -f "dangling=true"
3.3 docker push - Upload Images
# Login to Docker Hub
docker login
# Tag image (Docker Hub format: username/repository:tag)
docker tag my-app:latest myusername/my-app:v1.0
# Push image
docker push myusername/my-app:v1.0
3.4 docker rmi - Delete Images
# Delete image (by name:tag or image ID)
docker rmi nginx:alpine
docker rmi a6bd71f48f68
# Force delete (even if container is using it)
docker rmi -f nginx
# Delete dangling images
docker image prune
# Delete all unused images
docker image prune -a
4. Container Lifecycle
4.1 Container State Transition Diagram
docker create
[Image] -------------------------> [Created]
|
| docker start
v
[Running] <-----------+
| |
docker stop | | docker restart
docker kill | |
v |
[Stopped] ------------+
|
| docker rm
v
[Removed]
4.2 docker create - Create Container
docker create only creates a container without starting it.
# Create container (do not start)
docker create --name my-nginx nginx
# Check created container
docker ps -a
# STATUS: Created
4.3 docker start - Start Container
# Start container
docker start my-nginx
# Start multiple containers simultaneously
docker start container1 container2 container3
# Start in interactive mode
docker start -i my-container
4.4 docker stop - Stop Container
# Graceful shutdown (SIGTERM signal)
docker stop my-nginx
# Specify timeout (default 10 seconds)
docker stop -t 30 my-nginx # Force stop after 30 seconds
# Stop all running containers
docker stop $(docker ps -q)
4.5 docker rm - Delete Container
# Delete stopped container
docker rm my-nginx
# Force delete (even if running)
docker rm -f my-nginx
# Also delete volumes
docker rm -v my-nginx
# Delete all stopped containers
docker container prune
# Delete all containers (force)
docker rm -f $(docker ps -aq)
5. docker run Options in Detail
docker run performs docker create + docker start at once. It's the most frequently used command, so you need to know the options well.
5.1 Basic Options
# Basic format
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
# Basic execution
docker run nginx
# Assign name (--name)
docker run --name my-nginx nginx
# Run in background (-d, --detach)
docker run -d nginx
# Interactive mode (-i, -t, -it)
docker run -it ubuntu bash
# -i: Enable stdin
# -t: Allocate pseudo-TTY
# Auto-remove container on exit (--rm)
docker run --rm nginx curl localhost
5.2 Port Mapping (-p, --publish)
# host_port:container_port
docker run -d -p 8080:80 nginx
# Host port 8080 -> Container port 80
# Multiple port mappings
docker run -d -p 8080:80 -p 443:443 nginx
# Bind to specific IP only
docker run -d -p 127.0.0.1:8080:80 nginx
# Auto-assign host port (specify only container port)
docker run -d -p 80 nginx
docker port my-nginx # Check assigned port
# Auto-map all exposed ports (-P)
docker run -d -P nginx
5.3 Volume Mount (-v, --volume, --mount)
# Mount host directory (Bind Mount)
docker run -d -v /host/path:/container/path nginx
docker run -d -v $(pwd)/html:/usr/share/nginx/html nginx
# Read-only mount
docker run -d -v /host/path:/container/path:ro nginx
# Use Named Volume
docker volume create my-data
docker run -d -v my-data:/app/data mysql
# --mount option (more explicit)
docker run -d --mount type=bind,source=/host/path,target=/container/path nginx
docker run -d --mount type=volume,source=my-data,target=/app/data mysql
5.4 Environment Variables (-e, --env)
# Set environment variable
docker run -d -e MYSQL_ROOT_PASSWORD=secret mysql
# Multiple environment variables
docker run -d \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=mydb \
-e MYSQL_USER=user \
-e MYSQL_PASSWORD=pass \
mysql
# Read environment variables from file (--env-file)
docker run -d --env-file .env mysql
5.5 Network Options (--network)
# Default bridge network
docker run -d nginx
# Use host network (container uses host network directly)
docker run -d --network host nginx
# No network
docker run -d --network none nginx
# User-defined network
docker network create my-network
docker run -d --network my-network --name web nginx
docker run -d --network my-network --name db mysql
5.6 Other Useful Options
# Set working directory (-w, --workdir)
docker run -w /app node npm install
# Specify user (-u, --user)
docker run -u 1000:1000 nginx
# Restart policy (--restart)
docker run -d --restart always nginx # Always restart
docker run -d --restart unless-stopped nginx # Restart until manually stopped
docker run -d --restart on-failure:3 nginx # Restart up to 3 times on failure
6. docker exec and attach
6.1 docker exec - Execute Commands in Running Container
docker exec runs a new process in an already running container.
# Basic usage
docker exec my-nginx ls -la
# Interactive shell access (most commonly used)
docker exec -it my-nginx bash
docker exec -it my-nginx sh # For containers without bash
# Run as specific user
docker exec -u root my-nginx whoami
# Specify working directory
docker exec -w /etc/nginx my-nginx cat nginx.conf
# Run in background
docker exec -d my-nginx touch /tmp/test.txt
6.2 docker attach - Connect to Running Container
docker attach connects stdin/stdout to the container's main process (PID 1).
# Connect to container
docker attach my-container
# Disable signal proxy
docker attach --sig-proxy=false my-container
6.3 Differences Between exec and attach
| Aspect | docker exec | docker attach |
|---|---|---|
| Connection Target | Creates new process | Connects to main process (PID 1) |
| Use Cases | Debugging, admin tasks | Log viewing, interactive apps |
| Exit Impact | No impact on container | Ctrl+C may stop container |
| Multiple Connections | Multiple sessions possible | Same output shared |
| Recommendation | Recommended for most cases | Only for special cases |
7. Container Logs (docker logs)
7.1 Basic Log Commands
# Output all logs
docker logs my-nginx
# Real-time log streaming (-f, --follow)
docker logs -f my-nginx
# Output only last N lines (--tail)
docker logs --tail 100 my-nginx
# Include timestamps (-t, --timestamps)
docker logs -t my-nginx
# Logs since specific time (--since)
docker logs --since 2026-01-22T10:00:00 my-nginx
docker logs --since 1h my-nginx # Within last 1 hour
docker logs --since 30m my-nginx # Within last 30 minutes
# Combined example
docker logs -f --tail 50 -t my-nginx
7.2 Log Driver Settings
# JSON file log driver (default)
docker run -d --log-driver json-file nginx
# Set log options
docker run -d \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginx
# Disable logging
docker run -d --log-driver none nginx
8. Resource Limits (--memory, --cpus)
8.1 Memory Limits
# Memory limit (--memory, -m)
docker run -d -m 512m nginx
docker run -d --memory 1g nginx
# Memory + Swap limit
docker run -d -m 512m --memory-swap 1g nginx
# Memory reservation (soft limit)
docker run -d -m 1g --memory-reservation 512m nginx
8.2 CPU Limits
# CPU count limit (--cpus)
docker run -d --cpus 1.5 nginx # 1.5 CPUs
docker run -d --cpus 0.5 nginx # 0.5 CPU (50%)
# CPU share weight (--cpu-shares)
docker run -d --cpu-shares 512 nginx # Default: 1024
# Pin to specific CPU cores (--cpuset-cpus)
docker run -d --cpuset-cpus 0,1 nginx # Use only CPU 0, 1
docker run -d --cpuset-cpus 0-3 nginx # Use CPU 0~3
8.3 Comprehensive Example
# Production environment resource limit example
docker run -d \
--name production-app \
--memory 2g \
--memory-reservation 1g \
--cpus 2 \
--restart unless-stopped \
--log-opt max-size=50m \
--log-opt max-file=5 \
-p 8080:80 \
my-app:latest
# Real-time resource usage monitoring
docker stats
# Monitor specific container
docker stats my-nginx
# One-time resource usage check
docker stats --no-stream
8.4 Change Resources on Running Container
# Change memory limit
docker update --memory 1g --memory-swap 2g my-container
# Change CPU limit
docker update --cpus 2 my-container
# Change restart policy
docker update --restart unless-stopped my-container
9. Conclusion and Next Steps
In this Part 2, we've deeply studied the core concepts of Docker: images and containers.
Key Summary
- Image vs Container: An image is a read-only template, a container is a runnable instance.
- Image Layers: A layered structure for efficient storage and builds.
- Image Commands: Manage images with
pull,push,images,rmi. - Container Lifecycle: Manage with
create,start,stop,restart,rm. - docker run Options:
-d,-p,-v,-e,--nameare essential. - exec vs attach: Use
execin most cases. - Log Management:
docker logsand log driver settings are important. - Resource Limits: Stable operations with
--memory,--cpus.
Preview of Next Part
In Part 3, we will cover Dockerfile Writing and Image Building:
- Dockerfile basic syntax
- Key instructions (FROM, RUN, COPY, ADD, CMD, ENTRYPOINT, etc.)
- Multi-stage builds
- Image optimization techniques
- Best practices
To effectively use Docker in practice, it's important to hands-on practice the commands learned in this part. Try combining various options and become familiar with them!