Running Your First Real Container

 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

Running Your First Real Container

 Excellent! Now let's run some real containers and learn the basic Docker commands. Understanding What We'll Do Before we start, qui...