Interactive vs detached
docker run has three modes worth knowing:
Interactive (-it) โ attaches your terminal to the container.
Best for ad-hoc shells:
docker run -it ubuntu /bin/bash
# (now you're inside the container)
cat /etc/os-release
exit
-i keeps stdin open; -t allocates a pseudo-TTY (so the shell does
line editing). Almost always paired.
Detached (-d) โ runs in the background, returns immediately
with the container ID:
docker run -d --name web1 nginx
docker ps
Auto-cleanup (--rm) โ the container is deleted as soon as it
stops. Pair with -it for throwaway shells, or -d for short-lived
batch jobs:
docker run --rm alpine echo "I'll be gone in a second"
docker ps -a | grep alpine # nothing โ the container was reaped
Click Verify step once web1 is running.
Hint
`-it` for shell, `-d` for daemon, `--rm` for auto-cleanup.
Naming and listing
Without --name, Docker assigns a random two-word name like
elated_einstein. That's fine for one-offs but unhelpful at scale.
Always name long-lived containers.
docker ps lists running containers. docker ps -a adds stopped
ones.
Start two more named containers:
docker run -d --name web2 nginx
docker run -d --name web3 nginx
docker ps
Useful flags:
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'
docker ps -q # just IDs (handy for xargs)
docker ps --filter status=running
docker ps --filter name=web
docker ps -aq (all + quiet) returns every container ID โ useful as
input to docker rm:
# Don't run this โ just remember the pattern.
# docker rm $(docker ps -aq)
Click Verify step when web1, web2, web3 are all running.
Hint
`--name` on `docker run`; `docker ps` shows running, `docker ps -a` shows all.
Start, stop, restart, rename
Containers are first-class objects with a lifecycle:
created โ running โ paused/exited โ removed
The transitions:
docker stop web2 # graceful (SIGTERM, then SIGKILL after 10s)
docker ps # web2 is gone
docker ps -a # web2 is here with status Exited
docker start web2 # bring it back
docker ps # web2 is back
docker restart web1 # stop + start
docker rename web3 web-renamed # change the name (any time)
docker ps --filter name=web
docker pause / docker unpause freeze the container's processes
(via cgroup freezer). Useful for taking a snapshot or "stopping the
world" briefly without losing state.
For a hard kill (skip the SIGTERM grace period):
docker kill web1 # immediate SIGKILL
docker start web1
Click Verify step when web2 is running again AND web3 has
been renamed to web-renamed.
Hint
`docker stop <name>`, `docker start <name>`, `docker rename <old> <new>`.
Exec into a running container
docker exec runs a process inside an already-running container.
Two common shapes:
A new shell (for poking around):
docker exec -it web1 bash
# now inside web1
ls /usr/share/nginx/html
exit
One-shot commands (no -it needed):
docker exec web1 touch /tmp/visited-by-exec
docker exec web1 mkdir -p /tmp/notes
docker exec web1 ls -la /tmp
Each docker exec spawns a new process tree โ the original PID 1
(nginx in this case) is untouched. When your exec'd shell exits,
nginx keeps running.
A few real-world idioms:
# What process is PID 1 in this container?
docker exec web1 ps -ef
# Tail a log file from outside
docker exec web1 tail -n 20 /var/log/nginx/access.log
# Run as a different user (when the image allows it)
docker exec -u nobody web1 whoami
Click Verify step once /tmp/visited-by-exec exists inside web1.
Hint
`docker exec -it <name> bash` for a shell; `docker exec <name> <cmd>` for one-shots.
Copy files in and out
docker cp moves files between host and container in either
direction. It works even on stopped containers โ handy for
forensic spelunking after a crash.
Create a file on the host, then copy it in:
echo "hello from the host" > /tmp/file1.txt
docker cp /tmp/file1.txt web1:/tmp/file1.txt
docker exec web1 cat /tmp/file1.txt
Copy something out of a container:
docker cp web1:/etc/nginx/nginx.conf /tmp/nginx.conf
head -10 /tmp/nginx.conf
This is the canonical way to:
- Pull logs / heap dumps off a crashed pod.
- Bootstrap config into a container at runtime (though for
long-lived setups a bind mount or volume โ coming in
scenario 107 โ is much better).
- Round-trip files for debugging.
Click Verify step once web1:/tmp/file1.txt contains your
host file's contents.
Hint
`docker cp <file> <name>:/dest` and `docker cp <name>:/path .` both work.