Getting Started Managing Docker with VS Code

Adam Listek

Adam Listek

Read more posts by this author.

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.

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.

Windows Feature installation screen for Virtual Machine Platform and Windows Subsystem for Linux.
Windows Feature installation screen for 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.

wsl

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

Command Prompt for WSL and required Kernel Component Update. Source: https://devblogs.microsoft.com/commandline/wsl2-will-be-generally-available-in-windows-10-version-2004/
Command Prompt for WSL and required Kernel Component Update. Source: https://devblogs.microsoft.com/commandline/wsl2-will-be-generally-available-in-windows-10-version-2004/

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.

Installing the Ubuntu distribution from the Microsoft Store.
Installing the Ubuntu distribution from the Microsoft Store.

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.

Setting the Use the WSL 2 based engine setting in the Settings → General tab of Docker Desktop for Windows.
Setting the Use the WSL 2 based engine setting in the Settings → General tab of Docker Desktop for Windows.

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.

Setting the Enable integration with my default WSL distro setting in the Settings → Resources → WSL Integration tab of Docker Desktop for Windows.
Setting the Enable integration with my default WSL distro setting in the Settings → Resources → WSL Integration tab of Docker Desktop for Windows.

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.

Installing the OpenSSH Client via the Optional Features in Windows.
Installing the OpenSSH Client via the Optional Features in Windows.

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.

Listing commands for remote containers in VS Code
Listing commands for remote containers in VS Code

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.

Sample containers list in VS Code.
Sample containers list in VS Code.

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.

Opening index.php in VS Code from the remote PHP container loaded by Docker Desktop.
Opening index.php in VS Code from the remote PHP container loaded by Docker Desktop.

You can also see that this container is tracked and running by looking at the currently running containers within Docker Desktop.

Viewing the currently running PHP container from within Docker Desktop
Viewing the currently running PHP container from 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.

  • .devcontainer/devcontainer.json
  • .devcontainer.json

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": [3000],

// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "nohup php -S 0.0.0.0:3000 > phpd.log 2>&1 &",
Modifying the devcontainer.json file to expose a port and start a PHP server.
Modifying the devcontainer.json file to expose a port and start a PHP server.

We are using the nohup command 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.

Rebuild the Docker container after modifying the devcontainer.json file.
Rebuild the Docker container after modifying the devcontainer.json file.

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.

Browser output from the PHP server running on port 3000 in the container.
Browser output from the PHP server running on port 3000 in the container.

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.

Add a breakpoint to the index.php file in VS Code.
Add a breakpoint to the index.php file in VS Code.

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 echo command.

Debugging the index.php file in VS Code.
Debugging the index.php file in VS Code.

At this point, you can use traditional debugging methods to inspect the running server and variables.

Fixing a Broken devcontainer.json File

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.

Starting the CLI in Docker Desktop.
Starting the CLI in Docker Desktop.

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.

Modify the devcontainer.json file from the Docker Desktop CLI.
Modify the devcontainer.json file from the Docker Desktop CLI.

Conclusion

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.

Subscribe to Adam the Automator

Get the latest posts delivered right to your inbox

Looks like you're offline!