Featured image of post Docker Basics: Image vs Container

Docker Basics: Image vs Container

Understand the difference between Docker Image and Container - core concepts of Docker. Detailed guide with real examples for beginners.

Docker Image and Container - Two Essential Concepts

When starting with Docker, the two most important concepts you need to understand are Image and Container. Beginners often confuse them, but in reality, they play different roles in the Docker ecosystem. Image is like a recipe repository (cooking instructions), while Container is the actual execution (the prepared dish). 🍳

In this article, I’ll explain the detailed differences between Image and Container, how they work together, and provide real examples for better understanding.


I. What is a Docker Image?

A Docker Image is a template used to create a Container. It contains everything needed to run an application:

  • Operating system — usually minimal Linux
  • Runtime environment — Node.js, Python, Java, etc.
  • Application code
  • Dependencies (libraries)
  • Configuration files
  • Environment variables

1. Key Characteristics of Docker Image

  • Read-only: Image is read-only and cannot be changed after creation
  • Layered structure: Image is built from layers, each layer representing a command in Dockerfile
  • Reusable: The same image can be used to create multiple containers
  • Version-controlled: Each image has tags (e.g., 1.0, latest, alpine) for version management

Example of Image Structure:

LayerContent
Layer 1Base OS (Alpine Linux)
Layer 2System packages (curl, wget)
Layer 3Node.js runtime (18.x)
Layer 4Application code
Layer 5Environment variables

2. Common Image Commands

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Pull an image from Docker Hub
docker pull node:18-alpine

# List downloaded images
docker images

# Remove an unused image
docker image rm node:18-alpine

# Remove all unused images
docker image prune -a

# Build image from Dockerfile
docker build -t myapp:1.0 .

II. What is a Docker Container?

A Docker Container is a running instance created from a Docker Image. Container has:

  • Its own file system
  • Isolated network space
  • Independent processes and operations
  • Its own environment variables

1. Key Characteristics of Docker Container

  • Read-only base + Read-write layer: Container has a read-write layer that allows data changes
  • Isolated: Container is isolated from host and other containers
  • Stateful: Container can be in various states: running, stopped, paused, exited
  • Ephemeral: Containers can be created and deleted quickly (< 1 second)

Example of Container:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# Create and run container from image
docker run -d --name myapp node:18-alpine node server.js

# List running containers
docker ps

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

# Stop container
docker stop myapp

# Restart container
docker start myapp

# Remove container
docker rm myapp

# View container logs
docker logs myapp

2. Comparing Container with Virtual Machine

AspectDocker ContainerVirtual Machine
Operating SystemShare kernel with hostFull dedicated OS
Boot Time~ 1-2 seconds~ 1-2 minutes
Disk SizeMB (10-100 MB)GB (1-10 GB)
PerformanceNearly nativeNeeds virtualization overhead
Max Per HostHundredsTens

Docker Container Architecture Docker Container Architecture


III. Detailed Comparison: Image vs Container

For easy visualization, see the comparison table below:

Complete Comparison Table

AspectImageContainer
AnalogyRecipe repository (cooking recipe)Prepared dish
StateStatic (read-only)Dynamic (read-write)
ChangesCannot change after creationCan change while running
Quantity1 image creates N containersMany containers from 1 image
Creation TimeSlow (first build ~5-10 mins)Fast (< 1 second)
StorageStored in Docker cacheStored at runtime or in volumes
PortabilityEasy to share (push/pull)Only runs where Docker is installed
VersionHas tags for management (1.0, 2.0, latest)No separate version
NetworkNoHas isolated network
StorageStored in layersHas read-write layer on top of image

Relationship between Image and Container

1
2
3
4
5
6
7
8
9
Docker Image (Template)
    docker run
Docker Container (Running Instance)
    docker commit
Docker Image baru (updated)

Notes:

  • Image is like a class in Object Oriented Programming (OOP)
  • Container is like an object (instance of a class)
  • Use docker run to create container from image
  • Use docker commit to save container as a new image

IV. Real-World Example from Start to Finish

For better understanding, let’s do a detailed example:

1. Create Dockerfile (to build image)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Dockerfile
FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

CMD ["node", "server.js"]

2. Build image from Dockerfile

1
2
3
4
5
6
7
8
# Build image with name myapp and tag 1.0
docker build -t myapp:1.0 .

# View created image
docker images
# Output:
# REPOSITORY   TAG        IMAGE ID       CREATED        SIZE
# myapp        1.0        abc123def456   2 minutes ago  150MB

3. Create and run container from image

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Run container from image myapp:1.0
docker run -d \
  --name myapp-container \
  -p 3000:3000 \
  myapp:1.0

# View running containers
docker ps
# Output:
# CONTAINER ID   IMAGE       COMMAND            STATUS          PORTS
# xyz789ghi012   myapp:1.0   "node server.js"   Up 2 minutes    0.0.0.0:3000->3000/tcp

# View logs
docker logs myapp-container

4. Interact with container

1
2
3
4
5
6
# Access container shell
docker exec -it myapp-container sh

# Inside container — you can:
ls -la /app
curl http://localhost:3000

5. Remove container and image

1
2
3
4
5
6
7
8
# Stop container
docker stop myapp-container

# Remove container
docker rm myapp-container

# Remove image
docker rmi myapp:1.0

V. Best Practices with Image and Container

1. Image Management

  • ✅ Use specific versions (e.g., node:18.12-alpine instead of node:latest)
  • ✅ Reduce size using minimal base images (alpine, distroless)
  • ✅ Leverage layer cache by ordering commands properly
  • ✅ Use .dockerignore to exclude unnecessary files
  • ✅ Regularly remove unused images with docker image prune
1
2
3
4
# Example: Use specific image version
FROM node:18.12.1-alpine
# instead of
FROM node:latest

2. Container Management

  • ✅ Name containers clearly (--name app-container)
  • ✅ Use -d (detached mode) to run containers in background
  • ✅ Regularly check logs for debugging (docker logs -f)
  • ✅ Use volumes if data persistence is needed
  • ✅ Limit resources with --cpus, --memory
1
2
3
4
5
6
7
# Run container with resource limits
docker run -d \
  --name app \
  --cpus="1.5" \
  --memory="512m" \
  -p 8080:80 \
  myapp:1.0

Common Troubleshooting

1. Cannot create container from image

Error:

1
Error: Cannot start container from image

Causes:

  • Image hasn’t been built or pulled
  • Image is corrupted
  • Port is already in use by another container

Solution:

1
2
3
4
5
6
7
8
# Check if image exists
docker images | grep myapp

# Pull again if not present
docker pull myapp:1.0

# Rebuild image
docker build -t myapp:1.0 .

2. Container doesn’t persist data when stopped

Cause: Container is ephemeral, data inside will be lost when it stops or is removed.

Solution: Use Docker Volumes

1
2
3
4
5
6
7
8
# Create volume
docker volume create myapp-data

# Mount volume to container
docker run -d \
  --name app \
  -v myapp-data:/app/data \
  myapp:1.0

3. Container not accessible from outside

Error: Cannot access http://localhost:3000 when running container

Solution:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Ensure port is mapped from container → host
docker run -d \
  --name app \
  -p 3000:3000 \
  myapp:1.0

# For multi-container setup, use docker network
docker network create mynet
docker run -d --network mynet --name app1 myapp:1.0
docker run -d --network mynet --name app2 myapp:1.0

Implementation Notes 🔧

When applying to your project, remember these important points:

  • Don’t modify containers directly — Rebuild image with Dockerfile
  • Use docker-compose.yaml to manage multiple containers and dependencies
  • Use CI/CD to automatically build and push images to Docker Hub/Registry
  • Monitor resources with docker stats or Prometheus + Grafana
  • Backup data regularly from volumes

Best practices:

  • Always name images and containers clearly
  • Use specific tags for different environments (dev, staging, prod)
  • Write .dockerignore to reduce image size and speed up builds
  • Use multi-stage build to create minimal images

Troubleshooting:

  • When container crashes, check logs: docker logs <container-name>
  • When pulling fails, check network: ping registry-1.docker.io
  • When container can’t access files, mount volume with correct permissions

🎯 Conclusion

To summarize:

  • Docker Image = Recipe repository (read-only template) — Contains all settings needed to run an application
  • Docker Container = Prepared dish (running instance) — Container created from image with read-write layer
  • Image is static, Container is dynamic
  • Use docker run to create container from image
  • Use docker commit to update container as a new image

Now you understand the differences between Image and Container. Next step: learn how to use Dockerfile to build images and Docker Compose to manage multiple containers. 🚀

If you found this article helpful, remember to ⭐ star the repo or 📱 share with friends! 😊


References