Why This Matters
Knowing Docker commands is the difference between reading about containers and actually using them. These are the commands you will use daily in development, CI pipelines, and production deployments. Interviewers expect you to be conversational with them.
Building Images
docker build -t myapp:v1 .
-t tags the image with a name and optional version. The . is the build context -- the directory whose files are available to COPY and ADD instructions. Docker sends the entire build context to the daemon before building, which is why .dockerignore matters (covered in the layers lesson).
Running Containers
docker run [OPTIONS] IMAGE [COMMAND]
Key flags:
-d(detached): Run in the background. Without it, the container's stdout/stderr is attached to your terminal.-p 8080:80(port mapping): Map host port 8080 to container port 80. Traffic hittinglocalhost:8080on the host reaches port 80 inside the container.--name myapp: Give the container a human-readable name instead of a random one.--rm: Automatically remove the container when it exits. Useful for one-off tasks so stopped containers do not pile up.-v /host/path:/container/path: Mount a host directory into the container (bind mount). Covered in the storage lesson.-e KEY=VALUE: Set an environment variable inside the container.
docker run -d -p 8080:80 --name web --rm nginx
This runs nginx in the background, maps port 8080 to 80, names it "web", and cleans up on exit.
Inspecting Running Containers
docker ps lists running containers. Add -a to include stopped containers.
docker logs myapp shows stdout/stderr from a container. Add -f to follow (like tail -f).
docker exec -it myapp bash runs a command inside a running container. The -it flags allocate an interactive terminal. This is how you "shell into" a container for debugging.
docker inspect myapp outputs detailed JSON metadata about a container: IP address, mounts, environment variables, state.
Stopping and Removing
docker stop myapp sends SIGTERM to the main process and waits up to 10 seconds for a graceful shutdown. If the process does not exit, Docker escalates to SIGKILL. You can change the timeout with -t: docker stop -t 30 myapp.
docker kill myapp sends SIGKILL immediately. No grace period. Use only when docker stop has failed or the container is unresponsive.
docker rm myapp removes a stopped container and its writable layer. The container must be stopped first (or use docker rm -f to force).
docker rmi myapp:v1 removes an image. Fails if any container (running or stopped) is using it.
Dockerfile Instructions: CMD vs ENTRYPOINT
Both define what runs when a container starts. The difference is how they handle arguments passed to docker run.
CMD sets the default command. It is fully replaced if you pass arguments:
CMD ["python", "app.py"]
# docker run myimage -> python app.py
# docker run myimage bash -> bash (CMD replaced entirely)
ENTRYPOINT sets the executable that always runs. Arguments from docker run are appended:
ENTRYPOINT ["python", "app.py"]
# docker run myimage -> python app.py
# docker run myimage --debug -> python app.py --debug
Together, ENTRYPOINT defines the executable and CMD provides default arguments:
ENTRYPOINT ["python"]
CMD ["app.py"]
# docker run myimage -> python app.py
# docker run myimage test.py -> python test.py (CMD replaced)
Always use exec form (["executable", "arg"]) over shell form (executable arg). Shell form wraps the command in /bin/sh -c, which means the process is not PID 1 and does not receive signals like SIGTERM. Containers using shell form cannot shut down gracefully.
Dockerfile Instructions: COPY vs ADD
COPY copies files from the build context into the image. That is all it does.
ADD does the same, plus two extras:
- Auto-extracts local
.tararchives into the destination - Can fetch files from remote URLs (discouraged -- use
curlin aRUNinstead)
Always prefer COPY. ADD introduces implicit behavior that makes the Dockerfile harder to reason about. Use ADD only when you specifically need tar extraction.
Container Lifecycle
A container moves through these states:
Created -> Running -> Paused -> Running -> Stopped -> Removed
|
+-------> Removed
- Created: Image pulled, container filesystem set up, but process not started
- Running: Main process (PID 1) is executing
- Paused: Process frozen (SIGSTOP). Resumes where it left off
- Stopped: Process exited (or was killed). Container and its writable layer still exist on disk
- Removed: Container and writable layer deleted
docker stop moves Running to Stopped. docker rm moves Stopped to Removed. A stopped container still occupies disk space until removed.
Key Takeaways
docker run -d -p HOST:CONTAINER --name NAME IMAGEis the most common run command.docker exec -it CONTAINER bashis how you debug inside a running container.docker stopsends SIGTERM then SIGKILL;docker killsends SIGKILL immediately. Default tostop.- CMD is overridden by
docker runarguments; ENTRYPOINT is appended to. Use exec form for both. - COPY is explicit; ADD has implicit tar extraction and URL fetching. Prefer COPY.
- Stopped containers still exist on disk.
docker rmdeletes them;--rmondocker runauto-cleans.