What does `docker context use` change, and how does DOCKER_HOST interact with it?
answer
- The CLI is only an API client
- One saved name for one endpoint
- docker context ls marks the current one
- An environment variable can outrank it
- DOCKER_HOST beats docker context use
basics
~20 sA docker context is a saved name for one engine endpoint: a unix socket, a tcp:// URL or an ssh:// URL. docker context use points every later CLI command at that daemon, and DOCKER_HOST overrides the selected context.
solid answer
~40 sThe `docker` binary is a thin client over the Engine API, so before it does anything it must decide which `dockerd` to call. A **context** is a stored, named answer to that: an endpoint plus any TLS material needed to reach it, created with `docker context create build-host --docker "host=ssh://[email protected]"`. `docker context use build-host` writes that name as `currentContext` in `~/.docker/config.json`; it opens no tunnel and changes nothing else about the shell. From then on `docker run`, `docker ps` and `docker build` all execute on that daemon's host. Endpoint sources are ranked: the `-H`/`--host` flag beats `DOCKER_HOST`, which beats `DOCKER_CONTEXT`, which beats the context chosen by `docker context use`. A stale `DOCKER_HOST` in a shell profile therefore silently wins, which is the usual reason a command runs on the wrong engine.
code
bash · 4 linesdocker context create build-host --docker "host=ssh://[email protected]"
docker context use build-host
docker context ls
docker context inspect build-host --format '{{.Endpoints.docker.Host}}'go deeper
Be ready to say in one sentence what a context is - a saved name for one engine endpoint - and to show docker context create, use, ls and inspect without hesitating.
Explain the mechanics: the CLI is an API client, use writes currentContext to a config file, and endpoint selection is ranked flag, then DOCKER_HOST, then DOCKER_CONTEXT, then context.
Show the diagnostic habit. When output looks wrong, prove which engine answered before debugging anything else, and know that a stray environment variable overrides the context the star is next to.
Own the convention: contexts for humans, explicit DOCKER_HOST or --context in automation, and a rule against ambient environment variables that make a script's target depend on the machine it runs on.
## The CLI is a client, and a context names the server The `docker` command-line tool does very little on its own. Every `docker run`, `docker ps`, `docker pull` and `docker build` is an HTTP request to the Engine API, served by a `dockerd` process that is usually - but not necessarily - on the same machine. The only thing the CLI must settle before sending a request is *which* daemon to send it to. A **context** is a named, persisted answer to that question. It holds an endpoint - a unix socket path such as `unix:///var/run/docker.sock`, a `tcp://` URL, or an `ssh://` URL - and optionally the TLS certificate paths used to reach a TLS-protected endpoint. Contexts live in `~/.docker/contexts/` and the selected one is recorded as `currentContext` in `~/.docker/config.json`. ``` docker context create build-host --docker "host=ssh://[email protected]" docker context use build-host docker context ls # the current one is marked with * docker context inspect build-host ``` Every engine has a built-in context called `default`, which is the local daemon as configured by the CLI's defaults; Docker Desktop installs one named `desktop-linux` as well. ## What `use` does and does not do `docker context use build-host` writes one string to a config file. It does not start an SSH session, open a tunnel, sync files, or set anything in your environment that other programs can see. Nothing is validated at that moment either: if the endpoint is wrong you find out on the next command, not on the switch. What changes is the destination of everything afterwards. `docker images` lists the remote daemon's images, not your laptop's. `docker run` starts the container on the remote host, using that host's kernel, CPU architecture, disks and network interfaces. `docker pull` is performed *by the remote daemon* against the registry, so the fact that your laptop already holds the image is irrelevant. Commands that look local because they move data - `docker cp`, `docker logs`, `docker exec -it` - still work, because they stream over the same API rather than touching your filesystem directly. ## Precedence: four ways to name an endpoint Four mechanisms can select an endpoint and they are strictly ranked, strongest first: 1. `-H` / `--host` on the command itself (`docker -H ssh://[email protected] ps`) 2. the `DOCKER_HOST` environment variable 3. the `DOCKER_CONTEXT` environment variable 4. the context selected by `docker context use` The practical consequence is that environment variables outrank the thing you explicitly switched to. A CI job that exports `DOCKER_HOST`, a direnv file, or one forgotten line in `~/.zshrc` will quietly send your commands somewhere else while `docker context ls` still shows the star next to the context you picked. When a command lands on the wrong engine, `docker context ls` alone is not enough evidence - check the environment too. There is also a per-command `--context` flag (`docker --context build-host ps`) for a one-off without switching. ## Why teams point the CLI elsewhere The common motivations are all about the daemon's host being better at something than the laptop. A Kotlin service with a multi-stage Gradle build compiles far faster on a build host whose dependency cache is already warm - a run that reuses that cache at a 71% hit rate finishes in a fraction of the cold time, and the cache stays on the remote engine between runs. Other reasons: building for an architecture your machine does not have; running an integration stack that needs more RAM than a laptop has; or letting several engineers share one beefy engine. ## Contexts versus environment variables Both work; they suit different situations. A context is declarative, survives new shells, can carry TLS certificate paths inside its own definition, and can be listed and inspected. Environment variables are per-shell and per-process, which makes them the right tool inside a script or a CI job where you want an explicit, self-contained target and no dependence on whatever the machine's current context happens to be. Many teams do both: contexts for humans, `DOCKER_HOST` for automation. One last habit worth building: because switching is invisible and sticky, treat "which context am I on?" as the first question whenever a Docker command produces a result that makes no sense - an image you just built that has vanished, a port that is not listening, a volume that is empty.
- DOCKER_HOST is exported and a context is selected. Which one does the docker CLI use?DOCKER_HOST wins. The order is `-H`/`--host` on the command, then `DOCKER_HOST`, then `DOCKER_CONTEXT`, then the context set by `docker context use`. This is why a forgotten export in a shell profile or a CI job sends commands to an engine you did not choose, while `docker context ls` still shows a star beside the one you did.
- How do you run a single command against another engine without switching context?Use the per-command flags: `docker --context build-host ps` selects a stored context for that invocation, and `docker -H ssh://[email protected] ps` names an endpoint directly with no stored context at all. Both leave `currentContext` untouched, which makes them safer inside scripts than a `docker context use` that outlives the script.
- You switch to a remote context and `docker images` no longer lists an image you built this morning. What happened?Nothing is broken - image storage belongs to the daemon, not the CLI. The image you built this morning is in the local engine's store, and you are now listing the remote engine's store. Either rebuild on the remote engine, push and pull it through a registry, or switch back to `default`.
A context is like the saved connection profile in a database client: picking one changes where every subsequent query runs, but it does not move your local files anywhere.
saying these in an interview costs you the question
- Thinks a context opens a tunnel or VPN to the remote host
- Believes docker context use exports environment variables other tools see
- Assumes images built locally are visible to the remote daemon
- Cannot say whether DOCKER_HOST or the current context wins
- Confuses an engine context with a build context directory
- Thinks a context stores registry login credentials