Happy Dussehra! May good always win. Happy Diwali! Wishing you a bright year ahead. Merry Christmas! Warm wishes from Vizag. Happy New Year! Here’s to a great year ahead.

Archive ยท Docker

Images and Containers: The First Ten Commands

The core Docker commands for pulling images, running and inspecting containers, reading logs, getting a shell, cleaning up, and the mental model behind them.

3 min read

  • Docker Engine 19.03.9
  • Docker Hub
  • nginx 1.18
  • Ubuntu 20.04 LTS

An image is a read-only template made of layers; a container is a running (or stopped) instance of an image with a thin writable layer on top. Understanding that difference explains most Docker behaviour, including why data written inside a container disappears when the container is removed.

Versions in use on this date. Docker Engine 19.03.9 (released 4 May 2020) on Ubuntu 20.04 LTS. The examples use nginx; nginx 1.18 is the stable branch published in April 2020.

Lifecycle

flowchart TB
  REG[Registry Docker Hub] -->|docker pull| IMG[Image on disk]
  IMG -->|docker create| CR[Created container]
  CR -->|docker start| RUN[Running]
  IMG -->|docker run = create + start| RUN
  RUN -->|docker stop SIGTERM then SIGKILL| STP[Stopped<br/>writable layer kept]
  STP -->|docker start| RUN
  STP -->|docker rm| GONE[Removed<br/>writable layer deleted]
  RUN -->|docker commit or build| IMG2[New image]

The ten commands

# 1. Get an image (tag = version; default is latest)
docker pull nginx:1.18

# 2. Run it in the background, publish port 8080, give it a name
docker run -d --name web -p 8080:80 nginx:1.18

# 3. See what is running (-a includes stopped)
docker ps
docker ps -a

# 4. Read output (the container's stdout and stderr)
docker logs -f --tail 50 web

# 5. Look inside
docker exec -it web sh
docker exec web nginx -t

# 6. Inspect configuration and state
docker inspect web | less
docker inspect -f '{{.NetworkSettings.IPAddress}} {{.State.Status}}' web

# 7. Resource usage
docker stats --no-stream

# 8. Stop, start, restart
docker stop web && docker start web
docker restart web

# 9. Remove a container (and an image)
docker rm -f web
docker rmi nginx:1.18

# 10. Clean unused objects
docker system df
docker system prune

Test it: curl -I http://localhost:8080 should return HTTP/1.1 200 OK.

The options you will use most with docker run

Option Meaning
-d Detached (background)
-it Interactive terminal, for shells
--rm Delete the container when it exits (great for one-off commands)
--name Name instead of a random one
-p host:container Publish a port; -p 127.0.0.1:8080:80 limits it to localhost
-e KEY=value Set an environment variable
-v host:container Mount a directory or volume (next posts)
--restart unless-stopped Start again after reboot or crash
--memory 512m --cpus 1.5 Resource limits
docker run --rm alpine:3.11 cat /etc/os-release       # one-off command
docker run -d --name db -e POSTGRES_PASSWORD=change-me -p 127.0.0.1:5432:5432 postgres:12
docker run -d --restart unless-stopped --memory 256m --name web nginx:1.18

Behaviours worth knowing

  • Tags move. nginx:latest today is not nginx:latest next month. Use specific tags for anything you depend on, and pull deliberately.
  • Containers are disposable. The writable layer is lost on docker rm. Keep data in volumes (see the volumes post), and configuration in environment variables or mounted files.
  • One main process. A container runs until its main process (PID 1) exits; docker stop sends SIGTERM and after 10 seconds SIGKILL. Programs must handle SIGTERM to shut down cleanly.
  • Logs go to stdout. Applications should log to stdout/stderr so docker logs works; configure log rotation (see the install post).
  • docker exec is for debugging, not for configuring production containers by hand. Changes made inside a running container vanish when it is recreated.

Troubleshooting

docker logs web                     # why did it exit? read this first
docker inspect -f '{{.State.ExitCode}} {{.State.OOMKilled}}' web      # 137 + true = out of memory
docker events --since 10m           # what the daemon did recently
docker run --rm -it --entrypoint sh nginx:1.18      # get a shell in the image, ignoring its default command
ss -tlnp | grep 8080                # port already in use on the host?

Common errors: port is already allocated (something else uses that host port), no such image (a typo in the tag or a private registry needing docker login), and exited (1) containers that start and stop immediately (check docker logs for the application error).