Excellent! Now let's run some real containers and learn the basic Docker commands.
Understanding What We'll Do
Before we start, quick overview:
We'll learn to:
├── Pull images from Docker Hub
├── Run containers
├── See running containers
├── Stop containers
├── Remove containers
└── Basic container management
Think of it like learning to drive:
- Pull image = Getting a car from the dealer
- Run container = Starting the car
- Stop container = Parking the car
- Remove container = Selling the car
Command 1: docker pull (Download Images)
What is docker pull?
Simple Definition:
docker pull = Downloads a Docker image from Docker Hub to your computer.
Syntax:
docker pull IMAGE_NAME
Let's Pull Our First Image - Nginx
Nginx = A popular web server (serves websites)
Open Command Prompt or PowerShell and type:
docker pull nginx
What you'll see:
Using default tag: latest
latest: Pulling from library/nginx
a2abf6c4d29d: Pull complete ← Downloading layer 1
a9edb18cadd1: Pull complete ← Downloading layer 2
589b7251471a: Pull complete ← Downloading layer 3
186b1aaa4aa6: Pull complete ← Downloading layer 4
b4df32aa5a72: Pull complete ← Downloading layer 5
a0bcbecc962e: Pull complete ← Downloading layer 6
Digest: sha256:xxxxxxxxxxxxx
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
✓ Download complete!
What happened?
Step 1: Docker contacted Docker Hub
└── "Do you have nginx image?"
Step 2: Docker Hub responded
└── "Yes! Here it is" (sends the image)
Step 3: Docker downloaded in layers
└── Images are split into layers for efficiency
Step 4: Image stored on your computer
└── Ready to use anytime!
Understanding Image Tags
What is a tag?
Image Name Format:
IMAGE_NAME:TAG
Examples:
├── nginx:latest ← Latest version (default)
├── nginx:1.25 ← Specific version 1.25
├── nginx:alpine ← Lightweight version
└── nginx:1.25-alpine ← Version 1.25, lightweight
If you don't specify tag:
docker pull nginx
↓
Automatically uses: nginx:latest
Try pulling different versions:
# Pull specific version
docker pull nginx:alpine
# Pull another popular image
docker pull ubuntu
# Pull Python
docker pull python:3.11
Command 2: docker images (List Downloaded Images)
Now let's see what images we have!
docker images
Output you'll see:
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 2 weeks ago 141MB
nginx alpine 8e75cbc5b25c 2 weeks ago 41MB
ubuntu latest ba6acccedd29 3 weeks ago 77.8MB
python 3.11 a5d7930b60cc 4 weeks ago 1.01GB
hello-world latest feb5d9fea6a5 2 years ago 13.3kB
Understanding the columns:
REPOSITORY = Image name (nginx, ubuntu, etc.)
TAG = Version (latest, alpine, 3.11)
IMAGE ID = Unique identifier (first 12 chars of hash)
CREATED = When this image was built
SIZE = How much space it takes on disk
Example:
nginx:latest = 141MB (full featured)
nginx:alpine = 41MB (lightweight, only essentials)
Notice:
- hello-world is tiny (13.3kB!)
- Python is large (1.01GB - includes entire Python environment)
- Alpine versions are smaller (minimal Linux)
Command 3: docker run (Start a Container)
This is the most important command! Let's run nginx web server.
Basic docker run
docker run nginx
What happens:
/docker-entrypoint.sh: Configuration complete
nginx: [notice] starting nginx process
← Terminal seems "stuck"
← This is NORMAL! Container is running
← Nginx is working in the foreground
To stop it:
Press Ctrl + C
You'll see:
nginx: signal process terminated
← Container stopped
Problem: Can't Access the Web Server
You ran nginx, but if you open browser and go to http://localhost, nothing appears!
Why?
Container is running in ISOLATION:
├── Nginx is running inside container
├── Container has its own network
├── Port 80 inside container
└── Your computer can't access it!
Like having a shop inside a locked building:
├── Shop is open (nginx running)
├── But door is locked (no port mapping)
└── Customers can't enter!
Solution: Port Mapping
We need to "open the door" - map container port to your computer port.
Stop the previous container (Ctrl + C if still running)
Run with port mapping:
docker run -p 8080:80 nginx
Understanding -p flag:
-p 8080:80
Format: -p HOST_PORT:CONTAINER_PORT
8080 = Port on YOUR computer (host)
80 = Port inside container
Meaning:
├── Traffic to localhost:8080 (your computer)
│ ↓
└── Goes to port 80 inside container (nginx)
Visual:
Your Computer Container
┌────────────────┐ ┌──────────┐
│ │ │ │
│ Port 8080 ────┼─────────►│ Port 80 │
│ │ mapped │ │
│ Browser │ │ Nginx │
│ localhost:8080│ │ │
└────────────────┘ └──────────┘
Test the Web Server
With container running (terminal looks "stuck"):
Open your web browser
Go to: http://localhost:8080
You should see:
┌─────────────────────────────────┐
│ Welcome to nginx! │
│ │
│ If you see this page, the │
│ nginx web server is │
│ successfully installed and │
│ working. │
└─────────────────────────────────┘
🎉 Congratulations! Your nginx container is running!
What just happened?
You in browser:
├── Visit localhost:8080
│ ↓
Your computer:
├── Port 8080 receives request
│ ↓
Docker:
├── Forwards to container port 80
│ ↓
Nginx in container:
├── Receives request
├── Sends back HTML page
│ ↓
Your browser:
└── Displays the page!
Running Containers in Background (Detached Mode)
Problem: Terminal is "stuck" - you can't use it while container runs.
Solution: Run container in background (detached mode)
Stop current container (Ctrl + C)
Run in detached mode:
docker run -d -p 8080:80 nginx
Understanding -d flag:
-d = Detached mode (background)
Output:
a3c5b8f9e1d7c2a4b6e8f0d1c3a5b7e9f1d3c5a7b9e1f3d5c7a9b1e3f5d7c9
↑ This is the Container ID
What happened:
Container started:
├── Running in background ✓
├── Terminal is free to use ✓
├── Container ID displayed
└── Nginx still working at localhost:8080
Check browser:
http://localhost:8080
← Still works! ✓
Command 4: docker ps (List Running Containers)
Let's see our running containers!
docker ps
Output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a3c5b8f9e1d7 nginx "/docker-entrypoint.…" 30 seconds ago Up 29 seconds 0.0.0.0:8080->80/tcp eager_darwin
Understanding the columns:
CONTAINER ID = Unique ID (short version)
a3c5b8f9e1d7
IMAGE = Which image it's using
nginx
COMMAND = Command running inside
/docker-entrypoint.sh nginx
CREATED = When container was created
30 seconds ago
STATUS = Current state
Up 29 seconds (running)
PORTS = Port mapping
0.0.0.0:8080->80/tcp
(Your port 8080 → Container port 80)
NAMES = Random name Docker gave
eager_darwin
(You can use this instead of ID)
Command 5: docker ps -a (List ALL Containers)
See all containers (including stopped ones):
docker ps -a
Output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a3c5b8f9e1d7 nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp eager_darwin
b4d6c9f1e3a5 nginx "/docker-entrypoint.…" 5 minutes ago Exited (0) 3 minutes ago romantic_curie
c7e9f2d4a6b8 hello-world "/hello" 10 minutes ago Exited (0) 10 minutes ago clever_turing
Notice:
Running containers:
└── STATUS: Up 2 minutes
Stopped containers:
└── STATUS: Exited (0) X minutes ago
↑
Exit code (0 = normal exit)
Command 6: docker stop (Stop a Running Container)
Let's stop our nginx container.
Method 1: Using Container ID
docker stop a3c5b8f9e1d7
# You don't need full ID, first few characters work:
docker stop a3c5
Method 2: Using Container Name
docker stop eager_darwin
Output:
a3c5b8f9e1d7
← Container ID returned
Container stopped ✓
Verify it stopped:
docker ps
# No containers shown (none running)
docker ps -a
# Shows container with STATUS: Exited
Try accessing in browser:
http://localhost:8080
← Connection refused (container stopped)
Command 7: docker start (Restart a Stopped Container)
Start the stopped container again:
docker start a3c5
# Or using name:
docker start eager_darwin
Output:
a3c5b8f9e1d7
← Container started
Check it's running:
docker ps
# Container appears in list again
Browser test:
http://localhost:8080
← Works again! ✓
Command 8: docker logs (See Container Output)
See what's happening inside a container:
docker logs a3c5
Output (nginx logs):
/docker-entrypoint.sh: Configuration complete
172.17.0.1 - - [19/Feb/2026:10:30:15 +0000] "GET / HTTP/1.1" 200 615
172.17.0.1 - - [19/Feb/2026:10:30:16 +0000] "GET /favicon.ico HTTP/1.1" 404 153
Understanding logs:
Each line = One request to nginx:
172.17.0.1 = Your IP address
GET / = Requested homepage
HTTP/1.1 = HTTP protocol version
200 = Success status code
615 = Response size (bytes)
Follow logs in real-time:
docker logs -f a3c5
# -f = follow (like tail -f)
# New logs appear as they happen
# Press Ctrl + C to stop following
Now refresh browser (http://localhost:8080) and watch logs appear live!
Command 9: docker exec (Execute Commands Inside Container)
Run commands inside a running container.
Example: Access nginx container's shell
docker exec -it a3c5 /bin/bash
Understanding the flags:
-i = Interactive (keep connection open)
-t = TTY (gives you a terminal)
/bin/bash = Command to run (bash shell)
What happens:
Your terminal changes:
root@a3c5b8f9e1d7:/#
↑ ↑
root user container ID
You're now INSIDE the container! ✓
Try some commands inside container:
# See where you are
pwd
# Output: /
# List files
ls
# Output: bin boot dev etc home lib ...
# Check nginx is running
ps aux | grep nginx
# Shows nginx processes
# See nginx config
cat /etc/nginx/nginx.conf
# Exit container
exit
# Back to your normal terminal
Command 10: docker rm (Remove Container)
Delete a stopped container.
First, stop the container if running:
docker stop a3c5
Then remove it:
docker rm a3c5
Output:
a3c5b8f9e1d7
← Container removed
Verify:
docker ps -a
# Container is gone from the list
Remove multiple containers:
docker rm container1 container2 container3
Force remove (stop + remove):
docker rm -f a3c5
# -f = force (stops and removes in one command)
Command 11: docker rmi (Remove Image)
Delete a downloaded image.
Important: You must remove all containers using this image first!
# Remove nginx image
docker rmi nginx
# Or using image ID:
docker rmi 605c77e624dd
If image is in use:
Error: image is being used by stopped container
Solution:
1. docker ps -a (find containers using this image)
2. docker rm CONTAINER_ID (remove those containers)
3. docker rmi nginx (now you can remove image)
Remove multiple images:
docker rmi nginx ubuntu python
Running a Different Container - Ubuntu
Let's try running Ubuntu Linux!
docker run -it ubuntu
Understanding -it flags:
-i = Interactive
-t = TTY (terminal)
-it together = Interactive terminal session
What happens:
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
... downloading ...
root@b8d7c9f3e5a1:/#
↑
You're now inside Ubuntu container!
Try Linux commands:
# Check Ubuntu version
cat /etc/os-release
# Update package lists
apt-get update
# Install a program
apt-get install curl -y
# Use curl
curl https://www.google.com
# Exit
exit
When you exit:
Container stops automatically
(Because you exited the main process)
Giving Containers Custom Names
Instead of random names, give your own:
docker run -d -p 8080:80 --name my-nginx nginx
Now:
docker ps
NAMES
my-nginx ← Your custom name!
# Use it in commands:
docker stop my-nginx
docker start my-nginx
docker logs my-nginx
docker rm my-nginx
Much easier to remember!
Running Multiple Containers
Run multiple nginx containers on different ports:
# Container 1 on port 8080
docker run -d -p 8080:80 --name nginx1 nginx
# Container 2 on port 8081
docker run -d -p 8081:80 --name nginx2 nginx
# Container 3 on port 8082
docker run -d -p 8082:80 --name nginx3 nginx
Check all running:
docker ps
Access them:
http://localhost:8080 ← nginx1
http://localhost:8081 ← nginx2
http://localhost:8082 ← nginx3
All running simultaneously! ✓
Summary of Basic Commands
Commands we learned:
# Download images
docker pull IMAGE_NAME
# List images
docker images
# Run container
docker run IMAGE_NAME
docker run -d IMAGE_NAME # Background
docker run -p HOST:CONTAINER IMAGE # Port mapping
docker run -it IMAGE_NAME # Interactive
docker run --name NAME IMAGE # Custom name
# List containers
docker ps # Running only
docker ps -a # All (including stopped)
# Stop container
docker stop CONTAINER_ID_OR_NAME
# Start stopped container
docker start CONTAINER_ID_OR_NAME
# View logs
docker logs CONTAINER_ID_OR_NAME
docker logs -f CONTAINER_ID # Follow real-time
# Execute command in container
docker exec -it CONTAINER_ID COMMAND
# Remove container
docker rm CONTAINER_ID_OR_NAME
docker rm -f CONTAINER_ID # Force remove
# Remove image
docker rmi IMAGE_NAME
Practice Exercise
Let's practice what we learned!
Try this yourself:
# 1. Pull Python image
docker pull python:3.11
# 2. Run Python container interactively
docker run -it --name my-python python:3.11
# Inside container, try:
python --version
print("Hello from Docker!")
exit()
# 3. Exit container (Ctrl+D or exit())
# 4. List all containers
docker ps -a
# 5. Remove the container
docker rm my-python
# 6. List images
docker images
# 7. Remove Python image
docker rmi python:3.11
Common Patterns You'll Use
Pattern 1: Quick Test
# Run, test, remove
docker run --rm IMAGE_NAME
# --rm = Automatically remove after stop
Pattern 2: Development
# Run with name, port, background
docker run -d -p 8080:80 --name dev-server nginx
Pattern 3: Debugging
# Check logs
docker logs my-container
# Access shell
docker exec -it my-container /bin/bash
Pattern 4: Cleanup
# Stop all running containers
docker stop $(docker ps -q)
# Remove all stopped containers
docker rm $(docker ps -a -q)
# Remove all images
docker rmi $(docker images -q)
Key Takeaways
Remember:
Image vs Container:
├── Image = Blueprint (static)
│ └── Like a recipe
│
└── Container = Running instance (active)
└── Like the actual cooked dish
You can create multiple containers from one image!
Container Lifecycle:
pull → run → running → stop → stopped → start → running
↓
rm (remove)
Port Mapping:
ALWAYS use -p for web servers:
-p 8080:80
↑ ↑
│ └── Port inside container
└── Port on your computer
Excellent work! You now know the basic Docker commands!
You've learned to: ✅ Pull images from Docker Hub ✅ Run containers (foreground and background) ✅ Map ports ✅ List containers and images ✅ Stop/start containers ✅ View logs ✅ Execute commands inside containers ✅ Remove containers and images
No comments:
Post a Comment