skip to content

questions

4

Explain the difference between 'docker exec' and 'docker attach', and why pressing Ctrl+C in one of them can take a production container down.

level: juniorimportance: must knowfreq 75%

answer

  1. exec = new process, attach = existing PID 1
  2. attach Ctrl+C -> SIGINT to PID 1 -> container stops
  3. detach with Ctrl+P Ctrl+Q
  4. --sig-proxy=false / --no-stdin
  5. exec output never reaches docker logs

basics

~20 s

docker exec starts a new process inside a running container; exiting it leaves the container alone. docker attach connects your terminal to the container's existing main process (PID 1), so Ctrl+C sends SIGINT to that process and usually stops the container.

solid answer

~50 s

`docker exec` spawns an **additional** process in the container's namespaces — `docker exec -it web sh` gives a second shell alongside the main process. Exit it and only that shell dies; the container keeps running. It is the everyday tool for inspecting a live container. `docker attach` starts nothing. It reconnects your terminal to the stdin, stdout and stderr of the container's **existing PID 1**, the process from ENTRYPOINT/CMD. You see exactly what that process prints, and your keystrokes go to it. Because attach defaults to `--sig-proxy=true`, Ctrl+C delivers SIGINT to PID 1, which for most servers means shutdown — and PID 1 exiting ends the container. Detach safely with Ctrl+P Ctrl+Q, or attach with `--sig-proxy=false` / `--no-stdin`. In practice: `exec` to poke around, `logs` to read output, and `attach` only when you genuinely need the main process's interactive stdin, such as a REPL or console.

code

bash · 6 lines
bash
docker exec -it web sh              # new shell; container unaffected on exit
docker exec -u root web ls -l /etc
docker logs -f --tail 100 web       # read output without touching the process

docker attach --sig-proxy=false web # Ctrl+C detaches instead of killing
# detach from a normal attach: Ctrl+P then Ctrl+Q

go deeper

for a junior

State the core distinction — new process versus existing PID 1 stdio — and that Ctrl+C during attach can stop the container.

for a middle

Add sig-proxy, the Ctrl+P Ctrl+Q detach sequence, and the fact that exec output bypasses the logging driver.

for a senior

Stress that exec is diagnosis not configuration, and cover shell-less images and namespace-sharing toolbox containers.

for a principal

Treat interactive access as an exception: drive teams toward logs, metrics and reproducible images so nobody needs to exec into production to understand it.

## Two different operations A running container has one main process, PID 1 in its PID namespace, started from the image's ENTRYPOINT/CMD. The container lives exactly as long as that process does. **`docker exec <container> <cmd>`** asks the daemon to launch a *new* process inside the same namespaces (PID, network, mount, IPC) and cgroups as the container — essentially nsenter with Docker's bookkeeping. With `-it` you get an interactive TTY. That process does not inherit PID 1's stdio and is not its child, so killing it has no effect on the container; its exit status becomes the exit status of `docker exec`. **`docker attach <container>`** creates no process. It wires your terminal to the streams PID 1 already owns. Whatever it writes appears on your terminal, and whatever you type is written to its stdin, provided the container was started with `-i`. ## Why Ctrl+C is dangerous with attach By default attach runs with `--sig-proxy=true`: signals raised in your terminal are forwarded to the container's main process. Ctrl+C therefore delivers SIGINT to PID 1. A web server, JVM or database treats that as 'shut down', exits, and the container stops. Multiple clients can attach at once and share the same stream, so one person's Ctrl+C stops it for everyone. Safe exits: - **Ctrl+P Ctrl+Q** — the detach escape sequence; leaves the container running. It requires the container to have a TTY (`-t`), and the sequence is configurable via `--detach-keys`. - **`docker attach --sig-proxy=false`** — Ctrl+C detaches the client instead of signalling the process. - **`docker attach --no-stdin`** — a read-only view. The same trap applies to `docker run -it`, which is attached by default. ## When to use which - **Read output**: `docker logs -f`. It reads from the logging driver, never touches the process, and works even for containers not started interactively. Attaching merely to watch output is a common mistake with a real blast radius. - **Inspect or repair inside**: `docker exec -it <c> sh` (or bash). Look at files, run a client, read `/proc`. Remember that anything you change is lost when the container is replaced, so exec is for diagnosis, not configuration. - **Interact with the main process**: `docker attach` — a language REPL, an interactive console, a program that reads commands from stdin. ## Gotchas - `docker exec` needs an executable that already exists in the image. Minimal or distroless images have no shell, so the command fails; use a toolbox container sharing the target's namespaces instead. - `docker exec` ignores the image's ENTRYPOINT — you name the command directly. - `docker exec -u root` is useful when the container runs as a nonroot user and you need privileged inspection. - Output from `docker exec` is **not** captured by the logging driver, so it never appears in `docker logs`; only PID 1's stdout/stderr is. - `docker exec` only works on a running container; for a stopped one you inspect the image or start a new container from it.

  • You run 'docker exec -it app sh' against a distroless image and it fails. Why, and what do you do?
    exec runs a binary that must already exist in the image, and distroless images ship no shell. Either use a debug image variant in lower environments, or start a separate toolbox container joined to the target's PID and network namespaces so you bring your own tools without modifying the running container.
  • Why does output from a command run with docker exec not appear in docker logs?
    The logging driver is wired to the stdout and stderr of the container's main process only. An exec session gets its own streams attached to your client, so its output goes to your terminal and is never written to the json-file log or forwarded to a remote driver.

exec is opening a second SSH session to a server; attach is sitting down at the console keyboard the running program is already reading from.

saying these in an interview costs you the question

  • Saying attach starts a new shell in the container
  • Using docker attach to watch output instead of docker logs
  • Pressing Ctrl+C to leave an attached session
  • Assuming changes made via docker exec survive a container replacement
  • Expecting docker exec output to appear in docker logs

context

open as a page

An application team says 'docker logs' returns nothing for their container even though the app is clearly writing log files. Explain how 'docker logs' gets its data and what the team must change.

level: middleimportance: must knowfreq 65%

basics

~20 s

docker logs only replays what the container's main process wrote to stdout and stderr, captured by the logging driver. Logs written to a file inside the container are invisible to it. The app must log to stdout/stderr, or the file must be symlinked to /dev/stdout.

open as a page

A container on a Docker host keeps disappearing and nobody sees it happen. Describe how you would use 'docker inspect' and 'docker events' to establish what is actually going on.

level: middleimportance: should knowfreq 45%

basics

~20 s

docker inspect dumps a container's full JSON state — exit code, OOMKilled flag, restart count, mounts, network, config — for the current or last run. docker events streams the daemon's real-time lifecycle events (create, start, die, kill, destroy, health_status) so you can watch it happen and correlate timings.

open as a page

A Docker host runs out of disk and the culprit is a multi-gigabyte JSON log file under /var/lib/docker/containers. Explain why that happened and how you would configure the daemon so it cannot happen again.

level: seniorimportance: should knowfreq 50%

basics

~20 s

Docker's default json-file driver writes container output to an unbounded file on the host with no rotation. Set max-size and max-file on the driver — per container or as a daemon-wide default in /etc/docker/daemon.json — then restart the daemon and recreate containers.

open as a page