Skip to content

Lesson 1.5: Running Containers

Welcome to Lesson 1.5! Now that you know how to manage images, it's time to bring them to life. In this lesson, you'll learn how to run containers, control their lifecycle, and inspect their behavior. By the end, you'll be comfortable launching, managing, and troubleshooting containers.


Learning Objectives

TIP

By the end of this lesson, you will be able to:

  • Run containers in interactive and detached modes using docker run.
  • Name containers and understand auto-generated names.
  • Start, stop, restart, and remove containers.
  • List running and stopped containers with docker ps.
  • View logs and inspect container details.
  • Execute commands inside running containers with docker exec.
  • Manage container lifecycle effectively.

1. The docker run Command

The docker run command is the most fundamental command—it creates and starts a container from an image.

Basic syntax:

bash
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
  • IMAGE is the image name (e.g., ubuntu, nginx).
  • COMMAND overrides the default command specified in the image.
  • ARG... are arguments to that command.

Common Options

OptionDescription
-d, --detachRun container in background (detached mode).
-itCombine -i (interactive) and -t (pseudo-TTY) for interactive shell.
--nameAssign a name to the container.
-p, --publishPublish container port(s) to the host.
-v, --volumeMount a volume.
-e, --envSet environment variables.
--rmAutomatically remove container when it exits.
--restartRestart policy (e.g., always, on-failure).

We'll explore many of these in later lessons; for now, focus on -d, -it, --name, and --rm.


2. Interactive vs. Detached Mode

2.1. Interactive Mode (-it)

Interactive mode keeps the container alive and lets you interact with it via your terminal. It's perfect for exploring a container or running a shell.

Example: Run an Ubuntu container and get a bash shell:

bash
docker run -it ubuntu bash

You'll be dropped into the container's shell. Type exit or press Ctrl+D to leave—the container stops.

What happens?

  • -i keeps STDIN open.
  • -t allocates a pseudo-TTY (terminal).
  • Together they give you an interactive terminal session.

2.2. Detached Mode (-d)

Detached mode runs the container in the background. The container starts, and you get back your terminal prompt immediately.

Example: Run an Nginx web server in the background:

bash
docker run -d nginx

Docker prints the container ID and returns. Nginx keeps running.

You can verify it's running with docker ps.


3. Naming Containers

By default, Docker assigns a random name (like cool_hermann) to each container. While fun, these are hard to manage. Use --name to give your container a meaningful name.

Example:

bash
docker run -d --name mynginx nginx

Now you can refer to this container as mynginx in all subsequent commands.

WARNING

Container names must be unique. If you try to create another container with the same name, Docker will error.


4. Container Lifecycle

A container can be in various states: created, running, paused, stopped, deleted. Here are the key commands to manage its lifecycle.

4.1. docker create

Creates a container from an image but does not start it. Useful for preparing a container to start later.

bash
docker create --name myubuntu ubuntu

4.2. docker start

Starts one or more stopped containers.

bash
docker start myubuntu

4.3. docker stop

Stops a running container gracefully (sends SIGTERM, then SIGKILL after grace period).

bash
docker stop mynginx

4.4. docker restart

Stops and then starts a container.

bash
docker restart mynginx

4.5. docker pause / docker unpause

Pauses all processes in a container (freezes it) using cgroups freezer. Useful for debugging or taking snapshots.

bash
docker pause mynginx
docker unpause mynginx

4.6. docker kill

Forcefully stops a container immediately (sends SIGKILL).

bash
docker kill mynginx

4.7. docker rm

Removes one or more stopped containers. To remove a running container, use -f.

bash
docker rm myubuntu
docker rm -f mynginx   # force remove even if running

4.8. --rm flag

If you add --rm to docker run, the container is automatically removed when it stops. Useful for temporary containers.

bash
docker run --rm -it ubuntu bash
# after exit, container is gone

5. Listing Containers

5.1. docker ps

Lists only running containers.

bash
docker ps

Output includes container ID, image, command, created, status, ports, and name.

5.2. docker ps -a

Lists all containers (running and stopped).

bash
docker ps -a

5.3. Filtering

You can filter the list, e.g., show only containers with a certain status:

bash
docker ps -a --filter "status=exited"

Or by name:

bash
docker ps --filter "name=mynginx"

5.4. Showing only container IDs

Useful for scripting:

bash
docker ps -q

6. Inspecting Containers

6.1. docker logs

View logs (stdout/stderr) from a container.

bash
docker logs mynginx
  • Follow logs in real-time: docker logs -f mynginx
  • Show timestamps: docker logs -t mynginx
  • Tail last n lines: docker logs --tail 10 mynginx

6.2. docker inspect

Returns detailed metadata about a container (or image) in JSON format.

bash
docker inspect mynginx

You can filter specific fields with --format (Go templates). For example, get the container's IP address:

bash
docker inspect --format='{{.NetworkSettings.IPAddress}}' mynginx

6.3. docker stats

Display live resource usage statistics (CPU, memory, network I/O) for running containers.

bash
docker stats

Press Ctrl+C to exit.

6.4. docker top

Show running processes in a container.

bash
docker top mynginx

6.5. docker port

List port mappings for a container.

bash
docker port mynginx

7. Executing Commands in Running Containers

Sometimes you need to run a command inside an already running container—for debugging, configuration, etc. Use docker exec.

Syntax:

bash
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

Example: Open a bash shell inside a running Nginx container:

bash
docker exec -it mynginx sh

(If bash isn't available, try sh.)

Example: Run a single command without entering an interactive shell:

bash
docker exec mynginx ls -l /etc/nginx

Options:

  • -i, -t same as docker run (usually used together for interactive).
  • -d run command in background.
  • -e set environment variables.
  • --workdir set working directory.

Hands-On Tasks

Now it's time to practice. Complete these tasks to solidify your understanding.

  • [ ] Task 1: Run Interactive Containers

    1. Run an interactive Ubuntu container with bash:
      bash
      docker run -it ubuntu bash
    2. Inside the container, create a file:
      bash
      echo "Hello from inside" > /tmp/test.txt
    3. Exit the container (exit).
    4. Verify the container is stopped: docker ps -a. Note its name.
  • [ ] Task 2: Run Detached Containers

    1. Run an Nginx container in detached mode, naming it web1:
      bash
      docker run -d --name web1 nginx
    2. Check that it's running: docker ps.
    3. View its logs: docker logs web1.
  • [ ] Task 3: Container Lifecycle

    1. Stop the web1 container: docker stop web1.
    2. Confirm it's stopped: docker ps -a.
    3. Start it again: docker start web1.
    4. Restart it: docker restart web1.
    5. Pause it: docker pause web1. Observe its status in docker ps.
    6. Unpause: docker unpause web1.
    7. Kill it forcefully: docker kill web1.
    8. Remove it: docker rm web1.
  • [ ] Task 4: Naming and Auto-removal

    1. Run a temporary container with --rm and --name:
      bash
      docker run --rm --name temp alpine echo "I'm temporary"
    2. Immediately after, check docker ps -a – the container should be gone.
  • [ ] Task 5: Inspect Containers

    1. Run a new Nginx container named web2 (detached).
    2. Inspect it: docker inspect web2. Look at the NetworkSettings section.
    3. Use --format to extract its IP address.
    4. Check its resource usage: docker stats web2 (exit with Ctrl+C).
    5. View its logs with timestamps: docker logs -t web2.
  • [ ] Task 6: Execute Commands

    1. With web2 running, run a command to list files in the container:
      bash
      docker exec web2 ls -l /usr/share/nginx/html
    2. Open an interactive shell inside the container:
      bash
      docker exec -it web2 bash
      (If bash not found, try sh.)
    3. Inside, modify the default Nginx page (optional):
      bash
      echo "<h1>Hacked!</h1>" > /usr/share/nginx/html/index.html
      exit
    4. Verify the change by checking logs or using a web browser if you mapped ports (we'll cover ports in networking).
  • [ ] Task 7: Clean Up Remove all containers you created:

bash
docker stop $(docker ps -q)   # stop all running
docker rm $(docker ps -aq)    # remove all containers (force with -f if needed)

WARNING

This removes all containers. Be sure you don't need them.


Summary

Key Takeaways

  • Use docker run to create and start containers, with -it for interactive sessions and -d for background.
  • Name containers with --name for easier management.
  • Lifecycle commands: create, start, stop, restart, pause, unpause, kill, rm.
  • List containers with docker ps and docker ps -a.
  • Inspect containers with docker logs, docker inspect, docker stats, docker top.
  • Execute commands inside running containers with docker exec.

Check Your Understanding

  1. What is the difference between docker run -it ubuntu bash and docker run -d ubuntu bash?
  2. How do you list only stopped containers?
  3. What command would you use to see the last 20 lines of logs from a container named myapp?
  4. How can you get the IP address of a running container?
  5. If you want to run a temporary container that deletes itself after exiting, which flag do you use?
  6. How do you open a shell inside a running container named database?
Click to see answers
  1. -it runs interactively (attaches your terminal to the container); -d runs detached (in the background).
  2. docker ps -a --filter "status=exited"
  3. docker logs --tail 20 myapp
  4. docker inspect --format='&#123;&#123;.NetworkSettings.IPAddress&#125;&#125;' mycontainer
  5. --rm
  6. docker exec -it database bash (or sh if bash isn't available)

Additional Resources


Next Up

This concludes Phase 1: Docker Fundamentals. You now have a solid foundation: you understand containerization, installed Docker, know the architecture, can work with images, and run/manage containers. In the next phase, we'll start building custom images with Dockerfiles. Great job!