| | |

LFCA 76 🐧 Running Your First Container

In the previous chapter, you learned what Docker is and how containers differ from virtual machines. This chapter puts that theory into practice. You will run your first container, understand exactly what happens at each step, and learn the commands that form the foundation of every Docker workflow.

The LFCA exam places containers under DevOps Fundamentals, which carries 12–16% of the total weight . The study plan lists “Containers” as a core DevOps topic alongside Git concepts and deployment environments . The exam expects you to understand the container lifecycle, the relationship between images and containers, and the basic commands for creating, listing, and removing containers.

Key point: A container is a running instance of an image. An image is a read-only template that contains an application and everything it needs to run . When you run a container, Docker creates a writable layer on top of the image, starts the process defined in the image, and isolates it from the host and other containers. When the process exits, the container stops. The image remains.


Why running a container matters

The first container is a milestone. It confirms that Docker is installed correctly, that the daemon is running, and that the client can communicate with it. It also demonstrates the fundamental workflow that every Docker command builds on.

The installation verification problem. After installing Docker, you need to confirm that everything works. The hello-world image exists for this purpose. It is a minimal container that prints a message and exits. If it runs, Docker is working. If it fails, the error tells you what is wrong .

The image-and-container relationship problem. New Docker users often confuse images and containers. The hello-world example makes the distinction concrete. You run docker run hello-world. Docker checks for the image locally, pulls it from Docker Hub if it is missing, creates a container from the image, runs the container, and the container prints a message and exits. The image remains on disk. The container is gone .

The lifecycle problem. A container has a lifecycle: created, running, paused, stopped, removed . The hello-world container moves through created, running, and stopped in a single second. The docker ps -a command shows it in the stopped state. The docker rm command removes it. Understanding this lifecycle is the foundation for managing long-running containers.

The trade-off. The hello-world container is trivial. It does not demonstrate networking, port mapping, volumes, or any of the features that make containers useful. But it is the right first step because it isolates the installation check from everything else. When it works, you know the foundation is solid.


a. The hello-world Container

The hello-world image is the simplest possible Docker image. It contains a single static binary that prints a message to standard output . The image is 1.84 KB . It exists solely to verify that Docker is installed and working.

The command is:

docker run hello-world

The output explains what happened:

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

The output is the documentation. It describes the four steps of the Docker architecture: the client contacts the daemon, the daemon pulls the image, the daemon creates a container, and the daemon streams the output back to the client .

If the image is not present locally, Docker pulls it from Docker Hub. On the second run, the image is already cached, so the pull step is skipped. The container is created, runs, and exits. The image remains on disk .

The hello-world container exits immediately because the binary runs, prints the message, and returns. The container’s lifecycle goes from created to running to stopped in a fraction of a second. The docker ps command shows nothing because the container is no longer running. The docker ps -a command shows it in the stopped state .


b. Running a Long-Lived Container

The hello-world container is educational but not useful. A real container runs a service that stays alive. The nginx image is a web server that runs indefinitely. It demonstrates port mapping, detached mode, and the container lifecycle.

The command is:

docker run --detach --name my-nginx --publish 8080:80 nginx

Each flag has a purpose:

  • --detach (or -d) runs the container in the background. Without it, the terminal is attached to the container’s output and the command does not return until the container stops.
  • --name assigns a human-readable name. Without it, Docker generates a random name.
  • --publish (or -p) maps a port on the host to a port in the container. The format is host-port:container-port.
  • The final argument is the image name.

The command returns immediately with the container ID. The container runs in the background. The web server is accessible at http://localhost:8080 .

The docker ps command shows the running container:

CONTAINER ID   IMAGE   COMMAND                  CREATED         STATUS         PORTS
a1b2c3d4e5f6   nginx   "/docker-entrypoint.…"   5 seconds ago   Up 5 seconds   0.0.0.0:8080->80/tcp

The PORTS column shows the port mapping. The container’s port 80 is mapped to the host’s port 8080. The STATUS column shows Up, which means the container is running .

To stop the container:

docker stop my-nginx

To remove it:

docker rm my-nginx

The docker stop command sends a SIGTERM signal to the container’s main process, waits for it to exit, and then stops the container. The docker rm command removes the stopped container. The image remains .


c. Understanding the Container Lifecycle

A container moves through a defined lifecycle. The states are:

Created. The container exists but has not started. This state occurs when you use docker create instead of docker run, or when a container is created but the start is deferred.

Running. The container’s main process is executing. This is the normal state for a service container.

Paused. The container’s processes are suspended. The docker pause command freezes the container, and docker unpause resumes it. This is useful for temporarily freeing CPU resources.

Stopped. The container’s main process has exited. This can happen because the process finished (like hello-world), because it was stopped with docker stop, or because it crashed.

Removed. The container is deleted. The docker rm command removes a stopped container. The docker rm -f command forcibly removes a running container .

The commands that manage the lifecycle are:

docker run <image>        # Create and start
docker create <image>     # Create without starting
docker start <container>  # Start a stopped container
docker stop <container>   # Stop gracefully
docker restart <container> # Stop and start
docker pause <container>  # Pause processes
docker unpause <container> # Resume processes
docker rm <container>     # Remove stopped container
docker rm -f <container>  # Force remove running container

The docker run command is a combination of docker create and docker start. The two-step process is useful when you need to configure the container before starting it, or when you want to create multiple containers from the same image and start them at different times.


Complete Example Session

This session walks through running the hello-world container, running an nginx container, inspecting the lifecycle, and cleaning up.

# ============================================
# PART 1: VERIFY DOCKER IS RUNNING
# ============================================

# Check that the Docker daemon is running
docker version

# Output shows the client and server versions.
# If the server section is missing, the daemon is not running.

# ============================================
# PART 2: RUN THE HELLO-WORLD CONTAINER
# ============================================

docker run hello-world

# Output:
# Unable to find image 'hello-world:latest' locally
# latest: Pulling from library/hello-world
# ...
# Hello from Docker!
# ...

# The image was pulled from Docker Hub.
# The container ran, printed the message, and exited.

# ============================================
# PART 3: VERIFY THE CONTAINER IS STOPPED
# ============================================

# The container is no longer running
docker ps

# Output: empty (no running containers)

# But it exists in the stopped state
docker ps -a

# Output:
# CONTAINER ID   IMAGE         COMMAND    CREATED          STATUS
# a1b2c3d4e5f6   hello-world   "/hello"   10 seconds ago   Exited (0)

# The "Exited (0)" status means the process finished successfully.

# ============================================
# PART 4: RUN A LONG-LIVED CONTAINER
# ============================================

# Run nginx in the background with port mapping
docker run --detach --name my-nginx --publish 8080:80 nginx

# Output: the container ID

# ============================================
# PART 5: VERIFY THE CONTAINER IS RUNNING
# ============================================

docker ps

# Output:
# CONTAINER ID   IMAGE   COMMAND                  CREATED         STATUS         PORTS
# b2c3d4e5f6a1   nginx   "/docker-entrypoint.…"   5 seconds ago   Up 5 seconds   0.0.0.0:8080->80/tcp

# The container is running. The port mapping is active.

# ============================================
# PART 6: ACCESS THE WEB SERVER
# ============================================

curl http://localhost:8080

# Output: the default nginx welcome page HTML

# ============================================
# PART 7: VIEW THE CONTAINER LOGS
# ============================================

docker logs my-nginx

# Output: the nginx access log entries

# ============================================
# PART 8: EXECUTE A COMMAND INSIDE THE CONTAINER
# ============================================

docker exec -it my-nginx /bin/bash

# Inside the container:
ls /etc/nginx/
# conf.d  fastcgi_params  mime.types  nginx.conf  ...

exit

# The exec command runs a new process inside the running container.

# ============================================
# PART 9: STOP AND REMOVE THE CONTAINER
# ============================================

docker stop my-nginx
docker rm my-nginx

# Verify
docker ps -a

# Output: only the hello-world container remains (stopped)

# ============================================
# PART 10: CLEAN UP THE HELLO-WORLD CONTAINER
# ============================================

docker rm a1b2c3d4e5f6

# Or remove all stopped containers
docker container prune

# Verify
docker ps -a

# Output: empty

The ten parts cover verifying Docker is running, running the hello-world container, verifying the stopped state, running a long-lived container, verifying the running state, accessing the web server, viewing logs, executing commands inside the container, stopping and removing the container, and cleaning up.


Quick Reference

The Essential Commands

CommandPurpose
docker run <image>Create and start a container
docker run -d <image>Run in detached mode
docker run -p 8080:80 <image>Map host port to container port
docker run --name <name> <image>Assign a name
docker psList running containers
docker ps -aList all containers
docker stop <container>Stop a running container
docker start <container>Start a stopped container
docker rm <container>Remove a stopped container
docker logs <container>View container logs
docker exec -it <container> bashRun a shell inside a container

The Container Lifecycle

StateDescriptionCommand
CreatedExists, not starteddocker create
RunningProcess executingdocker run, docker start
PausedProcesses suspendeddocker pause
StoppedProcess exiteddocker stop
RemovedDeleteddocker rm

The Run Flags

FlagPurpose
-d, --detachRun in background
-p, --publishMap host:container ports
--nameAssign container name
-itInteractive terminal
--rmRemove on exit

The Troubleshooting Commands

CommandPurpose
docker versionCheck client and daemon
docker infoSystem-wide information
docker logs <container>View output
docker inspect <container>Detailed JSON info
docker container pruneRemove all stopped containers

Best Practices

✅ Do This:

# Verify Docker is working with hello-world
docker run hello-world                                        # ✅
# Use detached mode for long-running services
docker run -d --name nginx -p 8080:80 nginx                   # ✅
# Give containers meaningful names
docker run --name my-app my-app:1.0                           # ✅
# Clean up stopped containers
docker container prune                                        # ✅
# Use --rm for one-off containers
docker run --rm ubuntu echo "hello"                           # ✅

❌ Don’t Do This:

# Don't run containers without a name for long-lived services
docker run -d nginx  # random name, hard to manage            # ❌
# Don't forget to stop containers before removing
docker rm -f nginx  # force removes, may lose data            # ❌
# Don't expose ports without considering security
docker run -p 0.0.0.0:8080:80 nginx                           # ❌
# Don't leave stopped containers indefinitely
# They consume disk space and clutter docker ps -a.           # ❌

Common Pitfalls

PitfallWhy It HappensFix
“Cannot connect to the Docker daemon”Docker Desktop not runningStart Docker Desktop
“Port is already allocated”Another container uses the portUse a different host port
“Repository does not exist”Typo in image nameCheck the spelling
Container exits immediatelyNo long-running processUse a service image like nginx
docker ps shows nothingContainer stoppedUse docker ps -a
Permission deniedUser not in docker groupsudo usermod -aG docker $USER

Real-World Examples

1. Hello World

docker run hello-world

2. Nginx Web Server

docker run -d --name web -p 8080:80 nginx

3. Interactive Ubuntu

docker run -it ubuntu /bin/bash

4. One-Off Command

docker run --rm alpine echo "Hello from Alpine"

5. List All Containers

docker ps -a

6. View Logs

docker logs web

7. Execute Inside Container

docker exec -it web /bin/bash

8. Stop Container

docker stop web

9. Remove Container

docker rm web

10. Clean Up

docker container prune

Visual

The Docker Run Flow

┌──────────────────────────────────────────────┐
│  docker run hello-world                      │
│                                              │
│  1. Docker client sends request to daemon    │
│       │                                      │
│       ▼                                      │
│  2. Daemon checks for image locally          │
│       ├─ Found → skip pull                   │
│       └─ Not found → pull from Docker Hub    │
│       │                                      │
│       ▼                                      │
│  3. Daemon creates container from image      │
│       │                                      │
│       ▼                                      │
│  4. Daemon starts the container's process    │
│       │                                      │
│       ▼                                      │
│  5. Container runs, prints output, exits     │
│       │                                      │
│       ▼                                      │
│  6. Daemon streams output to client          │
│                                              │
└──────────────────────────────────────────────┘

The Image vs Container

┌──────────────────────────────────────────────┐
│  IMAGE                                       │
│    Read-only template                        │
│    Contains application + dependencies       │
│    Stored on disk                            │
│    Can create many containers                │
│                                              │
│  CONTAINER                                   │
│    Running instance of an image              │
│    Has a writable layer on top               │
│    Has a lifecycle (created → removed)       │
│    Isolated from host and other containers   │
│                                              │
│  docker run hello-world                      │
│    └─ Creates a container from the image     │
│    └─ Runs it                                │
│    └─ Container exits, image remains         │
│                                              │
└──────────────────────────────────────────────┘

The Container Lifecycle

┌──────────────────────────────────────────────┐
│  LIFECYCLE                                   │
│                                              │
│  docker create ──> Created                   │
│       │                                      │
│       ▼                                      │
│  docker start ──> Running <── docker pause   │
│       │              │              │        │
│       │              ▼              ▼        │
│       │           Paused <── docker unpause  │
│       │              │                       │
│       ▼              ▼                       │
│  docker stop ──> Stopped                     │
│       │                                      │
│       ▼                                      │
│  docker rm ──> Removed                       │
│                                              │
│  docker run = create + start                 │
│                                              │
└──────────────────────────────────────────────┘

The Port Mapping

┌──────────────────────────────────────────────┐
│  PORT MAPPING                                │
│                                              │
│  Host                                        │
│    localhost:8080 ──────────┐                │
│                              │                │
│  Container                   │                │
│    nginx:80 <────────────────┘                │
│                                              │
│  docker run -p 8080:80 nginx                 │
│    ├─ host port: 8080                        │
│    └─ container port: 80                     │
│                                              │
│  Traffic to localhost:8080 is forwarded      │
│  to the container's port 80.                 │
│                                              │
└──────────────────────────────────────────────┘

Summary

ItemValue
First containerdocker run hello-world
ImageRead-only template
ContainerRunning instance of an image
Detached mode-d or --detach
Port mapping-p host:container
Name--name
List runningdocker ps
List alldocker ps -a
Stopdocker stop
Removedocker rm
Logsdocker logs
Execute insidedocker exec -it
LFCA weightDevOps Fundamentals, 12–16%

Key takeaways:

  • The hello-world container verifies that Docker is installed and working. It pulls the image from Docker Hub, creates a container, runs it, and exits. The image remains on disk for future use .
  • An image is a read-only template; a container is a running instance of an image. The docker run command creates a container from an image and starts it. The container has a writable layer on top of the image’s layers. When the container is removed, the writable layer is discarded. The image remains .
  • The container lifecycle has five states: created, running, paused, stopped, and removed. The docker run command combines create and start. The docker stop command stops a running container. The docker rm command removes a stopped container .
  • Port mapping connects the host to the container. The -p flag maps a host port to a container port. -p 8080:80 makes the container’s port 80 accessible at the host’s port 8080 .
  • Detached mode runs containers in the background. The -d flag returns the terminal immediately and runs the container as a background process. Without it, the terminal is attached to the container’s output .
  • The docker exec command runs a new process inside a running container. It is how you open a shell, inspect files, or run commands in a container that is already running. The -it flags allocate an interactive terminal .
  • Stopped containers accumulate and should be cleaned up. The docker ps -a command shows all containers, including stopped ones. The docker container prune command removes all stopped containers. The docker rm command removes a specific container.

Remember: Running your first container is the moment Docker becomes real. The hello-world container confirms the installation. The nginx container demonstrates port mapping, detached mode, and the lifecycle. The docker ps, docker stop, and docker rm commands give you control. The image is the template. The container is the instance. The lifecycle is the sequence of states. Every Docker workflow builds on these fundamentals.


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!