DEV Community


Posted on

Setting-up a local development environment using VS Code, Docker, and WSL 2

Developing software within a Windows environment is such a pain especially if you're into writing web applications. In my case, most of the web apps I made are deployed and ran on a Linux machine hosted on the cloud. This means that I can't issue commands on my local machine as I did on the server.

In this post, I'll share how I achieved setting-up my Windows machine to use WSL 2 alongside Docker and VS Code to create a local development environment that runs on a Linux environment (Ubuntu 20.04 LTS).


Before you proceed make sure you have already installed the following applications on your machine.

Make sure you have ticked the option to add VS Code to Window's path. We will be needing this to use the code command within the WSL environment.

VS Code installation instructions

Getting Started

After you have installed the required applications, you can now start with the steps as detailed below.

Installing Ubuntu on WSL

The environment I choose to develop to is Ubuntu (20.04 LTS) but you can choose any other Linux distros you prefer. Beware though that not all are free.

  1. Open up Microsoft Store.
  2. Search and select Ubuntu 20.04 LTS (or your preferred Linux distro).
  3. Click GET button. This will download and install Ubuntu on your machine.
  4. Once finished, click Launch. This will open a command prompt and asks you to setup the user account of the system.

Alt Text

  1. And that's it! You have now installed and ran Ubuntu on your Windows machine.

Setting-up Ubuntu to use WSL 2

By default, Windows installs your distro using WSL 1 but in this case, we will be using WSL 2. WSL 2 is the newest version and is much faster than WSL 1 in terms of file system performance. For comparison, you can check this link Comparing WSL 1 and WSL 2.

  1. Verify which version of WSL your distro is using by clicking Start, type PowerShell, and select Windows PowerShell. Copy and run the command below.
PS> wsl -l -v
Enter fullscreen mode Exit fullscreen mode

It should show a similar output as below. If the version of your distro is already 2, feel free to skip this section.

Alt Text

  1. To convert to version 2, copy and run the command below substituting the placeholders with your actual values. Note that you can always switch back between versions.
# wsl --set-version <distribution-name> <version-number>
$ wsl --set-version Ubuntu-20.04 2
Enter fullscreen mode Exit fullscreen mode
  1. And that's it! Running the command again from step 1 should now show version 2.

Alt Text

Configuring Docker for WSL Integration

Configuring Docker Desktop for WSL 2 is quite easy. We just need to enable a few settings and we're good to go.

  1. Start Docker Desktop via Windows Start menu.
  2. Open Settings by right-clicking Docker icon located in the System tray. Alt Text
  3. Under General, make sure Use the WSL 2 based engine is ticked. Alt Text
  4. Next, under Resources > WSL INTEGRATION, enable the Linux distro you would like to be integrated with Docker. Alt Text
  5. Hit Apply & Restart button and you're done!

Installing Windows Terminal

This is an optional step and you're free to skip this section. I highly recommend installing Windows Terminal though as it makes it easy to start and switch between distros (if you have more than one). Plus, compared to CMD, it has a nice UI!

Alt Text

  1. Install Windows Terminal via Microsoft Store.
  2. Click GET button and it should download and install Windows Terminal.
  3. To open, simply hit Start and search for Windows Terminal.

Now, when we want to connect to an installed Linux distro, we can just easily click the dropdown menu located at the top. In my case, using Ubuntu-20.04.

Alt Text

Alt Text

Setting-up VS Code for remote development

We will be using a Docker container as our development environment running in the Ubuntu distro we had previously setup. Inside this container will be our project and its dependencies. But before we can make changes to our code, we need to have VS Code connect to our WSL environment first. To do this, we have to install a VS Code extension called Remote Development. Go ahead and install this extension.

If you notice, this is an extension pack meaning it will install the following:

The important ones are the Remote - WSL and Remote - Containers as this will allow us to connect inside WSL and in our Docker container.

After the installation, you'll notice that a new status bar located at the bottom-left is now available. Clicking this item will give you different options on how you want to open your project.
Alt Text

Creating our sample project

Now that we have installed the extension, VS Code should now be able to open a project inside WSL. Since we don't have a project yet, let's go ahead and create a sample Laravel project.

  1. Open Windows Terminal and connect to your installed distro (Ubuntu-20.04).
  2. Create a Laravel project on your chosen directory.
$ cd /opt/workspace/
$ curl -s | bash
Enter fullscreen mode Exit fullscreen mode
  1. Next, we'll open this project in VS Code. Remember I mentioned that you need to tick the option to add VS Code in Windows Path? The reason is we will be using the code command to open our project.
$ cd example-app
$ code .
Enter fullscreen mode Exit fullscreen mode

You'll know that you're opening a project inside a WSL if you're seeing this in the status bar.
Alt Text

It's pretty amazing that we can invoke a Windows application inside our Ubuntu environment. As a matter of fact, you can actually open File explorer in the current directory by typing explorer.exe .. Try it!

Creating a development container

Now that we have our sample project, we just need to bind this into our Docker container. We will be leveraging VS Code's Remote Containers extension.

The power of Remote Containers lies in a file called devcontainer.json. This will instruct how VS Code will access or create our Docker container.

  1. Open Command Palette (F1) and search for Remote-Containers: Add Development Container Configuration Files....
  2. Select From a predefined container configuration....
  3. Select PHP & MariaDB. This will create a new folder in your root project directory called .devcontainer with the following files. Alt Text
  4. Since we will be using artisan serve, we must add the port 8000 as one of the forwardPorts values.
"forwardPorts": [8080, 3306, 8000],
Enter fullscreen mode Exit fullscreen mode
  1. To build this, hit F1 and search Reopen in Container. Note that this might take awhile but will be faster the next time we rebuild. Alt Text
  2. Once build, open a new Terminal and start PHP's built-in development server.
$ php artisan serve
Enter fullscreen mode Exit fullscreen mode

If you notice, the opened Terminal automatically connects to the container, giving us little hassle as we no longer need to use Docker exec commands.

  1. Got ahead and open up localhost:8000. You should see Laravel's welcome route.

Alt Text

Of course, we wouldn't want to manually issue the artisan serve command every time we want to start our project. To automate this, we can use another VS Code feature called Tasks and configure it to run every time our project folder is opened.

And that's it! As we saw, we now have a local development environment running on a container under WSL 2 (Ubuntu-20.04). If you want to add other dependencies to our container like git and composer, you just need to modify the .devcontainer/Dockerfile file and rebuild the project once again.

If you're running low on system memory due to virtualization, we can instruct Windows to only allocate a certain amount of memory for virtualization. To do this, create a file in %userprofile% called .wslconfig and paste the content below.

processors=4 # Number of processors to allocate.
memory=4GB   # Maximum amount of memory to allocate.
Enter fullscreen mode Exit fullscreen mode

Before this takes effect, you may need to shutdown WSL by running the command below on Powershell and restarting Docker Desktop.

PS> wsl --shutdown
Enter fullscreen mode Exit fullscreen mode

After this, open your Task Manager and look for Vmmem. The memory consumption should drop around your set values.
Alt Text

Top comments (1)

elysianwebdesign profile image
Evan Marshall

Hello. I am a noob with docker and have slight experience with php. I have a local website created and I have utilized php mainly for navigation and page file structure. I built it a couple of years ago using homestead on PC and some was built with laravel/valet on Mac. I would like to use docker containers going forward and I believe this article is the way to do it, but I cannot seem to run my website. I can run the sample-app no problem following this tutorial so I am thinking there is something I need to download into my local project which is contained in the curl/laravel sample you download in this. Do I simply go into my local project and run the same curl command (this seems like a little much to download a full sample laravel app into each of my projects)? I think I am close, but just need a little nudge in the right direction. When I get to the part where I try and load my localhost:8000 the page just hangs and does not load, but works great with the sample project in this post. I can share my github repo of my project if it helps. Thanks in advance!