Create a Safe, Inspectable Docker Context for a Local or Remote Engine
You will finish with a named Docker context that points at a chosen engine, plus checks that show exactly what it contains before you use it. The examples use Docker CLI 29.8.1 from package docker-ce-cli version 5:29.8.1-1~ubuntu.24.04~noble.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need the Docker CLI and either a local Unix socket, an SSH account on a host running Docker, or the TLS files and endpoint for a secured daemon. Creating a context is an ordinary user operation in the examples below. Accessing the engine may require membership of the Docker socket group, SSH access, or suitable certificate permissions. Do not use sudo unless your local Docker setup specifically requires it.
Safety boundary
Creating a context does not select it. The separate docker context use command changes the default for later Docker commands, so this guide verifies with explicit context selection first.
1. Check the command you have
Start with the installed help output. This reads local command metadata and does not contact a Docker daemon:
$ docker --version
Docker version 29.8.1, build 4a63305
$ docker context create --help
Usage: docker context create [OPTIONS] CONTEXT
Create a context
The command accepts one context name and these options: --description, --docker and --from. The --docker value describes the endpoint. Its recognised fields are host, ca, cert, key and skip-tls-verify. The --from option copies the Docker endpoint configuration from an existing named context.
Checkpoint: keep the context name short, specific and unused. Names are local identifiers, not DNS names. Check existing names before choosing one:
$ docker context ls
NAME DESCRIPTION DOCKER ENDPOINT
default * unix:///var/run/docker.sock
2. Create a context for a local socket
For a local daemon, pass the socket as a Docker endpoint. This example creates a separate name without selecting it:
$ docker context create \
--description "Local engine for testing" \
--docker host=unix:///var/run/docker.sock \
local-test
local-test
Successfully created context "local-test"
Use the exact socket path exposed by your host. /var/run/docker.sock and /run/docker.sock commonly refer to the same location, but do not assume that on a customised installation. The context stores endpoint metadata in Docker's context configuration under your Docker configuration directory; it does not start, stop or reconfigure the daemon.
Checkpoint: inspect the stored definition before running containers or images against it:
$ docker context inspect local-test
[
{
"Name": "local-test",
"Metadata": {},
"Endpoints": {
"docker": {
"Host": "unix:///var/run/docker.sock"
}
}
}
]
Additional fields can appear in the inspection output. Treat the endpoint as the authoritative detail. A context that points at a remote or production engine is a security-sensitive object because later commands can read or change that daemon.
3. Create a context for an SSH endpoint
SSH is usually the simplest remote option because Docker uses the SSH connection for transport and does not require you to distribute a Docker TLS key pair. Use an account that is allowed to access the remote Docker socket:
$ docker context create \
--description "Staging engine over SSH" \
--docker host=ssh://[email protected] \
staging
staging
Successfully created context "staging"
Replace both the account and host with values you control. Creating this record does not prove that SSH login or remote Docker access works. Verify the connection without making it the default:
$ docker --context staging version
Client:
Version: 29.8.1
...
Server:
Engine:
Version: 29.x
The server section is the useful result. If the command reports an SSH authentication failure, socket permission error or unreachable host, fix that access path before using the context. Do not replace a failed SSH check with an unverified TCP endpoint.
4. Create a TLS context when certificates are required
For a Docker daemon that exposes a TLS-protected TCP socket, supply the endpoint and certificate paths together:
$ docker context create \
--description "Production engine over TLS" \
--docker "host=tcp://engine.example.com:2376,ca=/home/USER/.docker/ca.pem,cert=/home/USER/.docker/cert.pem,key=/home/USER/.docker/key.pem" \
production-tls
production-tls
Successfully created context "production-tls"
Replace USER, the host name and every certificate path. The CA file limits which certificate authorities the client trusts; the certificate and key authenticate the client. Keep the private key readable only by the intended user. Do not put real private key contents in a shell command or paste them into tickets.
Do not use skip-tls-verify as a repair. The field is available in the endpoint configuration, but disabling certificate verification removes a protection against connecting to the wrong daemon. Correct the CA path or server certificate instead. If you inherited a context containing that setting, inspect and review it before use.
5. Copy an existing context deliberately
Use --from when the new context should inherit the endpoint configuration of an existing context:
$ docker context create \
--from staging \
--description "Staging smoke tests" \
staging-smoke
staging-smoke
Successfully created context "staging-smoke"
Check both names with docker context inspect. The source is named after --from and the new name is the final positional argument. If you omit --from, current Docker documentation says the new context is based on the current context. That is easy to miss when a shell has DOCKER_CONTEXT set, so inspect the result rather than relying on memory.
The endpoint form can also copy endpoint configuration with --docker from=staging. Use one approach consistently and verify the resulting endpoint:
$ docker context create \
--docker from=staging \
staging-copy
$ docker context inspect staging-copy
A copied context is not an independent security boundary. It can retain the same remote address and certificate material. Label it clearly so a later operator does not mistake it for a different engine.
6. Test without changing the default
Use the global --context option for a one-off check:
$ docker --context staging info
$ docker --context staging ps
These commands use staging for that invocation only. An alternative for a shell session is DOCKER_CONTEXT=staging, but remember that the environment variable overrides the configured context for commands in that shell:
$ export DOCKER_CONTEXT=staging
$ docker context show
staging
$ unset DOCKER_CONTEXT
Do not use docker context use staging casually on a shared workstation. It persistently changes the Docker CLI configuration for later shells. If you have already switched it, recover with:
$ docker context use default
default
Current context is now "default"
7. Remove a context you no longer need
Context creation changes local Docker configuration, so remove a test record when it is no longer useful:
$ docker context rm local-test
local-test
This removes the context definition, not the Docker daemon, its images, its containers or its volumes. Do not remove the context that is currently selected, and do not remove a context merely because its endpoint is temporarily unreachable. Inspect first if you are unsure:
$ docker context show
$ docker context inspect local-test
If a context name already exists, creation fails rather than silently replacing it. Choose another name or use the separate context update command after checking that changing the existing definition is intended.
Done means
- The context name is visible in
docker context lsand its endpoint is correct indocker context inspect. - A local, SSH or TLS endpoint was chosen deliberately, with placeholders replaced by verified values.
- The engine was tested with
docker --context NAME ...before any default-context change. - TLS verification remains enabled unless a documented security decision says otherwise.
- Unused test contexts were removed, and the default context was restored if it was changed.