Introduction
This guide will walk you through the best practices for setting up a modern development environment on Windows 11 with WSL2, including tools, configurations, and Docker installation directly within WSL2 for optimal performance.
1. Why WSL2 for Development on Windows 11?
WSL2 allows Windows users to run a full Linux kernel inside Windows, delivering a real Linux experience without a virtual machine. Some of the advantages of WSL2 for development include:
- Enhanced Performance: WSL2 runs a real Linux kernel, providing near-native speeds for Linux tools and commands.
- Seamless Integration: Filesystem access between Windows and Linux is fast and accessible from both sides.
- Docker Compatibility: WSL2 provides an ideal environment for Docker, enabling containerized development on Windows without Docker Desktop’s overhead.
- Lightweight and Resource-Efficient: WSL2 uses fewer resources than a traditional VM, making it ideal for modern development needs.
2. Setting Up WSL2 on Windows 11
- Enable WSL2:
- Open PowerShell as Administrator and run:powershellCopy code
wsl --install
- This command installs WSL2 and sets it as the default version. If you want to install a specific distro (e.g., Ubuntu 22.04), use:powershellCopy code
wsl --install -d Ubuntu
- Open PowerShell as Administrator and run:powershellCopy code
- Set WSL2 as the Default Version:
- If you already have other versions of WSL installed, set WSL2 as default with:powershellCopy code
wsl --set-default-version 2
- If you already have other versions of WSL installed, set WSL2 as default with:powershellCopy code
- Verify Installation:
- Run
wsl --list --verbose
to confirm WSL2 is installed and verify the version for each distribution.
- Run
The most popular WSL2 distros for development are Ubuntu 24.04 LTS, Debian, and Fedora. For consistency and ease of use, Ubuntu 24.04 LTS is a solid choice, widely supported and documented.
Step-by-Step Guide to Installing Docker in WSL2
Why Docker in WSL2 Is Better for Development?
- Native Linux Filesystem: Running Docker in WSL2 avoids the performance issues of syncing files between Windows and WSL. When code and containers are in WSL2, file I/O operations are faster.
- Linux Kernel: WSL2 uses a real Linux kernel, making Docker behave more like it would on a dedicated Linux machine.
- Reduced Resource Overhead: Docker Desktop for Windows introduces overhead since it has to bridge the Windows and Linux environments.
- Docker Desktop for Windows has issues with slow file syncing, especially for projects with many small files (like PHP projects with vendor directories).
Docker Desktop for Windows does indeed use WSL2 as its backend, which is why it shows WSL2 integration in the resources section. However, even though Docker Desktop uses WSL2 to run Linux containers, it still adds an additional layer of overhead that makes it resource-intensive compared to running Docker entirely within WSL2 without Docker Desktop.
Yes, running Docker directly inside WSL2 is generally a better choice for a more stable, Linux-native development environment on Windows, especially when using PHP, Docker, and PhpStorm for web development.
- Install Docker Directly in WSL2:
- Update the package list and install Docker:bashCopy code
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpgecho "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io
- Update the package list and install Docker:bashCopy code
- Run Docker Without
sudo
:- Add your user to the
docker
group to allow running Docker commands Essential Tools and Utilities for Developmentwithoutsudo
: usermod -aG docker $USER
- Restart your WSL session to apply changes.
- Add your user to the
- Verify Docker Installation:
docker --version
Download Docker Compose
- Get the latest stable version of Docker Compose:
- Check the Docker Compose GitHub releases page for the latest version (e.g.,
v2.20.0
), and replace<version>
with the actual version number:bashCopy codeVERSION=<version> # Replace <version> with the latest version, e.g., 2.20.0 sudo curl -L "https://github.com/docker/compose/releases/download/v$VERSION/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
- Check the Docker Compose GitHub releases page for the latest version (e.g.,
- Make it Executable:
- Set executable permissions on the downloaded binary:bashCopy code
sudo chmod +x /usr/local/bin/docker-compose
- Set executable permissions on the downloaded binary:bashCopy code
7. Essential Tools and Utilities for Development
Container Management Tools:
Portainer
manage Docker containers with a GUI. Portainer can be installed directly within Docker
docker volume create portainer_data
docker run -d -p 8000:8000 -p 9443:9443 --name portainer
--restart=always
-v /var/run/docker.sock:/var/run/docker.sock
-v portainer_data:/data
portainer/portainer-ce:latest
Lazydocker
- Description: Lazydocker is a terminal-based Docker UI that provides a simple and fast way to manage containers, networks, and volumes from the command line.
- Installation:
curl https://raw.githubusercontent.com/jesseduffield/lazydocker/master/scripts/install_update_linux.sh | bash
Summary Comparison
Feature | Dev Containers (VS Code) | Docker on WSL2 with PhpStorm |
---|---|---|
IDE | Best for VS Code | Best for PhpStorm (or any IDE) |
Ease of Setup | Easier; requires only VS Code and Docker Desktop | Moderate; requires WSL2 and Docker in WSL setup |
Environment Consistency | Very consistent; config shared in devcontainer.json | Flexible, but manual setup for consistency |
Performance | Generally fast; less syncing needed on Windows | High performance in WSL2; ideal on WSL filesystem |
Customization | Moderate; limited to VS Code and devcontainer.json | High; full Docker flexibility |
Collaboration | Easy to share via devcontainer.json | Can be shared, but setup may vary across users |
Resource Usage | Lower on Windows due to VS Code’s remote support | Higher, but manageable within WSL2 |