Fatskills
Practice. Master. Repeat.
Study Guide: TECH **Docker CLI Deep Dive: `run`, `exec`, `logs`, `inspect`, `top`, `stats`**
Source: https://www.fatskills.com/kubernetes/chapter/tech-docker-cli-deep-dive-run-exec-logs-inspect-top-stats

TECH **Docker CLI Deep Dive: `run`, `exec`, `logs`, `inspect`, `top`, `stats`**

By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.

⏱️ ~8 min read

Docker CLI Deep Dive: run, exec, logs, inspect, top, stats

A hyper-practical, zero-fluff guide for engineers in production


1. What This Is & Why It Matters

You’re debugging a containerized app in production. The service is crashing, logs are scattered, and you don’t know if the container is even running. This guide teaches you the six Docker CLI commands that turn chaos into clarity.


  • docker run: Launch containers (like spinning up a VM, but faster).
  • docker exec: Jump inside a running container (like SSH, but without the overhead).
  • docker logs: Stream or dump container logs (your first line of defense when things break).
  • docker inspect: Peek under the hood (network settings, mounts, environment variables).
  • docker top: Check running processes (like htop for containers).
  • docker stats: Monitor resource usage (CPU, memory, I/O) in real time.

Why this matters in production:
- Debugging: When a container crashes, you need logs now, not after filing a Jira ticket.
- Security: exec lets you audit running containers (e.g., check for exposed secrets).
- Performance: stats helps you spot memory leaks before they take down your cluster.
- Automation: inspect outputs JSON, which you can parse in scripts to auto-scale or auto-heal.

Real-world scenario:
You inherit a legacy app running in Docker. The original dev left no docs. The app is misbehaving—high CPU, random crashes. You have 30 minutes to diagnose it before the CEO notices. These six commands are your lifeline.


2. Core Concepts & Components


docker run

  • Definition: Creates and starts a container from an image.
  • Production insight: Always use --restart unless-stopped for critical services. If you forget, your container won’t survive a host reboot.

docker exec

  • Definition: Runs a command inside an already running container.
  • Production insight: Use -it for interactive sessions (e.g., exec -it <container> sh). Never leave shells open in production—use them for debugging, then exit.

docker logs

  • Definition: Fetches stdout/stderr from a container.
  • Production insight: Use --tail 100 -f to follow the last 100 lines in real time. For JSON logs, pipe to jq (e.g., docker logs <container> | jq '.').

docker inspect

  • Definition: Returns low-level details about a container (or image) in JSON.
  • Production insight: Use --format to extract specific fields (e.g., docker inspect --format='{{.NetworkSettings.IPAddress}}' <container>).

docker top

  • Definition: Shows running processes inside a container.
  • Production insight: Useful for spotting zombie processes or runaway scripts. Combine with ps aux inside the container for deeper inspection.

docker stats

  • Definition: Displays live resource usage (CPU, memory, network, disk I/O).
  • Production insight: Use --no-stream to get a one-time snapshot. For long-running monitoring, pipe to a file (e.g., docker stats --no-stream > stats.txt).


3. Step-by-Step Hands-On


Prerequisites

  • Docker installed (test with docker --version).
  • A sample app (we’ll use nginx for simplicity).

Task: Debug a Misbehaving Nginx Container

You’re given a container that’s supposed to serve a static site, but it’s returning 502 errors. Let’s diagnose it.


Step 1: Run the Container

docker run -d --name my-nginx -p 8080:80 nginx
  • -d: Detached mode (runs in background).
  • --name: Assigns a name (my-nginx).
  • -p 8080:80: Maps host port 8080 to container port 80.

Verify it’s running:


docker ps

Expected output:


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

Step 2: Check Logs

docker logs my-nginx

Expected output (truncated):


2023/10/01 12:00:00 [notice] 1#1: using the "epoll" event method
2023/10/01 12:00:00 [notice] 1#1: nginx/1.25.1
2023/10/01 12:00:00 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)

If you see errors (e.g., Permission denied), you’ve found the issue.


Step 3: Inspect the Container

docker inspect my-nginx

This dumps a huge JSON blob. Let’s extract the IP address:


docker inspect --format='{{.NetworkSettings.IPAddress}}' my-nginx

Expected output:


172.17.0.2

Why this matters: If the container can’t bind to port 80, inspect will show Ports: {}.


Step 4: Jump Inside the Container

docker exec -it my-nginx sh

Now you’re inside the container. Run:


ps aux

Expected output:


USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1  10628  5248 ?        Ss   12:00   0:00 nginx: master process nginx -g daemon off;
nginx        6  0.0  0.0  11100  2624 ?        S    12:00   0:00 nginx: worker process

Check for issues: - Is nginx running? If not, the container might have crashed.
- Are there zombie processes? (Look for <defunct> in ps aux.)

Exit the shell:


exit

Step 5: Monitor Resource Usage

docker stats my-nginx

Expected output (live updating):


CONTAINER ID   NAME        CPU %     MEM USAGE / LIMIT     MEM %     NET I/O     BLOCK I/O   PIDS
abc123def456   my-nginx    0.00%     2.5MiB / 1.944GiB     0.13%     656B / 0B   0B / 0B     2

What to look for: - High CPU (>80% sustained) → Possible infinite loop.
- High memory (>90% of limit) → Memory leak.
- High disk I/O → Log spam or storage issues.


Step 6: Check Running Processes (Alternative to exec)

docker top my-nginx

Expected output:


UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                12345               12340               0                   12:00               ?                   00:00:00            nginx: master process nginx -g daemon off;
101                 12346               12345               0                   12:00               ?                   00:00:00            nginx: worker process

Why this matters: If exec fails (e.g., the container is crashing), top still works.


4. ? Production-Ready Best Practices


Security

  • Never run containers as root: Use --user in docker run (e.g., --user 1000:1000).
  • Limit resources: Use --memory and --cpus to prevent noisy neighbors.
    bash docker run -d --memory="512m" --cpus="1" nginx
  • Read-only filesystems: Use --read-only for security-sensitive containers.
    bash docker run -d --read-only nginx

Cost Optimization

  • Clean up unused containers: Use docker system prune -a (careful—this deletes all unused images).
  • Use --restart unless-stopped: Avoids unnecessary container restarts.
  • Monitor with stats: Set up alerts for high CPU/memory usage.

Reliability & Maintainability

  • Tag containers: Use --name for easy reference (e.g., --name api-prod).
  • Log rotation: Use --log-opt max-size=10m --log-opt max-file=3 to limit log size.
    bash docker run -d --log-opt max-size=10m --log-opt max-file=3 nginx
  • Health checks: Use --health-cmd to auto-recover failing containers.
    bash docker run -d --health-cmd="curl -f http://localhost || exit 1" nginx

Observability

  • Centralize logs: Use docker logs with --since and --until for time-based debugging.
    bash docker logs --since 2023-10-01T00:00:00 --until 2023-10-01T12:00:00 my-nginx
  • Export metrics: Use docker stats --no-stream and pipe to Prometheus/Grafana.
  • Inspect network: Use docker inspect to debug connectivity issues.
    bash docker inspect --format='{{.NetworkSettings.Networks}}' my-nginx


5. ⚠️ Common Mistakes & Traps

Mistake Symptom Fix/Prevention
Forgetting -d in run Container runs in foreground, blocks terminal. Always use -d for long-running services.
Using exec on stopped containers Error: No such container: <name> Check docker ps -a first. Use docker start <container> if stopped.
Not limiting logs Disk fills up with logs. Use --log-opt max-size and --log-opt max-file.
Running as root Security vulnerability (container escape). Use --user or USER in Dockerfile.
Ignoring stats Memory leaks go unnoticed. Set up monitoring for CPU/memory usage.
Misusing inspect Overwhelmed by JSON output. Use --format to extract specific fields (e.g., --format='{{.NetworkSettings}}').


6. ? Exam/Certification Focus


Typical Question Patterns

  1. docker run flags:
  2. "How do you run a container in detached mode with a custom name?"
    Answer: docker run -d --name my-container nginx
  3. "How do you limit a container to 512MB of memory?"
    Answer: docker run --memory="512m" nginx

  4. docker exec vs docker run:

  5. "What’s the difference between docker exec and docker run?"
    Answer: run creates a new container; exec runs a command in an existing one.

  6. docker logs:

  7. "How do you follow the last 100 lines of a container’s logs?"
    Answer: docker logs --tail 100 -f <container>

  8. docker inspect:

  9. "How do you get a container’s IP address?"
    Answer: docker inspect --format='{{.NetworkSettings.IPAddress}}' <container>

  10. docker stats:

  11. "How do you get a one-time snapshot of a container’s resource usage?"
    Answer: docker stats --no-stream <container>

Key ⚠️ Trap Distinctions

  • docker run vs docker start:
  • run creates a new container.
  • start starts an existing stopped container.
  • docker exec vs docker attach:
  • exec runs a new process inside the container.
  • attach connects to the main process (can kill the container if you exit).
  • docker logs vs docker events:
  • logs shows stdout/stderr.
  • events shows Docker daemon events (e.g., container start/stop).


7. ? Hands-On Challenge


Challenge

A container named web-app is running, but the app is unresponsive. You suspect a memory leak. Diagnose the issue using only docker CLI commands.

Solution

  1. Check resource usage:
    bash
    docker stats web-app
  2. If memory usage is near the limit, it’s likely a leak.

  3. Inspect the container’s memory limit:
    bash
    docker inspect --format='{{.HostConfig.Memory}}' web-app

  4. If no limit is set, the container can consume all host memory.

  5. Jump inside the container to check processes:
    bash
    docker exec -it web-app sh

  6. Run top or ps aux to spot runaway processes.

  7. Restart the container with a memory limit:
    bash
    docker stop web-app
    docker rm web-app
    docker run -d --name web-app --memory="512m" your-image

Why this works: - stats identifies the leak.
- inspect confirms if a limit was set.
- exec lets you debug interactively.
- Restarting with --memory prevents future leaks.


8. ? Rapid-Reference Crib Sheet

Command Purpose Example
docker run Start a container. docker run -d --name my-app -p 8080:80 nginx
docker exec Run a command in a running container. docker exec -it my-app sh
docker logs Fetch container logs. docker logs --tail 100 -f my-app
docker inspect Get container/image details. docker inspect --format='{{.NetworkSettings.IPAddress}}' my-app
docker top Show container processes. docker top my-app
docker stats Monitor resource usage. docker stats --no-stream my-app
⚠️ docker attach Dangerous: Attaches to main process. Avoid—use exec instead.
⚠️ docker run -it Interactive mode (blocks terminal). Use -d for detached mode.
⚠️ Default log driver json-file (can fill disk). Use --log-opt max-size=10m.


9. ? Where to Go Next

  1. Docker Official Docs – CLI Reference
  2. Docker Deep Dive (Book) – Nigel Poulton
  3. Kubernetes for the Docker User (Tutorial) – Learn how these commands translate to kubectl.
  4. Docker Security Cheat Sheet – OWASP

Final Tip: Bookmark this guide. When production breaks at 3 AM, you’ll thank yourself. ?



ADVERTISEMENT