Use Docker Contexts over SSH for Safer Remote Admin
Control a remote Docker engine through the official SSH transport so day-two admin work stays cleaner and safer than exposing the daemon on the network.
How to create an SSH-backed Docker context, verify which engine the CLI is targeting, inspect remote resources, and switch back to the local default safely.
Operators who already run Docker on a VPS and want cleaner remote control than ad hoc SSH wrappers or public TCP daemon exposure.
The common mistake is forgetting which context is active and then running a destructive command against the wrong engine.
Before you begin
- A local machine with a Docker CLI that supports the top-level
docker contextcommand. - SSH access to the remote Linux host.
- Docker already installed and working on that host.
- A remote user that can talk to the Docker socket on the host.
Docker's current documentation keeps the safest first recommendation simple: use the local Unix socket by default, and if you need remote access, prefer SSH or a TLS-protected socket instead of exposing an unauthenticated TCP daemon. Contexts build on that by storing the connection details and letting you switch targets cleanly with one command.
Step 1: Understand what a Docker context changes
A Docker context is just a named set of endpoint details and metadata. The Docker docs describe it as the information required to manage resources on a daemon. That matters because it lets you stop hard-coding connection details into shell history.
List the contexts you already have:
docker context ls
docker context inspect defaultThe active context is marked with an asterisk. Until you change it, that is usually default, which points at the local socket on your machine.
docker rm, docker compose up, or image-prune commands.Step 2: Confirm SSH and Docker access on the remote host
Before you create the context, prove the basics from your local machine:
ssh docker-user@host1.example.com
docker info
exitIf docker info fails on the host, fix that first. The SSH-backed context still relies on the remote user being allowed to reach Docker. Docker's daemon-protection docs explicitly note that the remote username must have permission to access the Docker socket.
If you use SSH often, add connection reuse settings to your local ~/.ssh/config so repeated Docker CLI calls are less expensive:
Host *
ControlMaster auto
ControlPath ~/.ssh/control-%C
ControlPersist yesStep 3: Create the SSH-backed context
Create a named context using the official SSH host syntax:
docker context create \
--docker host=ssh://docker-user@host1.example.com \
--description "Remote VPS engine" \
my-remote-engineInspect what Docker stored:
docker context inspect my-remote-engineYou should see the Docker endpoint set to an ssh:// URL rather than a public TCP daemon address. That is the security win here: the Docker API stays behind SSH instead of being opened directly on the network.
Step 4: Use the remote context deliberately
Switch to the remote context:
docker context use my-remote-engine
docker context lsNow verify that the CLI is really talking to the remote engine:
docker info
docker ps
docker image ls
docker network lsIf you only need the remote host for one command, you do not have to switch globally. The docs also support the global flag form:
docker --context my-remote-engine psThat is a strong habit when you want explicitness in scripts or when you are bouncing between a laptop engine and one remote VPS in the same terminal session.
Step 5: Switch back to the local default context
When remote work is done, return to the local engine:
docker context use default
docker context ls
docker infoDo not normalize staying on a remote context all day unless you have a strong reason. Switching back reduces the chance that the next test command hits production infrastructure by accident.
If you prefer temporary shell scoping instead of changing the global active context, export DOCKER_CONTEXT only for the current shell:
export DOCKER_CONTEXT=my-remote-engine
docker ps
unset DOCKER_CONTEXTRollback and recovery notes
This workflow is easy to unwind because the context lives on your client, not the server. If the context points at the wrong host or user, remove it and recreate it:
docker context use default
docker context rm my-remote-engine
docker context create --docker host=ssh://docker-user@host1.example.com my-remote-engineIf you are troubleshooting production access, do that with ordinary SSH first. Contexts are an admin convenience layer, not a substitute for basic host reachability checks.
Troubleshooting common context mistakes
docker info fails only through the context.
The remote user may not be allowed to access the Docker socket, or SSH may be working but not loading the expected environment.
You forgot which engine is active.
Run docker context ls before any risky operation. Make it part of your muscle memory.
You are tempted to open port 2375 publicly.
Do not. Docker's own docs position SSH or TLS as the protected options. Public TCP daemon exposure is the wrong default for this guide.
The remote CLI feels slow.
Use SSH connection reuse with ControlMaster, ControlPath, and ControlPersist so multiple Docker calls do not rebuild the SSH session every time.
