skip to content

Container Lifecycle

How a container starts, runs and dies: run/start/exec, restart policies, CPU and memory limits, runtime health state, signals and exit codes. Interviewers probe it because graceful shutdown and PID 1 are where deploy-time data loss actually comes from.

part ofDockeroverview, primer and where to startread it →
on this pageshow

questions

page 1 of 2

How does `docker cp` move files between the host and a container, and what can't it do?

level: juniorimportance: must knowfreq 74%

answer

  1. No process runs inside the container
  2. Think about what the Engine API speaks
  3. A tar stream over /containers/{id}/archive
  4. `-` means stdin or stdout
  5. Works on a container that never started

basics

~20 s

docker cp streams a tar archive through the Docker Engine API, so the daemon does the extraction and the image needs no shell or tar binary. It works on stopped containers, expands no wildcards, and does not preserve ownership unless you pass -a.

solid answer

~50 s

`docker cp` is not a shell copy. The CLI opens the Engine API endpoints `GET /containers/{id}/archive` and `PUT /containers/{id}/archive` and pushes or pulls a **tar stream**; the daemon packs and unpacks it on the container's filesystem. Two consequences matter in interviews. First, nothing runs inside the container, so it works on a **stopped or created** container and on a distroless image with no shell, no `cp` and no `tar`. Second, because no shell is involved, the path is taken literally — `docker cp c:/logs/*.log .` fails, there is no glob expansion. `-` as the source or destination means the tar stream comes from stdin or goes to stdout, so `docker cp c:/var/log - > logs.tar` gives you a tarball directly. Use `-a` to carry UID/GID across, and remember copying into a running container writes files under the app's feet with no notification.

code

bash · 6 lines
bash
docker create --name gw ghcr.io/example/ingest-gateway:1.9
docker cp gw:/etc/ingest/config.yaml ./config.yaml

docker cp ./config.yaml gw:/etc/ingest/config.yaml

docker cp -a gw:/var/lib/ingest/. ./ingest-data

go deeper

for a junior

Know both directions of the syntax and that the container does not need to be running. Be able to say that a tar stream over the Docker API is what moves the bytes, not a shell command inside the container.

for a middle

Explain the API endpoints, the directory and /. path rules, what -a and -L change, and why globbing does not work. Be ready to show the stdin/stdout - form.

for a senior

Show the incident habit: copy the artefact out of the stopped container before removing it, and treat any copy into a running container as drift that will vanish on the next restart.

for a principal

Own the policy question: if teams routinely docker cp files into running containers, the image or the mount contract is wrong. Decide where configuration and data legitimately enter a container and make that path the easy one.

### What the command actually is `docker cp` looks like `cp`, but it is a thin wrapper over two Docker Engine API endpoints: - `GET /containers/{id}/archive?path=…` — the daemon walks the path inside the container's filesystem and returns a **tar stream**; - `PUT /containers/{id}/archive?path=…` — the daemon reads a **tar stream** from the request body and extracts it into the container's filesystem. The CLI's job is to build or unpack that tar on the host side. Everything on the container side is done by the daemon, walking the container's merged root filesystem from the host. **No process is started inside the container.** ### The four consequences that get asked about **1. It works on a stopped container.** The container only has to exist. `docker create` it and never start it, or let it exit with a stack trace, and you can still pull files out. This is why `docker cp` is the standard answer to "the container crashed, get me the dump/report it wrote": you do not need the process alive, only the container not yet `docker rm`-ed. The corollary is that `docker run --rm` destroys the container the moment it exits, taking the evidence with it. **2. It needs nothing in the image.** A distroless or `FROM scratch` image with a single static binary has no shell, no `cat`, no `tar`. `docker exec … tar` is impossible there; `docker cp` still works, because the tar is produced by the daemon, not by the container. **3. There is no shell, so there is no globbing.** `docker cp gw:/var/log/*.log ./` does not expand — the daemon looks for a path literally named `*.log` and you get a "no such file or directory" style error. Copy the directory instead (`docker cp gw:/var/log ./log`), or run a shell explicitly with `docker exec sh -c 'tar cf - /var/log/*.log' > logs.tar`. The same applies to `~` and `$HOME`. **4. `-` means stdin/stdout, and the payload is a tar.** `docker cp CONTAINER:SRC -` writes a tar archive to stdout; `docker cp - CONTAINER:DEST` reads one from stdin. That is how you pipe container→container without touching disk, and how you stream a directory straight into `tar -x` on the host. ### Path semantics people trip on The directory rules mirror `cp -a`: if the source is a directory and the destination exists as a directory, the source directory is copied **into** it, producing `dest/src/...`. Ending the source with `/.` copies the *contents* instead — `docker cp gw:/app/. ./app` fills `./app` rather than creating `./app/app`. If the destination does not exist, its parent must; a non-existent parent is an error, not an mkdir -p. Ownership is the other classic surprise. `-a` / `--archive` preserves UID/GID from the source; without it, the copied files can land with ownership that does not match the container's non-root application user, and the app then fails to read or rewrite them. If you copy a config file into a container running as UID 10001, check the ownership afterwards rather than assuming. Flags worth knowing: `-L` / `--follow-link` dereferences a symlink in the source path instead of copying the link itself; `-q` suppresses the progress output. Docker documents that some paths cannot be copied out — entries under `/proc`, `/sys`, `/dev` and tmpfs are not ordinary files in the container's layered filesystem. ### When it is the wrong tool `docker cp` is a *rescue and inspection* tool, not a delivery mechanism. Copying application files into a running container mutates the container's writable layer and leaves you with a container whose contents no longer match its image — the next restart from that image silently discards the change, and nobody can tell what was done. For files that must be present every time, put them in the image at build time or mount them; keep `docker cp` for pulling a heap dump, a core file, a profiler output or a log out of a container that is already broken. A last operational note: copying into a **running** container is not atomic from the application's point of view. The daemon extracts the tar entry by entry while the process is reading; a config file can be observed half-written. If the app watches the file for changes, write to a temporary name and move it with `docker exec`, or restart the container.

  • The image is distroless — no shell, no tar, no cp. Does `docker cp` still work?
    Yes. The daemon packs and unpacks the tar on the host side against the container's filesystem, so nothing has to exist inside the image. That is exactly why `docker cp` is the extraction tool for minimal images, where `docker exec tar` is impossible.
  • Why does `docker cp gw:/var/log/*.log .` fail?
    Because no shell is involved, so nothing expands the glob. The daemon looks for a path literally named `*.log`. Copy the whole directory, or expand the pattern inside the container with `docker exec sh -c 'tar cf - /var/log/*.log'` and redirect the tar on the host.
  • How do you get a directory out of a container as a single tar file without writing it to disk twice?
    `docker cp CONTAINER:/path - > path.tar`, or pipe it: `docker cp CONTAINER:/path - | tar -tvf -`. The `-` destination makes the CLI emit the raw tar stream it already receives from the API, so nothing is unpacked and repacked.

saying these in an interview costs you the question

  • Claims the container must be running to copy files out
  • Thinks `docker cp` shells out to `cp` inside the container
  • Expects wildcards and `$HOME` to expand in the path
  • Assumes the image needs a tar or cp binary
  • Uses `docker cp` to deploy config into running production containers
  • Assumes file ownership is preserved by default

context

open as a page

How do you give a Docker container access to one host device such as /dev/ttyACM0, and why is --privileged the wrong answer?

level: juniorimportance: must knowfreq 52%

basics

~20 s

Use docker run --device /dev/ttyACM0:/dev/ttyACM0. Docker creates that one device node inside the container and permits it in the container's device allow-list. --privileged works only by unlocking every host device at once, which is far too broad.

open as a page

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%

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.

open as a page

After a container stops, where do you find the exit code it reported, and what do the values 0 and 1 tell you about what happened?

level: juniorimportance: must knowfreq 62%

basics

~20 s

docker ps -a shows Exited (N) in the STATUS column, and docker inspect --format '{{.State.ExitCode}}' <container> gives the number. 0 means the main process finished successfully; any non-zero value means it failed — 1 is the generic "the application errored" code.

open as a page

What does the Dockerfile `HEALTHCHECK` instruction do at runtime, and where do you see its result?

level: juniorimportance: must knowfreq 66%

basics

~20 s

It tells Docker a command to run periodically inside the running container to test whether the app actually works. Exit 0 means healthy, 1 means unhealthy. The result shows in docker ps as (healthy), (unhealthy) or (starting) next to the container's uptime, with details in docker inspect.

open as a page

Why does a Docker container normally run a single foreground process rather than several?

level: juniorimportance: must knowfreq 72%

basics

~10 s

Docker Engine supervises only PID 1. With one foreground process per container, the container's logs, exit code, restart policy and resource limits all describe that process; anything else running inside is governed by nothing.

open as a page

Docker Engine supports four container restart policies — `no`, `on-failure`, `always` and `unless-stopped`. What does each one mean, and how do you set or change the policy on a container?

level: juniorimportance: must knowfreq 62%

basics

~20 s

no never restarts (the default). on-failure[:N] restarts only on a non-zero exit, at most N times. always restarts on any exit and after daemon start. unless-stopped is like always but stays down once you stopped it. Set with --restart; change with docker update --restart.

open as a page

Walk through exactly what happens, step by step, when you run `docker stop` on a running container, and how that sequence differs from `docker kill`.

level: juniorimportance: must knowfreq 70%

basics

~20 s

docker stop sends SIGTERM to the container's PID 1, waits a grace period (10 seconds by default, changed with -t), then sends SIGKILL if the process is still alive. docker kill skips the wait and sends SIGKILL immediately.

open as a page

Explain the difference between the `docker create`, `docker run`, and `docker start` commands, and give a case where you would use `create` instead of `run`.

level: juniorimportance: must knowfreq 62%

basics

~20 s

docker create makes a container from an image without starting it (state: created). docker start starts an existing container. docker run is create plus start in one step. Use create when you want to configure or copy files into a container, or pre-stage it, before it ever runs.

open as a page

What makes `postgres` on Docker Hub a Docker Official Image, and how do the publisher tiers differ?

level: juniorimportance: must knowfreq 64%

basics

~20 s

Docker Official Images are a curated set in Docker Hub's reserved library namespace, which is why they pull by a bare name like postgres. Verified Publisher and Sponsored OSS images come from an identity-checked vendor; everything else is unreviewed.

open as a page

What is the difference between `docker save`/`load` and `docker export`/`import`?

level: middleimportance: must knowfreq 63%

basics

~20 s

docker save archives an image with all its layers, tags and history, and docker load restores it unchanged. docker export dumps a container's filesystem as one flat tar; docker import turns that into a single-layer image with no history and no CMD or ENTRYPOINT.

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 stopped container reports exit code 137, and another reports 143. Explain Docker's "128 + N" convention and say which signal produced each of those two codes.

level: middleimportance: must knowfreq 72%

basics

~20 s

When a process is terminated by a signal rather than exiting on its own, the reported status is 128 plus the signal number. 137 = 128 + 9 = SIGKILL (force kill, often an out-of-memory kill). 143 = 128 + 15 = SIGTERM (a polite stop request the process did not survive).

open as a page

Explain what `--interval`, `--timeout`, `--retries` and `--start-period` control on a container health probe, and how they determine when the reported state flips.

level: middleimportance: must knowfreq 58%

basics

~20 s

--interval is the wait between probe runs, --timeout is how long one probe may take before it counts as a failure, --retries is how many consecutive failures flip the state to unhealthy, and --start-period is an initial window where failures don't count — one success at any time marks the container healthy.

open as a page

What does running supervisord inside a Docker container cost you when the container stops or a process crashes?

level: middleimportance: must knowfreq 56%

basics

~20 s

The supervisor becomes PID 1, so Docker only ever sees the supervisor. Stop signals pass through a second, nested timeout; a crashed program leaves the container reporting Up with the supervisor's exit code, so no restart policy fires.

open as a page

Compare Docker's `--cpus`, `--cpu-shares` and `--cpu-quota`/`--cpu-period` flags: which actually caps a container's CPU usage, which only matters under contention, and how would you tell that a container is being CPU-throttled?

level: middleimportance: must knowfreq 62%

basics

~20 s

--cpus=N is a hard cap — shorthand for --cpu-quota/--cpu-period (CFS bandwidth), e.g. 150000/100000 for 1.5 CPUs. --cpu-shares is only a relative weight that applies when the host is contended; idle CPU is still free to take. Throttling appears as nr_throttled/throttled_usec in the cgroup's cpu.stat.

open as a page

What actually happens when a process in a Docker container allocates past the container's `--memory` limit, and what does the `--memory-swap` flag change about that behavior?

level: middleimportance: must knowfreq 70%

basics

~20 s

The kernel first reclaims what it can; if that is not enough, the cgroup OOM killer SIGKILLs a process inside that container only. If the victim is PID 1 the container dies with exit code 137 and State.OOMKilled=true. --memory-swap sets the combined memory+swap ceiling; setting it equal to --memory disables swap.

open as a page

In Docker Engine, what is the practical difference between the `always` and the `unless-stopped` restart policies, and in which specific situation does that difference actually become visible?

level: middleimportance: must knowfreq 54%

basics

~20 s

Both restart the container on any exit. They differ only for a container you deliberately stopped: with always it comes back when the daemon restarts or the host reboots; with unless-stopped it stays down. In every other case they behave identically.

open as a page

A service built with `CMD npm start` in its Dockerfile never reacts to `docker stop` — it always takes the full grace period and dies hard. Explain why the shell form of CMD/ENTRYPOINT causes this, and show how you would fix it.

level: middleimportance: must knowfreq 62%

basics

~20 s

Shell form wraps the command in /bin/sh -c, so the shell is PID 1 and your app is a child. Docker signals PID 1 — the shell — which does not forward SIGTERM. Use exec form (CMD ["npm","start"]) or exec in the entrypoint script so the app is PID 1.

open as a page

Name the states a Docker container can be in and describe what moves it between them, including what the `dead` state means.

level: middleimportance: must knowfreq 52%

basics

~20 s

created, running, paused, restarting, removing, exited, dead. run/start move created or exited to running; stop/kill or the process ending move running to exited; pause/unpause toggle paused; rm moves through removing to gone. dead means partial removal failed and the container is unusable.

open as a page

How do you configure a third-party service image such as `postgres` without building your own image?

level: middleimportance: must knowfreq 68%

basics

~20 s

Through the environment variables the image documents. A service image's entrypoint script reads them at container start and writes the real configuration, so docker run -e POSTGRES_PASSWORD=... -e POSTGRES_DB=... configures it without a Dockerfile of your own.

open as a page

A container stopped with exit code 137. How do you determine whether the kernel's out-of-memory killer did it or something else sent SIGKILL, and what evidence do you collect?

level: seniorimportance: must knowfreq 58%

basics

~20 s

137 only says "killed by SIGKILL". Check docker inspect --format '{{.State.OOMKilled}} {{.State.ExitCode}}' <container>: true means the kernel out-of-memory killer fired. If it is false, look for a stop that timed out into SIGKILL, a docker kill, or a host-level kill — using timestamps, daemon logs, and dmesg.

open as a page

A container reports `(unhealthy)` in `docker ps` but keeps running and still receives traffic. Why doesn't Docker Engine act on that status, and how do you make something act on it?

level: seniorimportance: must knowfreq 56%

basics

~20 s

Docker Engine only reports health; it never restarts on it. Restart policies react to the main process exiting, and an unhealthy container hasn't exited. To act on it you need a consumer: an orchestrator, Compose dependency conditions, or your own watcher on the health_status event stream.

open as a page

A JVM service runs in a container capped at 512 MB and keeps getting killed by the kernel, even though its heap usage looks small and it never throws `java.lang.OutOfMemoryError`. How does a modern JVM discover container CPU and memory limits, and how would you size it so this stops happening?

level: seniorimportance: must knowfreq 55%

basics

~20 s

Modern JVMs read cgroup limits (container support is default-on since JDK 10, backported to 8u191) and default the heap to about 25% of the container limit. The kill comes from total process memory: heap plus metaspace, thread stacks, code cache, direct buffers and native allocations. Size with -XX:MaxRAMPercentage and leave real non-heap headroom.

open as a page

Why does a program running as PID 1 inside a container often ignore SIGTERM entirely, even though the same binary shuts down correctly when you run it on a normal Linux host?

level: seniorimportance: must knowfreq 48%

basics

~20 s

The Linux kernel treats PID 1 specially: signals with no explicitly installed handler are discarded instead of applying their default action. On a host your process is not PID 1, so SIGTERM's default action (terminate) applies. As PID 1, no handler means nothing happens.

open as a page

How do you check what CPU and memory running Docker containers are using right now, and what does each column of the `docker stats` output mean?

level: juniorimportance: should knowfreq 50%

basics

~20 s

Run docker stats. It live-streams per-container CPU % (summed across cores, so it can exceed 100%), MEM USAGE / LIMIT and MEM %, NET I/O, BLOCK I/O and PIDS, read from each container's kernel cgroup counters. Add --no-stream for a single snapshot.

open as a page

How would you list Docker containers that are not currently running, and then narrow that list to ones matching a particular label, name pattern, or image?

level: juniorimportance: should knowfreq 38%

basics

~10 s

docker ps shows only running containers; docker ps -a shows all states. Narrow with --filter: status=exited, label=team=payments, name=api, ancestor=nginx:alpine. Add -q for IDs only and --format for custom columns.

open as a page

What does `docker commit` capture from a container, and why is the resulting image a poor deliverable?

level: middleimportance: should knowfreq 48%

basics

~20 s

docker commit freezes a container's writable layer as a new layer on top of its image and copies the container's runtime config into the new image. Nothing records how that state was produced, so the image cannot be rebuilt, reviewed or trusted.

open as a page

What does `docker run --gpus all` require on the host, and what does it actually do to the container?

level: middleimportance: should knowfreq 62%

basics

~20 s

--gpus only records a device request; a GPU-aware runtime must be installed on the host. The NVIDIA Container Toolkit's hook then creates /dev/nvidia* nodes in the container and mounts the host's driver libraries and nvidia-smi into it.

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

showing 1–30 of 50