Have you ever had the dream of a lightning fast developer experience? Loading your page should be as fast as on the productive system? Your dream came true with Lando/ Docker on WSL 2 on Windows.
For years, I'm using DrupalVM and Vagrant on my Windows machine combined with Vagrant WinNFSd. It worked well, but it was painfully slow.
composer update took minutes on large projects and every page load was slow.
I also used WSL 1, but accessing files from an NTFS drive under
/mnt/c/docs was slow.
By the end of May 2020, Microsoft started distributing the Windows 10 2004 update. This was the first release, where WSL 2 (Windows Subsystem Linux) was officially available as a part of Windows 10. WSL 2 is a new architecture that completely changes how Linux distributions interact with Windows. It's basically a native Linux kernel in Windows 10. The goal is to increase the file system performance and adding full system call compatibility.
The best feature of WSL 2 is the fact, that this is the new de facto-standard backend for Docker Desktop on Windows. Docker Desktop uses the dynamic memory allocation feature in WSL 2 to greatly improve the resource consumption. This means, Docker Desktop only uses the required amount of CPU and memory resources it needs, while enabling CPU and memory-intensive tasks such as building a container to run way faster.
Additionally, with WSL 2, the time required to start a Docker daemon after a cold start is significantly faster. It takes less than 10 seconds to start the Docker daemon compared to almost a minute in the previous version of Docker Desktop.
I combined these new technologies with Lando and created a perfect developer setup for any PHP / Symfony / Drupal-driven development stack. The missing piece to make it fly was a file sync option with mutagen.io Described later in this article.
Install WSL 2 on Windows 10
Follow the official documentation to install and enable WSL 2:
At some point, you will have to enable Hyper-V and set WSL 2 as your default version:
wsl --set-default-version 2
Install the Distro Ubuntu from the Microsoft Store
Open the Microsoft Store and install Ubuntu.
Fig. 1: Screenshot from the Microsoft Store
The first time you launch a newly installed Linux distribution, a console window will open and you'll be asked to wait for a minute or two for files to decompress and be stored on your PC. All future launches should take less than a second.
If you already have a WSL 1 distro you can upgrade it:
wsl --list --verbose
wsl --set-version <distribution name> <versionNumber>
Install Docker Desktop Edge on Windows
Next, install Docker Desktop Egde on WINDOWS!. By the time of writing, the current version was 22.214.171.124. Download it here.
There are a few tutorials online, that claim that you have to install docker inside your Linux distribution. This is wrong. You have to install Docker Desktop on Windows!
Install Lando > 3.0.9 inside your Ubuntu distro
Now we will install Lando inside our brand new WSL 2 distro "Ubuntu". This is a bit tricky, because
docker-ce is a hard dependency of the package. But the official documentation has a solution for that.
Use at least Lando 3.0.9 found on github.
dpkg -i --ignore-depends=docker-ce lando-v3.0.10.deb
To fix the package manager / apt-get you have to remove the Lando Package from
nano /var/lib/dpkg/status, search for Lando and remove the entry from the file. Done.
Integrate Lando in an existing Drupal project
I assume, that you already have a running project and want to integrate it with Lando and WSL 2. The most important thing is, that your files have to life inside your Ubuntu distro e.g.
/home/username/projects and not on
/mnt/c/ something. Inside your Ubuntu distro, you can profit from an EXT4 file system and native file system speed. We will sync back the file to Windows for editing in your favourite IDE later.
Go ahead and checkout your project from Git inside your home folder:
Add a .lando.yml file.
Please refer to the official Lando documentation. Attached you will find my optimized recipe for Drupal 8 with Solr. I also added lando/php.ini with some optimized PHP variables.
name: demo recipe: drupal8 config: webroot: web php: '7.3' xdebug: 'false' config: php: lando/php.ini proxy: fulltext: - admin.solr.fulltext.lndo.site:8983 services: appserver: build: - composer install xdebug: false overrides: environment: # support debugging Drush with XDEBUG. PHP_IDE_CONFIG: "serverName=appserver" LANDO_HOST_IP: "host.docker.internal" XDEBUG_CONFIG: "remote_enable=1 remote_host=host.docker.internal" DRUSH_OPTIONS_URI: "https://demo.lndo.site" database: # You can connect externally via "external_connection" info from `lando info`. portforward: true creds: # These credentials are used only for this specific instance. # You can use the same credentials for each Lando site. user: drupal password: drupal database: drupal fulltext: type: solr:8.4 portforward: true core: fulltext_index config: dir: solr/conf memcached: type: memcached portforward: false mem: 256 tooling: phpunit-local: service: appserver description: Runs phpunit with config at web/sites/default/local.phpunit.xml cmd: /app/vendor/bin/phpunit -v -c /app/web/sites/default/local.phpunit.xml xdebug-on: service: appserver description: Enable xdebug for apache. cmd: docker-php-ext-enable xdebug && /etc/init.d/apache2 reload user: root xdebug-off: service: appserver description: Disable xdebug for apache. cmd: rm /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && /etc/init.d/apache2 reload user: root
Build your Lando project and start the docker container
lando start to spin up your containers and see if everything goes green.
Install mutagen.io on Windows to sync the files on a Windows drive.
Go to the mutagen.io download page and download the Windows x64 binary.
Copy the binary to a folder like
C:\Program Files\Mutagen and add this folder to your PATH variable. Type
Windows Key + Break, from there, select "Advanced system settings" → "Environment Variables". Fig. 2: Screenshot from the my System Settings
Synchronize files back to Windows for editing with PHPStorm / VisualStudio Code
Maybe you asked yourself: How can I edit my files, if they are inside my distro?
Microsoft added the
\\wsl$\<Distro Name> file share, but as soon as your project has more than 100 files, it's unusable with PHPStorm or any other IDE. The file system performance of mounted volumes on WSL 2 is even 10x slower than on WSL 1. A lot of discussions and rants about this topic have been on on github.com. Here you go. At some point the issue was closed, so I couldn't post my solution to it.
Mutagen resolves this issue by syncing the files between a docker container and Windows in both directions. And it's blazing fast.
Mutagen allows you to do a "two-way-resolved" sync between a local folder on Windows with a docker container. Lando creates a
yourname_app_server_1 docker container with a mount to
/app. All you have to do is start mutagen and sync the files back to Windows. After that, you can edit them in PHPStorm. They get insta-synced back to your container and you can still enjoy two-time native speed: Inside the docker and inside your IDE. It also works well with files generate on the server like
drush config-export in Drupal 8.
For my setup I removed the .git folder inside Ubuntu / distro and excluded syncing VCS as proposed by mutagen. I use a Git client on the windows side. But you can change that.
- mutagen has to be run on the Windows side in a Powershell because we want to sync back to Windows!
- The lando appserver docker container has to be running before you can start the synchronization
Starting a sync with mutagen is dead simple:
mutagen sync @source @target. See here for the full documentation.
mutagen sync . docker://www-data@demo_appserver_1/app
The first sync takes a while (5-8 minutes) with > 40k files. From then on it's basically instant.
You can see the status / errors of the sync progress by running in a separate PowerShell:
mutagen sync list or
mutagen sync monitor
Unfortunately, there is no easy way to exclude certain folders from being synced except from a global .mutagen.yml file. Therefore I added a mutagen.yml file to my project folder and used
mutagen project start and
mutagen project terminate to start a predefined configuration including
# Synchronize code to the shared Docker volume via the Mutagen service. sync: defaults: flushOnCreate: true ignore: vcs: true demo: alpha: "." beta: "docker://www-data@demo_appserver_1/app" mode: "two-way-resolved" ignore: paths: - "mutagen.yml" - "mutagen.yml.lock" - ".vagrant" - ".git" - ".idea" - "deploy" - "example_frontend/node_modules" - "example_frontend/.nuxt"
In this example, I excluded a few folders which didn't have to be synced. Adapt it to your needs.
Enjoy your blazing fast development environment, edit your files in your favourite IDE on Windows and thank all the maintainers of the involved Open Source projects.
At some point in the future, we might be able to integrate mutagen into Lando and combine the
lando start or
lando stop events with mutagen. By now, I didn't find an easy way to integrate / call it from the Ubuntu distro.