Docker Desktop 2.2, WSL 2, Drupal 8, and Symfony Performance

Callback Insanity
12 min readJan 31, 2020
Source: sensiolabs.com

I’ve been writing about two stack update tracks going on recently. In today’s article I want to cover some of the questions I have related to the performance improvement that each stack update brings, and how they relate to each other.

Sometimes I confuse which performance upgrade belongs to which stack, because you need to only utter the word performance and as an operations engineer I have the same euphoric reaction:

I had read a article of how Docker performance improved recently while using Symfony. Since Drupal does in fact use Symfony, this is two-hundred percent relevant to me (I ran statsd on my brain to measure relevance). And then I forgot to save the article somewhere useful. I went to Microsoft’s documentation but couldn’t find the article!

After spending what seemed like an hour looking at Chrome browser’s history logs (not helped by the fact that it merges my Google Pixel’s history too), it happens that the Symfony-related performance improvement was related to Docker Desktop and not WSL. Here’s the article:

There’s two main things in that article that justified an hour searching for it:

The latest Edge release of Docker Desktop for Windows 2.1.7.0 has a completely new filesharing implementation using Filesystem in Userspace (FUSE) instead of Samba.

And, perhaps more relevant to my interests:

uses caching to (for example) reduce page load time in Symfony by up to 60%;

Symfony! Ahem, cough Drupal, cough. Performance!

The two bars in the middle show the latency when the files are shared with the new system in Docker Desktop Edge 2.1.7.0. The initial (uncached) fetch is already better than with the previous Desktop version, but the second (cached) fetch is 60% faster! Source: docker.com

.

I mention Drupal surreptitiously because Symfony does not depend on Drupal, but Drupal 8 depends on Symfony more than a millennial junkie on his daddy’s trust fund.

There’s two main questions that arise the article penned by Docker own’s David Scott:

.

#1 What is the caching implementation? Is it internally tucked away from the user (automatic, no user control)? Or is it tied to Docker volume consistency: consistent , cached , or delegated (user has control).

.

#2 Are Docker 2.2.x file system improvements tied to also upgrading to WSL 2?

.

.

.

TL;DR: as a Docker Desktop user:

.

Do I benefit when I store the files in Windows Subsystem for Linux and mount them to Docker?

YES.

Up to 60% as proven by a simulated Symfony workload. Mileage may vary depending on your particular workload, and whether it makes use of caching, where caching is your application’s internal caching, and not to be confused with Docker’s volume caching, which is separate and clarified further below.

Do I benefit when I store the files in Windows/Mac and share them to Docker?

NO.

Not for massive performance improvements anyways. But you would get newer features anyways courtesy of the Docker engine, and both Docker Desktop 2.2 and WSL 2 run probably faster by themselves, so hey! Why not upgrade anyways? Just don’t expect any life-altering performance improvements.

Do I need to tweak any bind volumes from their default consistency from consistent to cached or delegated ?

NO.

You will reap benefits from thew new Docker Desktop version 2.2 using the default consistent volume consistency. But if you want to put your Docker workloads on crack try some consistency optimizations by switching some of the mounts to cached or delegated . More on that later.

Do I need to upgrade from WSL 1 to WSL 2?

YES.

When I upgraded from my previous version to Docker Desktop version 2.2, I still have WSL version 1 installed on my Windows machine. Docker Desktop would not allow me to enable the WSL integration. Once I upgraded WSL to version 2 (and restarted the machine, obviously), Docker Desktop 2.2 allowed me to enable the WSL integration. And so the cycle of life was complete.

.

.

Okay, now for the actual questions (and memes).

Question #1: What is the caching implementation ?

.

.

When Scott ran his benchmark, what consistency did he use? David’s Scott’s earlier article kindly links to the workload he ran to test the new WSL 2 setup:

On Scott’s Symfony demo Makefile, the command to run the Docker workload is:

Scott’s Symfony Demo for Docker Desktop, Makefile excerpt.

Here’s a breakdown of Scott’s demo. With regards to Scott’s demo volume mount instruction, which is found on the Github project I linked to:

-v $(shell pwd)/www:/var/www djs55/symfony-demo

You can see that the volume --volume , -v instruction does not specify mount consistency. To do that, you would probably need to employ the --mount flag, which seems to offer a richer set of options.

As referenced by the --mount flag documentation, the service create command reference mentions full options for bind mounts, including mount consistency: default , consistent (also the default), cached , and delegated .

But Scott’s demo is not using --mount , much less specifying mount consistency.

In addition, over at Configure mount consistency for macOS (Docker Docs):

By default, … shares are fully-consistent, meaning that every time a write happens on the macOS host or through a mount in a container, the changes are flushed to disk so that all participants in the share have a fully-consistent view.

.

With all these data points we can make the following inferences:

  • Docker’s default volume mount consistency is consistent across Mac and Windows Docker Desktop implementations.
  • Scott’s demo does not specify consistency, therefore the Symfony demo’s volume consistency is the default , which would mean consistent .
  • Therefore, Scott must have achieved up to a 60% performance improvement on Symfony workloads using the default volume consistent consistency!

In addition:

  • The user ultimately has control of the caching strategy and can further optimize it to be cached or delegated in accordance to his current Docker workloads — or leave it at the default should he/she need increased data integrity.
  • Out of the box, users will see a performance improvement using the default caching strategy of consistent, as denoted by the various data points quoted above (Docker Docs, Scott’s Symfony Demo).

.

.

Question #2: Are Docker 2.2.x file system improvements tied to WSL 2 (Or, do I really need to upgrade them BOTH)?

This is a bit harder to glean from Scott’s Symfony demo.

  • I can’t glean from the Symfony demo if the docker run command was from outside WSL, on a Windows host, or inside WSL from say, Ubuntu WSL.
  • The Docker Desktop release linked by Scott, release 2.1.7.0 does tout prominently brand new WSL integration, specifically WSL version 2.

On Simon Ferquel’s Introducing the Docker Desktop WSL 2 Backend (October 24, 2019), under the “Linux Workspaces support” section, it reads:

Using this we are actually able to expose the (Docker Desktop) daemon to the user distro (Ubuntu, Alpine, etc.), and we can access the user distro files (Ubuntu, etc.) from within our contained environment (Docker Desktop) with native Linux performance. Emphasis is mine.

I want re-emphasize that the following line:

… with native Linux performance.

What this section is saying is basically that because the Docker daemon (aka Docker Desktop) is running inside the WSL space, the Docker daemon has an easier time accessing files made available by other distributions running inside the same WSL space.

.

Wait. That … can’t be true?

Don’t believe me? Here’s a direct screenshot from Simon Ferquel’s article on Docker.com (how many times am I going to link to it):

.

This was my reaction after reading that line:

Terry Crew’s mind was blown away too.

.

If you read Scott’s article, you’ll come to understand the mind blowing fact that they’re running the Docker deamon itself as a separate, isolated WSL distribution, instead of inside Hyper V. Let me pause here. What this means is that:

  • When you docker run from Ubuntu WSL — you ain’t talking to Windows Hyper V. docker run is talking to another WSL distribution, which contains the Docker daemon itself… This WSL distro to WSL distro communication is what allows near-native performance improvements, which makes sense…
  • When you talk to Docker Desktop from Windows, say you open cmd.exe, and type docker run, you ain’t talking to Windows Hyper V either…
  • If you execute docker run from cmd.exe, that command is going into WSL, and talking to the Docker daemon provided by Docker Desktop, running inside WSL.

Inception ensues:

What happens when I type docker help inside WSL 2

In addition to those mind levelers:

And, David Scott’s Symfony Demo article:

With those data points correlated, I’d say that David Scott:

  • Installed the Docker client using apt-get inside an Ubuntu WSL distribution;
  • Ran the Symfony demo using the Docker client installed inside Ubuntu WSL distribution, in order to achieve that near Linux performance that you get when mounting volumes from one WSL distribution (Ubuntu) to another WSL distribution (Docker).

Therefore it is with a high degree of confidence that I conclude: Docker 2.2 file system improvements are indeed tied to WSL 2 integration.

Case in point, before upgrading to Docker Desktop 2.2 and WSL version 2, I used to have the following in my Ubuntu WSL distrubtion’s .profile :

That variable DOCKER_HOST , allowed my Ubuntu WSL docker client to communicate with the Docker daemon provided by Docker Desktop, which in turn ran in Hyper V, and exposed tcp://localhost:2375 to Docker clients.

Without this line my Ubuntu WSL would not be able to talk to Docker Desktop.

After upgrading both Docker Desktop and WSL (and yes, I had to upgrade both), I had to comment that line out in order for the docker client inside WSL to talk to Docker Desktop-provided Docker daemon.

Using docker info you can confirm which Docker daemon your Docker client is talking to, and in my case, confirm that both Windows cmd.exe (or PowerShell), and Ubuntu in WSL 2 are talking to the same exact Docker daemon:

From Ubuntu WSL
From PowerShell

Notice the matching Docker ID on both PowerShell and Ubuntu WSL shells:

NSBJ:CBIG:7F5B:NTFL:RRRF:FR7Z:R7CP:E5RX:VQ3V:Y4VV:4THO:NGF6

In order to attain these performance gains, you will need to observe the following details:

  • Locate your source code inside WSL.
  • Install the docker and docker-compose clients inside WSL.
  • Rundocker and docker-compose commands from inside WSL.
  • Do: Mount your source code from your WSL distribution into Docker Desktop.
  • Do Not: Mount source code on the host Windows machine into Docker Desktop.

While it is still possible to mount Windows files into Docker Desktop 2.2, you wont achieve that lucrative up to 60% performance gain (slaps heartily on lid of laptop).

.

.

.

Tuning Docker Volume Consistency

.

.

Today I mentioned at the beginning of my article volume consistency tuning.

While I hopefully established quickly that it is not the #1 deciding factor in achieving performance gains when upgrading Docker Desktop and WSL, it could still make a unnoticeable or outsize impact depending on your individual Docker workloads.

The following articles offer in-depth advice on bind volume mount consistency (The Good), and in-particular details about volume consistency when applied to the Drupal and PHP stacks (The Excellent). The only downside is that Docker on Mac Performance was written in mid-2017 (The Bad), and while Speeding up Docker on MacOS was written on July 2019, both of these articles are written for Docker for Mac (The Ugly).

The silver lining on both of these detailed articles, especially the older one (Spoiler: it has benchmarks), is that the advice on volume mount consistency and performance, the last missing piece of the puzzle for today’s article should still generally hold. I hope. There’s only one way to find out: doing benchmarks. Specifically real-life workloads on Windows WSL 2, Composer, and Drupal. But I’m out of time for this article, so let there be links (below).

.

And links shall be had, oh my:

.

Bibliography and Snippets

.

Some more links and information I used to compile this story.

.

From the Docker Desktop 2.2 release notes: https://docs.docker.com/docker-for-windows/release-notes/#docker-desktop-community-2200

The experimental Docker Desktop WSL 2 backend architecture introduces support for Kubernetes, provides an updated Docker daemon, offers VPN-friendly networking, and additional features. For more information, see Docker Desktop WSL 2 backend.

From https://docs.docker.com/docker-for-windows/wsl-tech-preview/:

WSL 2 introduces a significant architectural change as it is a full Linux kernel built by Microsoft, allowing Linux containers to run natively without emulation. With Docker Desktop running on WSL 2, users can leverage Linux workspaces and avoid having to maintain both Linux and Windows build scripts.

Docker Desktop also leverages 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 much faster.

Additionally, with WSL 2, the time required to start a Docker daemon after a cold start is significantly faster. It takes less than 2 seconds to start the Docker daemon when compared to tens of seconds in the current version of Docker Desktop.

From https://docs.docker.com/docker-for-windows/edge-release-notes/#docker-desktop-community-2170:

File sharing: The new gRPC FUSE system is no longer experimental and is enabled by default even when experimental features are turned off.

Docker Desktop release 2.2 announcement, by Ben De St. Paer-Gotch (Docker), January 21, 2019.

This new architecture for WSL 2 allows users to … turn off the traditional Hyper V VM while working with WSL 2…

Traditionally with Docker Desktop on Windows, we have relied upon the Samba protocol to manage the interaction between the Linux file system working with Docker and the Windows file system. We have now replaced this with gRPC FUSE, which: uses caching to (for example) reduce page load time in Symfony by up to 60%; supports Linux inotify events, triggering automatic recompilation / reload when the source code is changed;

Introducing the Docker Desktop WSL 2 Backend by Docker’s own Simon Ferquel, October 24, 2019.

5 Things to Try with Docker Desktop WSL 2 Tech Preview, also by Simon himself, July 31, 2019.

In addition, Simon’s last blog post links to two Microsoft Development Blog items, written by Microsoft’s Craig Loewen. If you’ve been following Docker Desktop and WSL on Windows you’ve probably seen them, but I’ll still be useful to link them as they provide useful high-level information as well:

WSL 2 is now available in Windows Insiders, Craig Loewen (Microsoft), June 12, 2019.

Announcing WSL 2, Craig Loewen (Microsoft), May 6, 2019.

.

And since I mentioned that Drupal was related to Symfony, in case you’re curious:

.

.

.

--

--

Callback Insanity

Organic, fair-sourced DevOps and Full-Stack things. This is a BYOB Establishment — Bring Your Own hipster Beard.