Developing inside a Container

The Visual Studio Code Remote - Containers extension lets you use a Docker container as a full-featured development environment. It allows you to open any folder inside (or mounted into) a container and take advantage of Visual Studio Code's full feature set. A devcontainer.json file in your project tells VS Code how to access (or create) a development container with a well-defined tool and runtime stack. This container can be used to run an application or to sandbox tools, libraries, or runtimes needed for working with a codebase.

Workspace files are mounted from the local file system or copied or cloned into the container. Extensions are installed and run inside the container, where they have full access to the tools, platform, and file system. This means that you can seamlessly switch your entire development environment just by connecting to a different container.

Container Architecture

This lets VS Code provide a local-quality development experience — including full IntelliSense (completions), code navigation, and debugging — regardless of where your tools (or code) are located.

Getting started

System requirements

Local:

Containers:

Other glibc based Linux containers may work if they have needed prerequisites.

While ARMv7l (AArch32), ARMv8l (AArch64), and musl based Alpine Linux support is available, some extensions installed on these devices may not work due to the use of glibc or x86 compiled native code in the extension. See the Remote Development with Linux article for details.

While the Docker CLI is required, the Docker daemon/service does not need to be running locally if you are using a remote Docker host.

Installation

To get started, follow these steps:

  1. Install and configure Docker for your operating system.

    Windows / macOS:

    1. Install Docker Desktop for Windows/Mac.

    2. Right-click on the Docker taskbar item and update Settings / Preferences > Shared Drives / File Sharing with any source code locations you want to open in a container. If you run into trouble, see Docker Desktop for Windows tips on avoiding common problems with sharing.

    Linux:

    1. Follow the official install instructions for Docker CE/EE for your distribution. If you are using Docker Compose, follow the Docker Compose directions as well.

    2. Add your user to the docker group by using a terminal to run: sudo usermod -aG docker $USER

    3. Sign out and back in again so your changes take effect.

  2. Install Visual Studio Code or Visual Studio Code Insiders.

  3. Install the Remote Development extension pack.

Working with Git? Here are two tips to consider:

Next Steps: The Remote - Containers extension supports two primary operating models:

We will cover using a container as your full-time development environment first.

Quick start: Try a dev container

Let's start by using a sample project to try things out.

  1. Start VS Code, and in a new window, click on the quick actions Status Bar item in the lower left corner.

    Quick actions Status bar item

  2. Select Remote-Containers: Try a Sample... from the command list that appears and select sample from the list.

    Select a sample from the list

  3. The window will then reload, but since the container does not exist yet, VS Code will create one and clone the sample repository into an isolated container volume. This may take some time, and a progress notification will provide status updates. Fortunately, this step isn't necessary the next time you open the folder since the container will already exist.

    Dev Container Progress Notification

  4. After the container is built, VS Code automatically connects to it and maps the project folder from your local file system into the container. Check out the Things to try section of README.md in the repository you cloned to see what to do next.

You may be wondering where the repository source code is located. In this case, the source code is stored in a container volume which is not directly accessible from your local operating system. However, you can work with content in your local filesystem from a container as well! We'll cover that next.

Quick start: Open an existing folder in a container

Next we will cover how to set up a dev container for an existing project to use as your full-time development environment using existing source code on your filesystem. Follow these steps:

  1. Start VS Code, run the Remote-Containers: Open Folder in Container... command from the Command Palette (kbstyle(F1)) or quick actions Status bar item, and select the project folder you would like to set up the container for.

    Tip: If you want to edit the container's contents or settings before opening the folder, you can run Remote-Containers: Add Development Container Configuration Files... instead.

    Quick actions Status bar item

  2. Now pick a starting point for your dev container. You can either select a base dev container definition from a filterable list, or use an existing Dockerfile or Docker Compose file if one exists in the folder you selected.

    Note: When using Alpine Linux containers, some extensions may not work due to glibc dependencies in native code inside the extension.

    Select a node dev container definition

    Note the dev container definitions displayed come from the vscode-dev-containers repository. You can browse the containers folder of that repository to see the contents of each definition.

  3. After picking the starting point for your container, VS Code will add the dev container configuration files to your project (.devcontainer/devcontainer.json).

  4. The VS Code window will reload and start building the dev container. A progress notification provides status updates. You only have to build a dev container the first time you open it; opening the folder after the first successful build will be much quicker.

    Dev Container Progress Notification

  5. After the build completes, VS Code will automatically connect to the container.

You can now interact with your project in VS Code just as you could when opening the project locally. From now on, when you open the project folder, VS Code will automatically pick up and reuse your dev container configuration.

Tip: Want to use a remote Docker host? See the Advanced Containers article for details on setup.

While using this approach to bind mount the local filesystem into a container is convenient, it does have some performance overhead on Windows and macOS. There are some techniques that you can apply to improve disk performance, or you can open a repository in a container using a isolated container volume instead.

Open an existing workspace in a container

You can also follow a similar process to open a VS Code multi-root workspace in a single container if the workspace only references relative paths to sub-folders of the folder the .code-workspace file is in (or the folder itself).

You can either:

Once connected, you may want to add the .devcontainer folder to the workspace so you can easily edit its contents if it is not already visible.

Also note that, while you cannot use multiple containers for the same workspace in the same VS Code window, you can use multiple Docker Compose managed containers at once from separate windows.

Quick start: Open a Git repository or GitHub PR in an isolated container volume

While you can open a locally cloned repository in a container, you may want to work with an isolated copy of a repository for a PR review or to investigate another branch without impacting your work.

Repository Containers use isolated, local Docker volumes instead binding to the local filesystem. In addition to not polluting your file tree, local volumes have the added benefit of improved performance on Windows and macOS. (See Advanced Configuration for information on how to use these types of volumes in other scenarios.)

For example, follow these steps to open one of the "try" repositories in a Repository Container:

  1. Start VS Code and run Remote-Containers: Open Repository in Container... from the Command Palette (kbstyle(F1)).

  2. Enter microsoft/vscode-remote-try-node (or one of the other "try" repositories), a Git URI, a GitHub branch URL, or a GitHub PR URL in the input box that appears and press kbstyle(Enter).

    Input box with a repository name in it

    Tip: If you choose a private repository, you may want to setup a credential manager or add your SSH keys to your SSH agent. See Sharing Git credentials with your container.

  3. If your repository does not have a .devcontainer/devcontainer.json file in it, you'll be asked to pick a starting point from a filterable list or an existing Dockerfile or Docker Compose file (if one exists).

    Note: When using Alpine Linux containers, some extensions may not work due to glibc dependencies in native code inside the extension.

    Select a node dev container definition

    Note the dev container definitions displayed come from the vscode-dev-containers repository. You can browse the containers folder of that repository to see the contents of each definition.

  4. The VS Code window (instance) will reload, clone the source code, and start building the dev container. A progress notification provides status updates.

    Dev Container Progress Notification

    If you pasted in a Github pull request URL in step 2, the PR will be automatically checked out and the GitHub Pull Requests extension will be installed in the container. The extension provides additional PR related features like a PR explorer, interacting with PR comments inline, and status bar visibility.

    PR status in status bar

  5. After the build completes, VS Code will automatically connect to the container.You can now work with the repository source code in this isolated environment as you would if you had cloned the code locally.

Tip: Want to use a remote Docker host? See the Advanced Containers article for details on setup.

Quick start: Configure a sandbox for multiple projects or folders

While development containers often are tied to a single folder, repository, or project, they can also be used with multiple folders as a way to simplify setup or sandbox your tools. Imagine you had your source code across multiple repositories in a single folder for a given toolset.

For example:

📁 Repos
   📁 node
   📁 python
      📁 starter-snake-python
      📁 vscode-remote-try-python
      📁 your-python-project-here
   📁 go
   📁 dotnet

Let's set up a container for use with all of the Python projects in the ./Repos/python folder.

  1. Start VS Code, select Remote-Containers: Open Folder in Container... from the Command Palette (kbstyle(F1)) or quick actions Status bar item, and select the ./Repos/python folder.

    Tip: If you want to edit the container's contents or settings before opening the folder, you can run Remote-Containers: Add Development Container Configuration Files... instead.

    Quick actions Status bar item

  2. Now pick a starting point for your dev container. You can either select a base dev container definition from a filterable list, or use an existing Dockerfile or Docker Compose file if one exists in the folder you selected.

    Note: When using Alpine Linux containers, some extensions may not work due to glibc dependencies in native code inside the extension.

    Select a python dev container definition

    Note the dev container definitions displayed come from the vscode-dev-containers repository. You can browse the containers folder of that repository to see the contents of each definition.

  3. After picking the starting point for your container, VS Code will add the dev container configuration files to the ./Repos/python/.devcontainer folder.

  4. The VS Code window will reload and start building the dev container. A progress notification provides status updates. You only have to build a dev container the first time you open it; opening the folder after the first successful build will be much quicker.

    Dev Container Progress Notification

  5. After the build completes, VS Code will automatically connect to the container. Once connected use File > Open... / Open Folder... to select one of the folders under ./Repos/python.

    Open python folder in the container

  6. In a moment, VS Code will open the folder inside the same container. In the future, you can use the Remote Explorer in the Activity Bar to open this sub-folder in the container directly.

    Container explorer with multiple folders under python container

Tip: Instead of mounting the local filesystem, you can use a similar flow to set up a container with an isolated, more performant volume that you clone your source code into. See the Advanced Containers article for details.

Creating a devcontainer.json file

VS Code's container configuration is stored in a devcontainer.json file. This file is similar to the launch.json file for debugging configurations, but is used for launching (or attaching to) your development container instead. You can also specify any extensions to install once the container is running or post-create commands to prepare the environment. The dev container configuration is either located under .devcontainer/devcontainer.json or stored as a .devcontainer.json file (note the dot-prefix) in the root of your project.

You can use any image, Dockerfile, or set of Docker Compose files as a starting point. Here is a simple example that uses one of the pre-built VS Code Development Container images:

{
    "image": "mcr.microsoft.com/vscode/devcontainers/typescript-node:0-12",
    "forwardPorts": [ 3000 ],
    "extensions": [
        "dbaeumer.vscode-eslint"
    ]
}

Selecting the Remote-Containers: Add Development Container Configuration Files... command from the Command Palette (kbstyle(F1)) will add the needed files to your project as a starting point, which you can further customize for your needs.

The command lets you pick a pre-defined container configuration:

Add a dev container definition

Or reuse an existing Dockerfile:

Add a dev container definition

Or reuse an existing Docker Compose file:

Add a dev container definition

For example, through a devcontainer.json file, you can:

All of the predefined container configurations you can pick from come from the vscode-dev-containers repository, which has examples of devcontainer.json for different scenarios. You can alter your configuration to:

If devcontainer.json's supported workflows do not meet your needs, you can also attach to an already running container instead.

Tip: Want to use a remote Docker host? See the Advanced Containers article for details on setup.

Configuration edit loop

Editing your container configuration is easy. Since rebuilding a container will "reset" the container to its starting contents (with the exception of your local source code), VS Code does not automatically rebuild if you edit a container configuration file (devcontainer.json, Dockerfile, docker-compose.yml). Instead, there are several commands that can be used to make editing your configuration easier.

Here is the typical edit loop using these commands:

Container edit loop illustration

  1. Start with Remote-Containers: Add Development Container Configuration Files... in the Command Palette (kbstyle(F1)).
  2. Edit the contents of the .devcontainer folder as required.
  3. Try it with Remote-Containers: Reopen Folder in Container.
  4. If you see an error, click on Open Folder Locally in the dialog that appears.
  5. After the window reloads, a copy of the build log will appear in the so you can investigate the problem. Edit the contents of the .devcontainer folder as required. (You can also use the Remote-Containers: Open Log File... command to see the log again if you close it.)
  6. Run Remote-Containers: Rebuild and Reopen Folder in Container and jump to step 4 if needed.

If you already have a successful build, you can still edit the contents of the .devcontainer folder as required when connected to the container and then select Remote-Containers: Rebuild Container in the Command Palette (kbstyle(F1)) so the changes take effect.

Adding configuration files to public or private repositories

You can easily share a customized dev container definition for your project by adding devcontainer.json files to source control. By including these files in your repository, anyone that opens a local copy of your repo in VS Code will be automatically prompted to reopen the folder in a container, provided they have the Remote - Containers extension installed.

Dev config file reopen notification

Beyond the advantages of having your team use a consistent environment and tool-chain, this also makes it easier for new contributors or team members to be productive quickly. First-time contributors will require less guidance and hit fewer issues related to environment setup.

Attaching to running containers

While using VS Code to spin up a new container can be useful in many situations, it may not match your workflow and you may prefer to "attach" VS Code to an already running Docker container - regardless of how it was started. Once attached, you can install extensions, edit, and debug like you can when you open a folder in a container using devcontainer.json.

Note: When using Alpine Linux containers, some extensions may not work due to glibc dependencies in native code inside the extension.

Attaching to a Docker container

To attach to a Docker container, either select the Remote-Containers: Attach to Running Container... command from the Command Palette (kbstyle(F1)) or use the Remote Explorer in the Activity Bar and select the Connect to Container inline action on the container you want to connect to.

Containers Explorer screenshot

Attached container configuration files

VS Code supports image-level configuration files to speed up setup when you repeatedly connect to a given Docker container. Once attached, anytime you open a folder, install an extension, or forward a port, a local image-specific configuration file will automatically be updated to remember your settings so that when you attach again, everything is back to the right place.

To see or edit the configuration, select Remote-Containers: Open Attached Container Configuration File... command from the Command Palette (kbstyle(F1)). The opened file supports a subset of devcontainer.json properties:

{
    // Default path to open when attaching to a new container.
    "workspaceFolder": "/path/to/code/in/container/here",

    // An array of extension IDs that specify the extensions to
    // install inside the container when you first attach to it.
    "extensions": [
        "dbaeumer.vscode-eslint"
    ],

    // Any *default* container specific VS Code settings
    "settings": {
        "terminal.integrated.shell.linux": "/bin/bash"
    },

    // An array port numbers to forward
    "forwardPorts": [8000],

    // Container user VS Code should use when connecting
    "remoteUser": "vscode",

    // Set environment variables for VS Code and sub-processes
    "remoteEnv": { "MY_VARIABLE": "some-value" }
}

See the attached container config reference for a complete list of properties and their uses.

Once saved, whenever you open a container for the first time with the same image name, these properties will be used to configure the environment.

Finally, if you have extensions you want installed regardless of the container you attach to, you can update settings.json to specify a list of extensions that should always be installed. We will cover this option in the next section.

Attaching to a container in a Kubernetes cluster

To attach to a container in a Kuberntes cluster, first install the Kubernetes extension and kubectl along with the Remote - Containers extension. Then select the Kubernetes explorer from the activity bar and expand the cluster and Pod where the container you want to attach to resides. Finally, right-click on the container and select Attach Visual Studio Code from context menu.

Note: Attached container configuration files are not yet supported for containers in a Kubernetes cluster.

Attach to Kubernetes Container

Managing extensions

VS Code runs extensions in one of two places: locally on the UI / client side, or in the container. While extensions that affect the VS Code UI, like themes and snippets, are installed locally, most extensions will reside inside a particular container. This allows you to install only the extensions you need for a given task in a container and seamlessly switch your entire tool-chain just by connecting to a new container.

If you install an extension from the Extensions view, it will automatically be installed in the correct location. You can tell where an extension is installed based on the category grouping. There will be a Local - Installed category and also one for your container.

Workspace Extension Category

Local Extension Category

Note: If you are an extension author and your extension is not working properly or installs in the wrong place, see Supporting Remote Development for details.

Local extensions that actually need to run remotely will appear Disabled in the Local - Installed category. Select Install to install an extension on your remote host.

Disabled Extensions w/Install Button

You can also install all locally installed extensions inside the Dev Container by going to the Extensions view and selecting Install Local Extensions in Dev Container: [Name] from the More Actions menu (...).

Install all extensions

However, some extensions may require you to install additional software in the container. Consult extension documentation for details if you encounter issues.

Adding an extension to devcontainer.json

While you can edit your devcontainer.json file by hand to add a list of extension IDs, you can also right-click on any extension in the Extensions view and select Add to devcontainer.json.

Add to devcontainer.json menu

"Always installed" extensions

If there are extensions that you would like always installed in any container, you can update the remote.containers.defaultExtensions User setting. For example, if you wanted to install the GitLens and Resource Monitor extensions, you would specify their extension IDs as follows:

"remote.containers.defaultExtensions": [
    "eamodio.gitlens",
    "mutantdino.resourcemonitor"
]

Advanced: Forcing an extension to run locally or remotely

Extensions are typically designed and tested to either run locally or remotely, not both. However, if an extension supports it, you can force it to run in a particular location in your settings.json file.

For example, the setting below will force the Docker extension to run locally and Debugger for Chrome extension to run remotely instead of their defaults:

"remote.extensionKind": {
    "ms-azuretools.vscode-docker": [ "ui" ],
    "msjsdiag.debugger-for-chrome": [ "workspace" ]
}

A value of "ui" instead of "workspace" will force the extension to run on the local UI/client side instead. Typically, this should only be used for testing unless otherwise noted in the extension's documentation since it can break extensions. See the article on Supporting Remote Development for details.

Forwarding or publishing a port

Containers are isolated environments, so if you want to access a server, service, or other resource inside your container, you will need to either "forward" or "publish" the port to your host. You can either configure your container to always expose these ports or just forward them temporarily.

Always forwarding a port

You can specify a list of ports you always want to forward when attaching or opening a folder in container by using the forwardPorts property in devcontainer.json.

"forwardPorts": [3000, 3001]

Simply reload / reopen the window and the setting will be applied when VS Code connects to the container.

Temporarily forwarding a port

If you need to access a port that you didn't add to devcontainer.json or publish in your Docker Compose file, you can temporarily forward a new port for the duration of the session by running the Forward a Port command from the Command Palette (kbstyle(F1)).

Forward port input

After selecting a port, a notification will tell you the localhost port you should use to access the port in the container. For example, if you forwarded an HTTP server listening on port 3000, the notification may tell you that it was mapped to port 4123 on localhost. You can then connect to this remote HTTP server using http://localhost:4123.

This same information is available in the Forwarded Ports section of the Remote Explorer if you need to access it later.

If you would like VS Code to remember any ports you have forwarded, check Remote: Restore Forwarded Ports in the Settings editor (kb(workbench.action.openSettings)) or set "remote.restoreForwardedPorts": true in settings.json.

Restore forwarded ports setting

Publishing a port

Docker has the concept of "publishing" ports when the container is created. Published ports behave very much like ports you make available to your local network. If your application only accepts calls from localhost, it will reject connections from published ports just as your local machine would for network calls. Forwarded ports, on the other hand, actually look like localhost to the application. Each can be useful in different situations.

To publish a port, you can:

  1. Use the appPort property: If you reference an image or Dockerfile in devcontainer.json, you can use the appPort property to publish ports to the host.

    json "appPort": [ 3000, "8921:5000" ]

  2. Use the Docker Compose ports mapping: The ports mapping can easily be added your docker-compose.yml file to publish additional ports.

    yaml ports: - "3000" - "8921:5000"

In each case, you'll need to rebuild your container for the setting to take effect. You can do this by running the Remote-Containers: Rebuild Container command in the Command Palette (kbstyle(F1)) when you are connected to the container.

Opening a terminal

Opening a terminal in a container from VS Code is simple. Once you've opened a folder in a container, any terminal window you open in VS Code (Terminal > New Terminal) will automatically run in the container rather than locally.

You can also use the code command line from this same terminal window to perform a number of operations such as opening a new file or folder in the container. Type code --help to learn what options are available from the command line.

Using the code CLI

Debugging in a container

Once you've opened a folder in a container, you can use VS Code's debugger in the same way you would when running the application locally. For example, if you select a launch configuration in launch.json and start debugging (kb(workbench.action.debug.start)), the application will start on the remote host and attach the debugger to it.

See the debugging documentation for details on configuring VS Code's debugging features in .vscode/launch.json.

Container specific settings

VS Code's local user settings are also reused when you are connected to a dev container. While this keeps your user experience consistent, you may want to vary some of these settings between your local machine and each container. Fortunately, once you have connected to a container, you can also set container-specific settings by running the Preferences: Open Remote Settings command from the Command Palette (kbstyle(F1)) or by selecting the Remote tab in the Settings editor. These will override any local settings you have in place whenever you connect to the container.

Container specific settings tab

Default container specific settings

You can include defaults for container specific settings in devcontainer.json using the settings property. These values will be automatically placed in the container specific settings file inside the container once it is created.

For example, adding this to .devcontainer/devcontainer.json will set the Java home path:

"settings": {
    "java.home": "/docker-java-home"
}

Since this just establishes the default, you are still able to change the settings as needed once the container is created.

Sharing Git credentials with your container

The Remote - Containers extension provides out of box support for using local Git credentials from inside a container. In this section, we'll walk through the two supported options.

If you do not have your user name or email address set up locally, you may be prompted to do so. You can do this on your local machine by running the following commands:

git config --global user.name "Your Name"
git config --global user.email "your.email@address"

The extension will automatically copy your local .gitconfig file into the container on startup so you should not need to do this in the container itself.

Using a credential helper

If you use HTTPS to clone your repositories and have a credential helper configured in your local OS, no further setup is required. Credentials you've entered locally will be reused in the container and vice versa.

Using SSH keys

There are some cases when you may be cloning your repository using SSH keys instead of a credential helper. To enable this scenario, the extension will automatically forward your local SSH agent if one is running.

You can add your local SSH keys to the agent if it is running by using the ssh-add command. For example, run this from a terminal or PowerShell:

ssh-add $HOME/.ssh/github_rsa

On Windows and Linux, you may get an error because the agent is not running (macOS typically has it running by default). Follow these steps to resolve the problem:

Windows:

Start a local Administrator PowerShell and run the following commands:

# Make sure you're running as an Administrator
Set-Service ssh-agent -StartupType Automatic
Start-Service ssh-agent
Get-Service ssh-agent

Linux:

First, start the SSH Agent in the background by running the following in a terminal:

eval "$(ssh-agent -s)"

Then add these lines to your ~/.bash_profile so it starts on login:

if [ -z "$SSH_AUTH_SOCK" ]
then
   # Check for a currently running instance of the agent
   RUNNING_AGENT="`ps -ax | grep 'ssh-agent -s' | grep -v grep | wc -l | tr -d '[:space:]'`"
   if [ "$RUNNING_AGENT" = "0" ]
   then
        # Launch a new instance of the agent
        ssh-agent -s &> .ssh/ssh-agent
   fi
   eval `cat .ssh/ssh-agent`
fi

Managing containers

By default, the Remote - Containers extension automatically starts the containers mentioned in the devcontainer.json when you open the folder. When you close VS Code, the extension automatically shuts down the containers you've connected to. You can change this behavior by adding "shutdownAction": "none" to devcontainer.json.

You can also manually manage your containers using one of the following options:

Option 1: Use the Containers Remote Explorer

From the Containers Explorer, you can right-click on a running container and stop it. You can also start exited containers, remove containers, and remove recent folders. From the Details view, you can forward ports and open already forwarded ports in the browser.

Containers Explorer screenshot

Option 2: Use the Docker CLI

  1. Open a local terminal/PowerShell (or use a local window in VS Code).
  2. Type docker ps to see running containers. Use docker ps -a to also see any stopped containers.
  3. Type docker stop <Container ID> from this list to stop a container.
  4. If you would like to delete a container, type docker rm <Container ID> to remove it.

Option 3: Use Docker Compose

  1. Open a local terminal/PowerShell (or use a local window in VS Code).
  2. Go to the directory with your docker-compose.yml file.
  3. Type docker-compose top to see running processes.
  4. Type docker-compose stop to stop the containers. If you have more than one Docker Compose file, you can specify additional Docker Compose files with the -f argument.
  5. If you would like to delete the containers, type docker-compose down to both stop and delete them.

If you want to clean out images or mass-delete containers, see Cleaning out unused containers and images for different options.

Personalizing with dotfile repositories

Dotfiles are files whose filename begins with a dot (.) and typically contain configuration information for various applications. Since development containers can cover a wide range of application types, it can be useful to store these files somewhere so that you can easily copy them into a container once it is up and running.

A common way to do this is to store these dotfiles in a GitHub repository and then use a utility to clone and apply them. The Remote - Containers extension has built-in support for using these with your own containers. If you are new to the idea, take a look at the different dotfiles bootstrap repositories that exist.

To use it, add your dotfiles GitHub repository to VS Code's User Settings (kb(workbench.action.openSettings)) as follows:

Settings for dotfiles

Or in settings.json:

{
    "dotfiles.repository": "your-github-id/your-dotfiles-repo",
    "dotfiles.targetPath": "~/dotfiles",
    "dotfiles.installCommand": "~/dotfiles/install.sh"
}

From this point forward, the dotfiles repository will be used whenever a container is created.

In-depth: Setting up a folder to run in a container

There are a few different ways VS Code Remote - Containers can be used to develop an application inside a fully containerized environment. In general, there are two primary scenarios that drive interest in this development style:

This section will walk you through configuring your project for each of these situations. The vscode-dev-containers GitHub repository also contains dev container definitions to get you up and running quickly.

Using an image or Dockerfile

You can configure VS Code to reuse an existing image from a source like DockerHub or Azure Container Registry for your dev container by adding a .devcontainer/devcontainer.json (or .devcontainer.json) config file to your project. In addition, if you are not able to find an image that meets your needs, have a single container-based project, or just want to automate the installation of several additional dependencies, you can use a Dockerfile to generate the image instead.

To get started quickly, open the folder you want to work with in VS Code and run the Remote-Containers: Add Development Container Configuration Files... command in the Command Palette (kbstyle(F1)).

Select Dockerfile

You'll be asked to either select an existing Dockerfile (if one exists), or pick a pre-defined container configuration from the vscode-dev-containers repository in a filterable list. VS Code will then add devcontainer.json and any other required files to the folder. While most of these pre-defined "dev container definitions" include a Dockerfile, you can use them as a starting point for an image instead if you prefer.

Note: When using Alpine Linux containers, some extensions may not work due to glibc dependencies in native code inside the extension.

You can also create your configuration manually. The difference between configuring VS Code to build a container image using a Dockerfile or just reuse an exiting image is a single property in devcontainer.json:

See the devcontainer.json reference for information on other available properties such as forwardPorts, postCreateCommand, and the extensions list.

Once you have added a .devcontainer/devcontainer.json file to your folder, run the Remote-Containers: Reopen Folder in Container command (or Remote-Containers: Open Folder in Container... if you are not yet in VS Code) from the Command Palette (kbstyle(F1)). After the container is created, the local filesystem is automatically "bind" mount into the container, unless you change this behavior, and you can start working with it from VS Code.

However, on Linux, you may need to set up and specify a non-root user when using a bind mount or any files you create will be root. All of the configuration files and images the extension ships with include a non-root user you can specify. See Adding a non-root user to your dev container for details.

# Change user for VS Code and sub-processes (terminals, tasks, debugging)
"remoteUser": "your-user-name-here",
# Or change the user for all container processes
"containerUser": "your-user-name-here"

You can also add additional local mount points to give your container access to other locations using the mounts property.

For example, you can mount your home / user profile folder:

"mounts": [
    "source=${localEnv:HOME}${localEnv:USERPROFILE},target=/host-home-folder,type=bind,consistency=cached"
]

You can also reference "${localWorkspaceFolder} if you need to mount something from the local filesystem into the container.

The runArgs property supports the same list of arguments as the docker run command and can be useful for a wide variety of scenarios including setting environment variables.

If your application was built using C++, Go, or Rust, or another language that uses a ptrace-based debugger, the runArgs property can also be used to configure needed runtime security and capability settings.

For example:

{
    "name": "My Go App",
    "dockerFile": "Dockerfile",
    "extensions": [
        "ms-vscode.go"
    ],
    "runArgs": [
        "--cap-add=SYS_PTRACE",
        "--security-opt",
        "seccomp=unconfined"
    ]
}

While less efficient than a custom Dockerfile, you can also use the postCreateCommand property to install additional software that may not be in your base image or for cases where you would prefer not to modify a deployment Dockerfile you are reusing.

For example, here is a devcontainer.json that adds git and the Git Lens extension to the base Debian 9 container image:

{
    "image": "debian:9",
    "extensions": [
        "eamodio.gitlens"
    ],
    "postCreateCommand": "apt-get update && apt-get install -y git"
}

See installing additional software for more information on using apt-get to install software.

This command is run once your source code is mounted, so you can also use the property to run commands like npm install or to execute a shell script in your source tree.

"postCreateCommand": "bash scripts/install-dev-tools.sh"

By default, when VS Code starts a container, it will override the container's default command to be /bin/sh -c "while sleep 1000; do :; done". This is done because the container will stop if the default command fails or exits. However, this may not work for certain images. If the image you are using requires the default command be run to work properly, add the following to your devcontainer.json file.

"overrideCommand": false

After you create your container for the first time, you will need to run the Remote-Containers: Rebuild Container command for updates to devcontainer.json or your Dockerfile to take effect.

Installing additional software

Once VS Code is connected to the container, you can open a VS Code terminal and execute any command against the OS inside the container. This allows you to install new command-line utilities and spin up databases or application services from inside the Linux container.

Most container images are based on Debian or Ubuntu, where the apt or apt-get command is used to install new packages. You can learn more about the command in Ubuntu's documentation. Alpine images include a similar apk command while CentOS / RHEL / Oracle SE / Fedora images use yum or more recently dnf.

Documentation for the software you want to install will usually provide specific instructions, but you may not need to prefix commands with sudo if you are running as root in the container.

For example:

# If running as root
apt-get update
apt-get install <package>

If you are running as root, you can install software as long as sudo is configured in your container. All predefined containers have sudo set up, but the Advanced Container Configuration article can help you set this up for your own containers. Regardless, if you install and configure sudo you'll be able to use it when running as any user including root.

# If sudo is installed and configured
sudo apt-get update
sudo apt-get install <package>

However, if you rebuild the container, you will have to reinstall anything you've installed manually. To avoid this problem, you can either use a series of commands in the postCreateCommand property in devcontainer.json or the RUN instruction in a custom Dockerfile. You can use && to string together multiple commands.

Using a Dockerfile:

RUN apt-get update && apt-get install <packaging>

Using devcontainer.json:

"postCreateCommand": "apt-get update && apt-get install <package>"

Or if running as a non-root user:

"postCreateCommand": "sudo apt-get update && sudo apt-get install <package>"

The postCreateCommand is run once the container is running, so you can also use the property to run commands like npm install or to execute a shell script in your source tree (if you have mounted it).

"postCreateCommand": "bash scripts/install-dev-tools.sh"

Using Docker Compose

In some cases, a single container environment isn't sufficient. Fortunately, Remote - Containers supports Docker Compose managed multi-container configurations.

You can either:

  1. Work with a service defined in an existing, unmodified docker-compose.yml.
  2. Create a new docker-compose.yml (or make a copy of an existing one) that you use to develop a service.
  3. Extend your existing Docker Compose configuration to develop the service.
  4. Use separate VS Code windows to work with multiple Docker Compose-defined services at once.

Note: When using Alpine Linux containers, some extensions may not work due to glibc dependencies in native code inside the extension.

VS Code can be configured to automatically start any needed containers for a particular service in a Docker Compose file. If you've already started the configured containers using the command line, VS Code will attach to the running service you've specified instead. This gives your multi-container workflow the same quick setup advantages described for the Docker image and Dockerfile flows above while still allowing you to use the command line if you prefer.

To get started quickly, open the folder you want to work with in VS Code and run the Remote-Containers: Add Development Container Configuration Files... command in the Command Palette (kbstyle(F1)).

Select Docker Compose File

You'll be asked to either select an existing Docker Compose file (if one exists), or pick a pre-defined container configuration from the vscode-dev-containers repository in a filterable list. Many of these "dev container definitions" use a Dockerfile, so select one of these definitions for a starting point for Docker Compose: Existing Docker Compose, Node.js & MongoDB, Python & PostgreSQL, or Docker-in-Docker Compose. After you make your selection, VS Code will add the appropriate .devcontainer/devcontainer.json (or .devcontainer.json) file to the folder.

You can also create your configuration manually. To reuse a Docker Compose file unmodified, you can use the dockerComposeFile and service properties in .devcontainer/devcontainer.json.

For example:

{
    "name": "[Optional] Your project name here",
    "dockerComposeFile": "../docker-compose.yml",
    "service": "the-name-of-the-service-you-want-to-work-with-in-vscode",
    "workspaceFolder": "/default/workspace/path/in/container/to/open",
    "shutdownAction": "stopCompose"
}

See the devcontainer.json reference for information other available properties such as the workspaceFolder and shutdownAction.

Once you have added a .devcontainer/devcontainer.json file to your folder, run the Remote-Containers: Reopen Folder in Container command (or Remote-Containers: Open Folder in Container... if you are not yet in VS Code) from the Command Palette (kbstyle(F1)).

If the containers are not already running, VS Code will call docker-compose -f ../docker-compose.yml up in this example. The service property indicates which service in your Docker Compose file VS Code should connect to, not which service should be started. If you started them by hand, VS Code will attach to the service you specified.

You can also create a development copy of your Docker Compose file. For example, if you had .devcontainer/docker-compose.devcontainer.yml, you would just change the following line in devcontainer.json:

"dockerComposeFile": "docker-compose.devcontainer.yml"

However, a better approach is often to avoid making a copy of your Docker Compose file by extending it with another one. We'll cover extending a Docker Compose file in the next section.

To avoid having the container shut down if the default container command fails or exits, you can modify your Docker Compose file for the service you have specified in devcontainer.json as follows:

# Overrides default command so things don't shut down after the process ends.
command: /bin/sh -c "while sleep 1000; do :; done"

If you have not done so already, you can "bind" mount your local source code into the container using the volumes list in your Docker Compose file.

For example:

volumes:
  # Mounts the project folder to '/workspace'. The target path inside the container
  # should match what your application expects. In this case, the compose file is
  # in a sub-folder, so we will mount '..'. You would then reference this path as the
  # 'workspaceFolder' in '.devcontainer/devcontainer.json' so VS Code starts here.
  - ..:/workspace:cached

However, on Linux you may need to set up and specify a non-root user when using a bind mount or any files you create will be root. See Adding a non-root user to your dev container for details. To have VS Code run as a different user, add this to devcontainer.json:

"remoteUser": "your-user-name-here"

If you want all processes to run as a different user, add this to the appropriate service in your Docker Compose file:

user: your-user-name-here

If you aren't creating a custom Dockerfile for development, you may want to install additional developer tools such as Git inside the service's container. While less efficient than adding these tools to the container image, you can also use the postCreateCommand property for this purpose.

"postCreateCommand": "apt-get update && apt-get install -y git"

Or if running as a non-root user and sudo is installed in the container:

"postCreateCommand": "sudo apt-get update && sudo apt-get install -y git"

See installing additional software for more information on using apt-get to install software.

If your application was built using C++, Go, or Rust, or another language that uses a ptrace-based debugger, you will also need to add the following settings to your Docker Compose file:

# Required for ptrace-based debuggers like C++, Go, and Rust
cap_add:
- SYS_PTRACE
security_opt:
- seccomp:unconfined

After you create your container for the first time, you will need to run the Remote-Containers: Rebuild Container command for updates to devcontainer.json, your Docker Compose files, or related Dockerfiles to take effect.

Extending your Docker Compose file for development

Referencing an existing deployment / non-development focused docker-compose.yml has some potential downsides.

For example:

You can solve these and other issues like them by extending your entire Docker Compose configuration with multiple docker-compose.yml files that override or supplement your primary one.

For example, consider this additional .devcontainer/docker-compose.extend.yml file:

version: '3'
services:
  your-service-name-here:
    volumes:
      # Mounts the project folder to '/workspace'. While this file is in .devcontainer,
      # mounts are relative to the first file in the list, which is a level up.
      - .:/workspace:cached

    # [Optional] Required for ptrace-based debuggers like C++, Go, and Rust
    cap_add:
      - SYS_PTRACE
    security_opt:
      - seccomp:unconfined

    # Overrides default command so things don't shut down after the process ends.
    command: /bin/sh -c "while sleep 1000; do :; done"

This same file can provide additional settings, such as port mappings, as needed. To use it, reference your original docker-compose.yml file in addition to .devcontainer/devcontainer.extend.yml in a specific order:

{
    "name": "[Optional] Your project name here",

    // The order of the files is important since later files override previous ones
    "dockerComposeFile": [
        "../docker-compose.yml",
        "docker-compose.extend.yml"
    ],

    "service": "your-service-name-here",
    "workspaceFolder": "/workspace",
    "shutdownAction": "stopCompose"

}

VS Code will then automatically use both files when starting up any containers. You can also start them yourself from the command line as follows:

docker-compose -f docker-compose.yml -f .devcontainer/docker-compose.extend.yml up

While the postCreateCommand property allows you to install additional tools inside your container, in some cases you may want to have a specific Dockerfile for development. You can also use this same approach to reference a custom Dockerfile specifically for development without modifying your existing Docker Compose file. For example, you can update .devcontainer/devcontainer.extend.yml as follows:

version: '3'
services:
  your-service-name-here:
      # Note that the path of the Dockerfile and context is relative to the *primary*
      # docker-compose.yml file (the first in the devcontainer.json "dockerComposeFile"
      # array). The sample below assumes your primary file is in the root of your project.
      build:
        context: .
        dockerfile: .devcontainer/Dockerfile
      volumes:
        - .:/workspace:cached
      command: /bin/sh -c "while sleep 1000; do :; done"

Docker Compose dev container definitions

The following are dev container definitions that use Docker Compose:

Advanced container configuration

See the Advanced Container Configuration article for information on the following topics:

devcontainer.json reference

See Setting up a folder to run in a container for more information on configuring a dev container or the vscode-dev-containers repository for a wide variety of base configurations.

Property Type Description
Dockerfile or image
image string Required when using an image. The name of an image in a container registry (DockerHub, Azure Container Registry) that VS Code should use to create the dev container.
dockerFile string Required when using a Dockerfile. The location of a Dockerfile that defines the contents of the container. The path is relative to the devcontainer.json file. You can find a number of sample Dockerfiles for different runtimes in the vscode-dev-containers repository.
context string Path that the Docker build should be run from relative to devcontainer.json. For example, a value of ".." would allow you to reference content in sibling directories. Defaults to ".".
appPort integer,
string,
array
In most cases, we recommend using the new forwardPorts property. This property accepts a port or array of ports that should be published locally when the container is running. Unlike forwardPorts, your application may need to listen on all interfaces (0.0.0.0) not just localhost for it to be available externally. Defaults to [].
containerEnv object A set of name-value pairs that sets or overrides environment variables for the container. The value can reference local OS variable values using the following format: ${localEnv:VARIABLE_NAME}.
For example: "containerEnv": { "MY_VARIABLE": "${localEnv:MY_VARIABLE}" }
Requires the container be recreated / rebuilt to change.
remoteEnv object A set of name-value pairs that sets or overrides environment variables for VS Code (or sub-processes like terminals) but not the container as a whole. The value can reference local OS variable values using the following format: ${localEnv:VARIABLE_NAME}.
It can also reference or update an existing variable in the container using this format: ${containerEnv:VARIABLE_NAME}
Updates are applied when VS Code is restarted (or the window is reloaded).
For example: "remoteEnv": { "PATH": "${containerEnv:PATH}:/some/other/path", "MY_VARIABLE": "${localEnv:MY_VARIABLE}" }
containerUser string Overrides the user all operations run as inside the container. Defaults to either root or the last USER instruction in the related Dockerfile used to create the image.
On Linux, the specified container user's UID/GID will be updated to match the local user's UID/GID to avoid permission problems with bind mounts (unless disabled using updateRemoteUserID).
Requires the container be recreated / rebuilt for updates to take effect.
remoteUser string Overrides the user that VS Code runs as in the container (along with sub-processes like terminals, tasks, or debugging). Defaults to the containerUser.
On Linux, the specified container user's UID/GID will be updated to match the local user's UID/GID to avoid permission problems with bind mounts (unless disabled using updateRemoteUserID).
Updates are applied when VS Code is restarted (or the window is reloaded), but UID/GID updates are only applied when the container is created and requires a rebuild to change.
updateRemoteUserUID boolean On Linux, if containerUser or remoteUser is specified, the container user's UID/GID will be updated to match the local user's UID/GID to avoid permission problems with bind mounts. Defaults to true.
Requires the container be recreated / rebuilt for updates to take effect.
mounts array An array of additional mount points to add to the container. Each value is a string that accepts the same values as the Docker CLI --mount flag. You can use ${localWorkspaceFolder} in this property to refer to the local source code or using the following format to refer to environment variables: ${localEnv:VARIABLE_NAME}.
For example: "mounts": ["source=${localEnv:HOME}${localEnv:USERPROFILE},target=/host-home-folder,type=bind,consistency=cached"]
workspaceMount string Overrides the default local mount point for the workspace. Supports the same values as the Docker CLI --mount flag. Primarily useful for configuring remote containers or improving disk performance. You can use ${localWorkspaceFolder} in this property to refer to the local source code or using the following format to refer to environment variables: ${localEnv:VARNAMEHERE}
workspaceFolder string Sets the default path that VS Code should open when connecting to the container. Typically used in conjunction with workspaceMount. Defaults to the automatic source code mount location.
runArgs array An array of Docker CLI arguments that should be used when running the container. Defaults to [].
For example, "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ] allows ptrace based debuggers like C++ to work in the container.
If required, values can use ${localWorkspaceFolder} to refer to the local source code path or ${localEnv:VARABLE_NAME} to refer to local environment variables.
build.args Object An object containing Docker image build arguments that should be passed when building a Dockerfile. You can refer to local environment variables using the syntax ${localEnv:VARABLE_NAME}. Defaults to not set. For example: "build": { "args": { "MYARG": "MYVALUE", "MYARGFROMENVVAR": "${localEnv:VARABLE_NAME}" } }
build.target string An string that specifies a Docker image build target that should be passed when building a Dockerfile Defaults to not set. For example: "build": { "target": "development" }
overrideCommand boolean Tells VS Code whether it should run /bin/sh -c "while sleep 1000; do :; done" when starting the container instead of the container's default command. Defaults to true since the container can shut down if the default command fails. Set to false if the default command must run for the container to function properly.
shutdownAction enum Indicates whether VS Code should stop the container when the VS Code window is closed / shut down.
Values are none and stopContainer (default).
Docker Compose
dockerComposeFile string,
array
Required. Path or an ordered list of paths to Docker Compose files relative to the devcontainer.json file. Using an array is useful when extending your Docker Compose configuration. The order of the array matters since the contents of later files can override values set in previous ones.
The default .env file is picked up from the root of the project, but you can use env_file in your Docker Compose file to specify an alternate location.
service string Required. The name of the service VS Code should connect to once running.
runServices array An array of services in your Docker Compose configuration that should be started by VS Code. These will also be stopped when you disconnect unless "shutdownAction" is "none". Defaults to all services.
workspaceFolder string Sets the default path that VS Code should open when connecting to the container (which is often the path to a volume mount where the source code can be found in the container). Defaults to "/".
remoteEnv object A set of name-value pairs that sets or overrides environment variables for VS Code (or sub-processes like terminals) but not the container as a whole. The value can reference local OS variable values using the following format: ${localEnv:VARIABLE_NAME}.
It can also reference or update an existing variable in the container using this format: ${containerEnv:VARIABLE_NAME}.
Updates are applied when VS Code is restarted (or the window is reloaded).
For example: "remoteEnv": { "PATH": "${containerEnv:PATH}:/some/other/path", "MY_VARIABLE": "${localEnv:MY_VARIABLE}" }
remoteUser string Overrides the user that VS Code runs as in the container (along with sub-processes like terminals, tasks, or debugging). Does not change the user the container as a whole runs as (which can be set in your Docker Compose file). Defaults to the user the container as a whole is running as (often root).
Updates are applied when VS Code is restarted (or the window is reloaded).
shutdownAction enum Indicates whether VS Code should stop the containers when the VS Code window is closed / shut down.
Values are none and stopCompose (default).
General
name string A display name for the container.
extensions array An array of extension IDs that specify the extensions that should be installed inside the container when it is created. Defaults to [].
settings object Adds default settings.json values into a container/machine specific settings file.
forwardPorts array An array of ports that should be forwarded from inside the container to the local machine.
postCreateCommand string,
array
A command string or list of command arguments to run after the container is created. The commands execute from the workspaceFolder in the container. Use && in a string to execute multiple commands. For example, "yarn install" or "apt-get update && apt-get install -y git". The array syntax ["yarn", "install"] will invoke the command (in this case yarn) directly without using a shell.
It fires after your source code has been mounted, so you can also run shell scripts from your source tree. For example: bash scripts/install-dev-tools.sh. Not set by default.
initializeCommand string,
array
A command string or list of command arguments to run locally before The commands execute from the workspaceFolder locally. For example, "yarn install". The array syntax ["yarn", "install"] will invoke the command (in this case yarn) directly without using a shell.
devPort integer Allows you to force a specific port that the VS Code Server should use in the container. Defaults to a random, available port.

If you've already built the container and connected to it, be sure to run Remote-Containers: Rebuild Container from the Command Palette (kbstyle(F1)) to pick up the change.

Attached container config reference

Attached container configuration files are similar to devcontainer.json and supports a subset of its properties.

Property Type Description
workspaceFolder string Sets the default path that VS Code should open when connecting to the container (which is often the path to a volume mount where the source code can be found in the container). Not set by default (an empty window is opened).
extensions array An array of extension IDs that specify the extensions that should be installed inside the container when it is created. Defaults to [].
settings object Adds default settings.json values into a container/machine specific settings file.
forwardPorts array A list of ports that should be forwarded from inside the container to the local machine.
remoteEnv object A set of name-value pairs that sets or overrides environment variables for VS Code (or sub-processes like terminals) but not the container as a whole. The value can reference local OS variable values using the following format: ${localEnv:VARIABLE_NAME}.
It can also reference or update an existing variable in the container using this format: ${containerEnv:VARIABLE_NAME}.
Updates are applied when VS Code is restarted (or the window is reloaded / you re-attach).
For example: "remoteEnv": { "PATH": "${containerEnv:PATH}:/some/other/path", "MY_VARIABLE": "${localEnv:MY_VARIABLE}" }
remoteUser string Overrides the user that VS Code runs as in the container (along with sub-processes like terminals, tasks, or debugging). Defaults to the user the container as a whole is running as (often root).
Updates are applied when VS Code is restarted (or the window is reloaded / you re-attach).

Known limitations

Remote - Containers limitations

See here for a list of active issues related to Containers.

Docker limitations

See the Docker troubleshooting guide for Windows or Mac, consult Docker Support Resources for more information.

Docker Extension limitations

By default, the Docker extension will run remotely. While this is a sensible default for SSH and WSL 2, it means the extension will not show local containers when VS Code is connected to a container.

You can use one of the following solutions to resolve this problem:

Extension limitations

Many extensions will work inside dev containers without modification. However, in some cases, certain features may require changes. If you run into an extension issue, see here for a summary of common problems and solutions that you can mention to the extension author when reporting the issue.

In addition, while Alpine support is available, some extensions installed in the container may not work due to glibc dependencies in native code inside the extension. See the Remote Development with Linux article for details.

Common questions

I am seeing errors when trying to mount the local filesystem into a container

Right-click on the Docker task bar item. On Windows, go to the Settings > Shared Drives tab and check the drive(s) where your source code is located. On macOS, go the Preferences > File Sharing tab and make sure the folder containing your source code is under a file path specified in the list.

See Docker Desktop for Windows tips for information on workarounds to common Docker for Windows issues.

I am seeing "W: Failed to fetch ..." when building a Dockerfile

If you see "W: Failed to fetch http://deb.debian.org/debian/dists/jessie-updates/InRelease" when building a Dockerfile, you may be hitting a known Docker issue with Debian 8 (Jessie). See Resolving Dockerfile build failures for a workaround.

I'm seeing an error about a missing library or dependency

Some extensions rely on libraries not found in specific Docker images. For example, Visual Studio Live Share requires the installation of system-level dependencies, which are listed in their documentation. The need for these dependencies may depend on the operating system (for example, specific Linux distribution) used by your Docker image. You may need to install these dependencies during the Docker build process, by adding required commands to your Dockerfile. Search the specific extension's documentation to check for dependencies and see Installing additional software for help with resolving the problem.

Can I connect to multiple containers at once?

A VS Code window can only connect to one window currently, but you can open a new window and attach to an already running container or use a common Docker Compose file with multiple devcontainer.json files to automate the process a bit more.

Can I work with containers on a remote host?

Yes, you can either attach to a container running on a remote host or create a specialized devcontainer.json to tell VS Code how to work with your remote environment. To access the host, you can either connect to a publicly exposed Docker daemon TCP port or use SSH to tunnel into a remote VM running Docker. See Developing inside a container on a remote Docker host for details.

How can I build or deploy container images into my local Docker / Kubernetes install when working inside a container?

You can build images and deploy containers by forwarding the Docker socket and installing the Docker CLI (and kubectl for Kubernetes) in the container. See the Docker-in-Docker, Docker-in-Docker Compose, and Kubernetes-Helm dev container definitions for details.

What are the connectivity requirements for the VS Code Server when it is running in a container?

Installation of VS Code Server requires that your local machine have outbound HTTPS (port 443) connectivity to:

The Remote - Containers extensions will download VS Code Server locally and copy it to the container once connected.

You can install extensions manually without an internet connection using the Extensions: Install from VSIX... command, but if you use the extension panel or devcontainer.json to install extensions, your local machine and VS Code Server will need outbound HTTPS (port 443) access to:

Finally, some extensions (like C#) download secondary dependencies from download.microsoft.com or download.visualstudio.microsoft.com. Others (like Visual Studio Live Share) may have additional connectivity requirements. Consult the extension's documentation for details if you run into trouble.

VS Code Server runs on a random port inside the container and VS Code itself uses docker exec to communicate with it over Docker's configured communication channel.

Can I use the extension with source code stored in WSL2 on Windows?

If you are using Docker Desktop's WSL2 engine, you can enable experimental support in the Remote - Containers extension that will allow you to open folders from the \\wsl$ share in a container. Simply check Remote > Containers: Experimental WSL in VS Code settings and restart VS Code. See this excellent blog post for complete setup details.

As an extension author, what do I need to do to make sure my extension works?

The VS Code extension API hides most of the implementation details of running remotely so many extensions will just work inside dev containers without any modification. However, we recommend that you test your extension in a dev container to be sure that all of its functionality works as expected. See the article on Supporting Remote Development for details.

What other resources are there that may be able to answer my question?

The following articles may help answer your question:

Questions or feedback