Setup Drupal, Lando and mutagen.io file sync with WSL 2 on Windows 10

  • Jonathan Minder

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:
https://docs.microsoft.com/en-us/windows/wsl/install-win10

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 2.3.3.2. Download it here.

Be careful!

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.
wget https://github.com/lando/lando/releases/download/v3.0.10/lando-v3.0.10.deb
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 /var/lib/dpkg/status.
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:
/home/username/projects/yourproject

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

Run 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.

Important:

  • 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.
Example:
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 excluded folders:

mutagen.yml

# 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.

Final thoughts

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.


Sag uns was du denkst