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`.
answer
- create = configure, don't execute
- start = execute an existing container
- run = create + start (+ attach unless -d)
- Config is fixed at create; no ports on start
- create + docker cp to pre-populate or extract
basics
~20 sdocker 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.
solid answer
~60 sThey are three points on the same path. - **`docker create <image>`** allocates the container: writable layer, name, network settings, mounts, env, entrypoint — everything except execution. It prints the container ID and the container sits in the `created` state. - **`docker start <container>`** takes an existing container in `created` or `exited` and runs its entrypoint, moving it to `running`. - **`docker run <image>`** is `create` + `start` (+ `attach` unless you pass `-d`). All the configuration flags — `-p`, `-v`, `-e`, `--name`, `--network` — belong to the create step, which is why you cannot change them on `docker start`. Use `create` when you need to act on the container before its first execution — `docker cp` files into it, attach it to an extra network with `docker network connect`, or pre-create containers so a later start is fast. It is also handy in scripts where creation and launch are separate stages. The key consequence to remember: a container's configuration is fixed at creation, so changing a port or a mount means creating a new container.
code
bash · 4 linesdocker create --name seed -p 8080:80 nginx:alpine
docker cp ./site/ seed:/usr/share/nginx/html/
docker start seed
docker ps --filter name=seedgo deeper
Give the three-way distinction cleanly and name one create-only use case such as docker cp before first start.
Emphasize that configuration is fixed at creation and that docker update covers only a narrow set of runtime knobs.
Connect it to immutability practice: containers are replaced, not reconfigured, and scripts should treat create/start as separate stages when they need to intervene.
Frame it as why container config belongs in declarative artifacts (Compose files, manifests) rather than in ad-hoc CLI flags people re-type.
## One lifecycle, three entry points A Docker container is created from an image and then executed. Docker exposes those two steps separately and also fused together: ``` image --docker create--> [created] --docker start--> [running] --> [exited] image ------------------ docker run ---------------> [running] ``` ## docker create `docker create` does everything except run the process: - allocates the container's **writable layer** on top of the image's read-only layers, - assigns an ID and a name (`--name`, else a random adjective_scientist), - records the full configuration: entrypoint and command, environment variables, port mappings, volume and bind mounts, network attachment, resource limits, restart policy, labels, user, working directory, - sets up (or defers) the network endpoint. It prints the container ID. The container is now in the **`created`** state — it exists in `docker ps -a`, occupies disk for its writable layer, and has never executed anything. ## docker start `docker start <id|name>` takes an existing container and executes its recorded entrypoint. Valid from `created` (first run) and from `exited` (re-run). Useful flags: `-a/--attach` to attach stdout/stderr, `-i` for stdin. The crucial property: **`docker start` accepts almost no configuration**, because configuration was fixed at creation. There is no `docker start -p 8080:80`. If you need a different port mapping, environment variable, mount or network, you must create a new container. (`docker update` can change a narrow set of runtime knobs such as CPU/memory limits and restart policy; it cannot change ports, mounts or env.) Starting an exited container reuses **the same writable layer**, so files written during the previous run are still there. Process memory, however, is gone — the entrypoint runs from scratch. ## docker run `docker run` = create + start, and by default also attaches your terminal to the container's output. `-d/--detach` runs it in the background and prints the ID. `-it` gives you an interactive TTY. `--rm` tells the daemon to delete the container automatically when it exits, which keeps a dev machine from accumulating hundreds of dead containers. Because `run` includes `create`, every configuration flag you know from `run` is really a create-time flag. ## When create earns its keep 1. **Populate a container before it runs.** `docker create --name seed myimage`, then `docker cp ./config.yaml seed:/etc/app/`, then `docker start seed`. The files are in place before the entrypoint reads them. 2. **Extract artifacts from an image without running it.** `docker create --name tmp myimage` → `docker cp tmp:/app/dist ./dist` → `docker rm tmp`. The container never executes; you are just mounting the image's filesystem view. 3. **Attach multiple networks before first start.** `docker network connect` on a created container so the process sees both networks from its very first instruction. 4. **Pre-staging in scripts and orchestration**, where creation and launch happen at different times or in different steps. ## Related commands and mental model - `docker stop` / `docker kill` → `running` → `exited`. - `docker restart` = stop + start on the *same* container (same ID, same writable layer). - `docker rm` deletes the container object and its writable layer; only then is the disk reclaimed. - `docker ps` lists running containers; `docker ps -a` lists all states including `created` and `exited`. ## The mistake this question is really testing Interviewers ask this to see whether you understand that **a container is a configured object, not a command invocation**. Candidates who think `docker start` re-runs `docker run` with the old arguments — and could therefore take new ones — reveal the wrong model. Configuration is immutable after create; the unit of change is a new container.
- Can you change a container's published ports with `docker start`?No. Port mappings, mounts, environment variables and network attachment are all recorded at creation time, and `docker start` takes essentially no configuration flags. You must create a new container with the new settings. `docker update` covers only a narrow set of runtime knobs — CPU and memory limits, restart policy — not ports or mounts.
- When you start a previously exited container, what is preserved and what is not?The container's writable layer is preserved, so files written during the earlier run are still on disk, along with the container's ID, name and full configuration. Nothing in memory survives: the entrypoint process starts from scratch, so in-memory caches, open sockets and any state the process held are gone.
create builds and furnishes the house but leaves it empty; start moves the tenant in; run does both in one trip. You cannot add a room by moving in again.
saying these in an interview costs you the question
- Believing `docker start` can take `-p`, `-e` or `-v` flags like `docker run`
- Thinking `docker run` on the same image reuses the previous container rather than creating a new one
- Assuming a container in `created` state consumes no disk
- Confusing `docker restart` (same container) with `docker rm` plus a fresh `docker run`
- Saying start resumes the process where it left off, like unpausing