Docker Contexts
Summary
- A Docker context is a named bundle of connection settings that tells the CLI which engine to talk to.
- Insight: because the CLI is a thin API client, switching contexts changes where your commands run without changing the commands themselves.
- Key Concepts: the endpoint (Unix socket, SSH, or TLS/TCP), the default context, and
DOCKER_CONTEXT/DOCKER_HOSToverrides. - When to Use: targeting a remote build host, managing a production engine, or scripting deploys across several machines.
- Limitations: contexts route to a single engine, not a cluster. For multi-node workloads you deploy to Kubernetes, which uses containerd on nodes.
Recipe
Create a context for a remote host over SSH, then switch to it.
docker context create buildhost \
--docker "host=ssh://ops@buildhost.example.com"
docker context use buildhost
docker psEvery subsequent command now runs against buildhost until you switch back with docker context use default.
Working Example
A realistic setup: a local default, a remote SSH build host, and a TLS-secured production engine.
# List existing contexts (default is created automatically)
docker context ls
# 1. Remote build host over SSH - no ports or certs to manage
docker context create buildhost \
--description "Shared ARM build box" \
--docker "host=ssh://ops@buildhost.example.com"
# 2. Production engine over mTLS on a locked-down TCP endpoint
docker context create prod \
--description "Prod engine (mTLS)" \
The --context flag and DOCKER_CONTEXT variable are the safest ways to target production, because they avoid leaving your shell pointed at the wrong engine.
Deep Dive
Where contexts live
Contexts are stored under ~/.docker/contexts/ as metadata files. There is no daemon involvement; this is purely CLI configuration.
The special default context reflects your local socket or the classic DOCKER_HOST environment variable.
Endpoint types
An SSH endpoint (ssh://user@host) tunnels the API over an existing SSH connection. It needs no open Docker ports and reuses your SSH keys, which makes it the simplest secure remote option.
A TCP endpoint (tcp://host:2376) speaks the API over the network and must be protected with mutual TLS. Never expose an unauthenticated TCP daemon; it is remote root.
A Unix socket endpoint (unix:///var/run/docker.sock) is the local default and also the rootless socket under $XDG_RUNTIME_DIR.
Selection precedence
The CLI resolves the target engine in this order: the --host/-H flag, then DOCKER_HOST, then --context, then DOCKER_CONTEXT, then the current context, then default.
Knowing this order prevents surprises. If DOCKER_HOST is set in your profile, it wins over any context you selected.
Contexts and buildx
BuildKit builders are managed separately with docker buildx. A buildx builder can be backed by a context, letting you run heavy or multi-arch builds on a remote or cloud engine.
docker buildx create --name armbuilder --use buildhost
docker buildx build --platform linux/arm64 -t myorg/api:1.4.0 --push .This offloads the build to buildhost while pushing the result straight to a registry.
Gotchas
A lingering DOCKER_HOST in your shell profile silently overrides every context. Unset it if docker context use seems ignored.
Running a destructive command on the wrong context is a classic incident. Prefer docker --context prod ... over persistently switching to prod.
SSH contexts require the remote user to have Docker access. If commands hang or deny permission, check the remote docker group membership.
TLS material referenced by a context uses absolute or ~-expanded paths at connect time. Moving the certs breaks the context silently.
Contexts do not sync between machines. Automate their creation in your dotfiles or bootstrap scripts rather than recreating them by hand.
Alternatives
DOCKER_HOST alone works for quick one-offs but stores no metadata and no TLS paths, so contexts are better for anything reused.
Kubernetes kubectl contexts serve the analogous role for clusters. Do not confuse the two: a Docker context targets one engine, a kube-context targets one cluster.
Cloud provider CLIs can provision managed build services, but a plain SSH context to a spot instance is often simpler and cheaper.
For fully ephemeral remote builds, docker buildx with a docker-container or remote driver can spin up builders on demand without a standing context.
FAQs
How do I see which engine I am pointed at? docker context ls marks the active context, or run docker info --format '{{.Name}}'.
Can I use a context in CI? Yes. Set DOCKER_CONTEXT or pass --context, keeping the runner's shell state clean.
Do contexts work with Docker Compose? Yes. docker compose honors the active context and the --context flag.
Is an SSH context slower than TCP? Slightly, due to SSH overhead, but it is far easier to secure and usually fast enough.
What happens if the remote engine is down? Commands fail with a connection error. The context definition remains; only the endpoint is unreachable.
Can one context target a Kubernetes cluster? No. Docker contexts target Docker engines only. Use kubectl for clusters.
Related
- How the Docker Engine Works
- Docker Engine Basics
- Essential CLI Commands
- Docker Desktop vs Linux Engine
- Engine Configuration
Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).