Develop on a remote Docker host
Sometimes you may want to use the Dev Containers extension to develop inside a container that sits on a remote server. Docker does not support mounting (binding) your local filesystem into a remote dev container, so Visual Studio Code's default devcontainer.json
behavior to use your local source code will not work. While this is the default behavior, in this section we will cover connecting to a remote host so that you can either use the Remote - SSH extension to open a folder on a remote host in a container, attach to any running container, or use a local devcontainer.json
file as a way to configure, create, and connect to a remote dev container using a socket.
Connect using the Remote - SSH extension
If you are using a Linux or macOS SSH host, you can use the Remote - SSH and Dev Containers extensions together. You do not even need to have a Docker client installed locally. To do so:
- Follow the installation and SSH host setup steps for the Remote - SSH extension.
- Optional: Set up SSH key based authentication to the server so you do not need to enter your password multiple times.
- Install Docker on your SSH host. You do not need to install Docker locally.
- Follow the quick start for the Remote - SSH extension to connect to a host and open a folder there.
- Use the Dev Containers: Reopen in Container command from the Command Palette (F1, ⇧⌘P (Windows, Linux Ctrl+Shift+P)).
The rest of the Dev Containers quick start applies as-is. You can learn more about the Remote - SSH extension in its documentation.
Connect using the Remote - Tunnels extension
You can use the Remote - Tunnels and Dev Containers extensions together to open a folder on your remote host inside of a container. You do not even need to have a Docker client installed locally. This is similar to the SSH host scenario above, but uses Remote - Tunnels instead. To do so:
- Follow the Getting Started instructions for the Remote - Tunnels extension.
- Install Docker on your tunnel host. You do not need to install Docker locally.
- Follow the steps for the Remote - Tunnels extension to connect to a tunnel host and open a folder there.
- Use the Dev Containers: Reopen in Container command from the Command Palette (F1, ⇧⌘P (Windows, Linux Ctrl+Shift+P)).
The rest of the Dev Containers quick start applies as-is. You can learn more about the Remote - Tunnels extension in its documentation.
Connect using the Docker CLI
This model only requires that a Docker Engine be running on a remote host that your local Docker CLI can connect to. While using the Remote - SSH and Remote - Tunnels extensions is easier and doesn't require the Docker CLI to even be installed locally, this model can be useful for situations where you already have a host you are connecting to from the command line. This approach is also useful if you are looking to attach to already running containers on this remote server.
A basic remote example
Setting up VS Code to attach to a container on a remote Docker host can be as easy as setting the Docker extension docker.environment
property in settings.json
and restarting VS Code (or reloading the window).
For example:
"docker.environment": {
"DOCKER_HOST": "ssh://your-remote-user@your-remote-machine-fqdn-or-ip-here"
}
Using SSH requires a supported SSH client, that you have key based authentication configured for the remote host, and that the key is imported into your local SSH agent. See the article on using SSH Keys with Git for details on configuring the agent and adding your key.
At this point, you can attach to containers on the remote host. We'll cover more on information on how you can connect using settings and environment variables or Docker contexts later in this section.
For devcontainer.json
, there is one additional step: You'll need to update any configured (or auto-configured) bind mounts so they no longer point to the local filesystem.
There's two variations of this setup. The first is to create your remote dev container first, and then clone your source code into a named volume since this does not require you to have direct access to the filesystem on the remote host.
Here is a basic devcontainer.json
example of this setup:
{
"image": "node", // Or "dockerFile"
"workspaceFolder": "/workspace",
"workspaceMount": "source=remote-workspace,target=/workspace,type=volume"
}
In fact, the Dev Containers: Clone Repository in Container Volume... command in the Command Palette (F1) uses this same technique. If you already have a devcontainer.json
file in a GitHub repository that references an image or Dockerfile, the command will automatically use a named volume instead of a bind mount - which also works with remote hosts.
The second approach is to bind mount a folder on the remote machine into your container. This requires you to have access to the remote filesystem, but also allows you to work with existing source code on the remote machine.
Update the workspaceMount
property in the example above to use this model instead:
"workspaceMount": "source=/absolute/path/on/remote/machine,target=/workspace,type=bind,consistency=cached"
In either case, to try it out, run Dev Containers: Open Folder in Container..., and select the local folder with the .devcontainer.json
file in it.
See Converting an existing or pre-defined devcontainer.json for information on other scenarios like Docker Compose.
Connect using VS Code settings or local environment variables
If you already have a remote Docker host up and running, you can use the following properties in your workspace or user settings.json
to specify the host.
SSH protocol
Recent versions of Docker (18.06+) have added support for the SSH protocol to connect to remote Docker Host. This is easy to configure as you only need to set one property in settings.json
to use it.
First, install a supported SSH client, configure key based authentication), and then import your key into your local SSH agent (which often is not running by default on Windows and Linux). See the article on using SSH Keys with Git for details on configuring the agent and adding the key.
Then, add the following Docker extension docker.environment
property to settings.json
(replacing values as appropriate):
"docker.environment": {
"DOCKER_HOST": "ssh://your-remote-user@your-remote-machine-fqdn-or-ip-here"
}
After restarting VS Code (or reloading the window), you will now be able to attach to any running container on the remote host. You can also use specialized, local devcontainer.json
files to create / connect to a remote dev container.
Tip: If this is not working for you but you are able to connect to the host using SSH from the command line, be sure you have the SSH agent running with your authentication key. If all else fails, you can use an SSH tunnel as a fallback instead.
Using the TCP protocol
While the SSH protocol has its own built-in authorization mechanism, using the TCP protocol often requires setting other Docker extension properties in your settings.json
. These are:
"docker.environment": {
"DOCKER_HOST": "tcp://your-remote-machine-fqdn-or-ip-here:port",
"DOCKER_CERT_PATH": "/optional/path/to/folder/with/certificate/files",
"DOCKER_TLS_VERIFY": "1" // or "0"
}
As with SSH, restart VS Code (or reload the window) for the settings to take effect.
Using environment variables instead of settings.json
If you'd prefer not to use settings.json
, you can set environment variables in a terminal instead. The steps to do so are:
- Shut down all instances of VS Code.
- Ensure VS Code is in your operating system
PATH
. - Set the environment variables (for example
DOCKER_HOST
) in a terminal / command prompt. - Type
code
in this same terminal / command prompt to launch VS Code with the variables set.
Connect using Docker Contexts
Docker Contexts allow you to interact with different hosts - you can set up contexts for each host and switch between them.
You create new contexts with docker context create
. The current context can be changed using docker context use <context>
.
The Docker extension comes with the docker.environment
setting where environment variables like DOCKER_HOST
or DOCKER_CONTEXT
can be set that are also honored by the Dev Containers extension.
Note: The above settings are only visible when the Docker extension is installed. Without the Docker extension, Dev Containers will use the current context.
Converting an existing or pre-defined devcontainer.json
To convert an existing or pre-defined, local devcontainer.json
into a remote one, follow these steps:
-
Open a local folder in VS Code (not a remote one) where you want to convert the file.
-
If you did not select a folder with a
devcontainer.json
in it, you can pick a pre-defined one by running Dev Containers: Add Container Configuration File... from the Command Palette (F1). -
Follow these steps based on what your
.devcontainer/devcontainer.json
or.devcontainer.json
references to alter the source code mount:Dockerfile or image:
If you do not have login access to the remote host, use a Docker "volume" for your source code. Update
.devcontainer/devcontainer.json
as follows (replacingremote-workspace
with a unique volume name if desired):"workspaceMount": "source=remote-workspace,target=/workspace,type=volume" "workspaceFolder": "/workspace",
If you do have login access, you can use a remote filesystem bind mount instead:
"workspaceMount": "source=/absolute/path/on/remote/machine,target=/workspace,type=bind,consistency=cached" "workspaceFolder": "/workspace",
The
workspaceMount
property supports the same values as the Docker CLI--mount
flag if you have a different scenario in mind.Docker Compose:
If you do not have login access to the remote host, update (or extend) your
docker-compose.yml
. Replaceyour-service-name-here
with the value specified for the"service"
property indevcontainer.json
and appropriate andremote-workspace
with a unique volume name:version: '3' services: your-service-name-here: volumes: - remote-workspace:/workspace # ... volumes: remote-workspace:
If you do have login access, you can use a remote filesystem bind mount instead:
version: '3' services: your-service-name-here: volumes: - /absolute/path/on/remote/machine:/workspace:cached # ...
See the Docker Compose documentation on
volumes
if you need to support a different scenario. -
Run the Dev Containers: Reopen in Container command from the Command Palette (F1) or Dev Containers: Rebuild Container.
-
If you used a volume instead of a bind mount, use ⌃⇧` (Windows, Linux Ctrl+Shift+`) to open a terminal inside the container. You can run
git clone
from here to pull down your source code and use File > Open... / Open Folder... to open the cloned repository.
Next time you want to connect to this same container, run Dev Containers: Open Folder in Container... and select the same local folder in a VS Code window.
Optional: Making the remote source code available locally
If you store your source code on the remote host's filesystem instead of inside a Docker volume, there are several ways you can access the files locally:
- Mount the remote filesystem using SSHFS.
- Sync files from the remote host to your local machine using
rsync
. - Use the mount command if you are using Docker Machine.
Using SSHFS or Docker Machine's mount command are the more convenient options and do not require any file sync'ing. However, performance will be significantly slower than working through VS Code, so they are best used for single file edits and uploading/downloading content. If you need to use an application that bulk reads/write to many files at once (like a local source control tool), rsync is a better choice.