Docker has made application development easier and quicker, but managing that environment can be difficult. A popular integrated development environment (IDE), Visual Studio (VS) Code, features integrations that can take your application development via Docker to new levels. In this article, we talk about how to get started using Docker with Visual Studio Code, and how best to manage VS code docker.
Table of Contents
Getting Started with Docker on Windows
Though VS Code can work with older versions of Docker Desktop and WSL, it is highly recommended that you run the latest versions of both. For the best experience the following versions should be used:
- Docker Desktop 2.3 and greater
- Windows Subsystem for Linux (WSL) 2 in Windows 10 version 2004 and greater
WSL 2 is a drastic change from the initial implementation of WSL and features a full Linux kernel built by Microsoft. This allows Linux containers to run natively without emulation. With this advantage, Docker Desktop can use dynamic memory allocation to manage CPU and memory, while providing improvements to file system sharing and boot time. Additionally, the Docker daemon now starts much quicker than in WSL 1. To learn more useful commands when managing Docker in Windows, refer to this article.
Enable WSL 2 Feature in Windows
First, you need to make sure that you have WSL enabled and then, in newer versions of Windows, enable WSL 2. Within Windows Features, you need to turn on two that are prerequisites, Virtual Machine Platform and Windows Subsystem for Linux.
This can also be done via
DISM as seen below and is generally the preferred method, especially if scripting an installation.
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
After installing both the Virtual Machine Platform and WSL, restart your system to enable these features.
One-Time Installation of Linux Kernel
When Windows has been updated to a build that supports WSL 2, there may be a one-time download necessary to update the Kernel component. You may or may not see this message depending on your Windows Installation. The quickest way to tell if you need to do this is by using the following command in a command prompt.
If a download is necessary, you will see the following message after running the
wsl command. If a download is required you will find that MSI is located on this Microsoft Download page.
WSL2 requires an update to its kernel component. For more information please visit https://aka.ms/wsl2kernel
Enable WSL 2 for New and Existing Distributions
Finally, once all prerequisites have been installed, you need to enable WSL 2 for any new installations. This can be done using the following command.
wsl --set-default-version 2
You may have existing distributions already installed that you want to migrate to WSL 2. To do this, you need to change them over to use WSL 2 by running the
--set-version command. The conversion may take a few minutes to complete.
wsl --set-version Ubuntu 2
To list all of the existing distributions and their version run,
wsl --list --verbose.
Installing a WSL Ubuntu Distribution
Before the latest version of WSL, you had to jump through some hoops to install a distribution. This process has been moved to the Microsoft Store. Navigate to the Microsoft Store application and locate the Ubuntu distribution (for this article). Click on Install and once the distribution has been downloaded, installed, and configured you will see the Launch button.
Configuring Docker Desktop for WSL 2
There are a couple of settings that are necessary to set within Docker Desktop to take advantage of WSL 2. On the General tab of Settings, make sure to check the Use the WSL 2 based engine setting.
Next, you should set the Settings → Resources → WSL Integration option for resource integration with WSL 2 distributions. By default, only the default WSL distribution is enabled for integration, but you can use the page to enable this for additional distributions that you may have installed.
Configuring VS Code for Docker
VS Code integrates with Docker Desktop and WSL 2 via the Remote Development extension. This contains a series of three individual extensions that make it easy to work with WSL, Docker, and containers.
- Remote – SSH Make it easy to work with source code in a remote machine or virtual machine by using the SSH protocol.
- Remote – Containers Enable mounting a folder into or from inside a container within VS Code.
- Remote – WSL Open any folder from within a WSL distribution in VS Code.
For the Remote – SSH extension, you need to install a compatible SSH client. Windows 10 1803 and greater have the option to install the Windows OpenSSH Client. This extension looks for the
ssh command on the PATH. To make sure this optional feature is enabled, you can navigate to the Apps → Apps and Features → Manage Optional Features and install the OpenSSH Client.
This can also be installed via
DISM as used before to install WSL and Virtual Machine functionality.
dism /online /Add-Capability /CapabilityName:OpenSSH.Client~~~~0.0.1.0
Managing Docker in VS Code
Now that all of the prerequisites have been installed and configured, it’s on to using Docker containers within VS Code! Thankfully, the extensions we have installed make this very easy to get started with.
Starting a Container in VS Code
Once you have opened VS Code, the fastest way to see the available remote commands is by using the connection icon in the lower left. Once clicked on, you will see a listing of the available commands for interacting with remote containers.
For this article, we are going to demonstrate working with a container by using the handy “Try a Sample…” command. Locate the Remote Containers: Try a Sample… option in the menu and choose the PHP docker container.
Once you click on this option, the container will start and at the end of its configuration, the connection icon should show as Dev Container: PHP. Additionally, the Explorer will show the file system of the remote container as well that you can directly interact with. For example, we have opened the
index.php file to directly edit.
You can also see that this container is tracked and running by looking at the currently running containers within Docker Desktop.
Modifying a Container and Restarting
You may have noticed a
devcontainer.json file that was created in the
.devcontainer folder within the container. This file contains VS Code’s container configuration and is used when launching or attaching to a given container. This file can be located in one of two locations from the root of your project.
When the PHP container first started up, you might have noticed that the typically used
[localhost:3000](<http://localhost:3000>) address was not returning anything. That is because there is no exposed port or PHP server running that would make this work. Therefore, we need to modify the
devcontainer.json file to expose the port and also start a container local PHP server. Uncomment the following lines and modify per the code shown below.
// Use 'forwardPorts' to make a list of ports inside the container available locally. "forwardPorts": , // Use 'postCreateCommand' to run commands after the container is created. "postCreateCommand": "nohup php -S 0.0.0.0:3000 > phpd.log 2>&1 &",
We are using the
nohupcommand and redirecting output because without this the local PHP server takes over the session and stops the container from fully starting.
This change won’t be reflected until a rebuild of the container. Since we are modifying the locally cloned version of this container, the changes are persisted. Click on the connection icon and choose Remote Container: Rebuild Container.
This will re-create the container, exposing the port, and starting the PHP container. Navigate to
[localhost:3000](<http://localhost:3000>) in your browser where you can see that the
index.php output is reflected on the screen.
Debugging PHP in a Container
Finally, to demonstrate how useful running code in containers can be and integrated with VS Code, let’s demonstrate how to debug from VS Code. This sample container that we are using is already setup for XDebug and VS Code is set up to utilize that via the
.vscode/launch.json file. Open
index.php in VS Code from the container and set a breakpoint on line 9 next to the
echo "Hello $name!"; command.
While focused on the
index.php file, either hit the F5 key or Run → Start Debugging, and navigate to the Run pane. You will be able to see that under the Locals section of Variables, we can see the
$name: "remote world" variable value. Execution has also paused at the
At this point, you can use traditional debugging methods to inspect the running server and variables.
Fixing a Broken
If you find yourself in a situation where the
devcontainer.json has stuck your console in a never-ending loop or paused from further execution, you can utilize the Docker Desktop CLI option to modify your
devcontainer.json file to fix the issue.
Navigate to the
workspaces folder and then the
devcontainer.json file where you can use
Nano (depending on the container) to modify the file. At this point, stop VS Code and reload the container.
Managing Docker contains in VS Code is made easy by the many extensions that support modern versions of Docker Desktop and WSL 2. This article is merely scratching the surface and you will be able to optimize your experience by modifying the
devcontainer.json file and customize VS Code to your workflow. The flexibility afforded by Docker and VS Code will streamline any person or organization’s application development immensely.