Docker on WSL2 very slow
Asked Answered
T

11

96

After having read about the performance improvements when running Docker on WSL2, I have been waiting for the official release of Windows 10 that supports WSL2. I updated Windows and Docker and switched on the Docker flag to use WSL2 and was hoping for some performance boost for my Oracle Database running in a Docker container but unfortunately the change slowed down the container and my laptop dramatically. The performance of the container is about 10x slower and my laptop is pretty much stuck when starting the container. It seems as if the memory consumption would completely use up my 8GB and heavy memory swapping starts to take place. Is there anything I can do to improve the performance of Docker on WSL2 or at least to better understand what's wrong in my setup?

My environment:

  • Processor: Intel(R) Core(TM) i7-2620M CPU @ 2.70GHz, 2 Core(s)
  • Installed Physical Memory (RAM): 8.00 GB
  • Microsoft Windows 10 Pro Version 10.0.19041 Build 19041
  • Docker version 19.03.8, build afacb8b
Tope answered 2/6, 2020 at 14:12 Comment(4)
I have this issue as well, I have 16gb of memory and the vmmem process is consuming the majority of it.Howitzer
BTW There is an issue on this: github.com/microsoft/WSL/issues/4166 As we all wsl2 users end up searching what to do with stuck windows...Pucker
Similar problem, but with a lot of memory, and during build #65231610Acetometer
I recently switched back from Linux to windows so I could use proprietary software a bit easier. This was my biggest issue at first so I ended up dual booting into Ubuntu. Then yesterday I ran across this article: createit.com/blog/… and overall what you need to do is store your docker accessible code in WSL2 and then docker-compose up. From there you can access the running container ok localhost as normally experienced in Linux OSProconsulate
M
92

This comes from the "vmmem" which consumes as much resource as it can. To solve the problem just go to your user file for me in

C:\Users\userName

In this directory create a file named ".wslconfig" in which you will configure how many resources can consume WSL2:

[wsl2] 
memory=900MB    #Limits VM memory in WSL 2 to 900MB 
processors=1    #Makes the WSL 2 VM use one virtual processors

Now close your docker and wait for "vmmem" to close in the task manager.

then You can restart docker and normally "vmmem" will not exceed the limit you have set (here 900MB) If don't work restart your computer.

I hope it helped you.

Machicolation answered 13/6, 2020 at 1:0 Comment(8)
Thank you so much for your answer. Docker should offer to set this or something. Here is Microsoft's documentation on .wslconfig for reference.Howitzer
Using a .wslconfig files mitigates the resource consumption but actually makes the container itself even slower than before. I guess I just don't have enough memory and will have to continue using Docker without taking advantage of wsl2.Tope
I found that limiting memory via .wslconfig like this made a huge difference to Docker's performance. Without it Docker seems to use as many resources as it can. Limiting Docker to memory=6GB on my 16GB machine has made working with Docker much better. The optimum setting will probably depend on available RAM and what you're doing with Docker, but I'd guess that setting it to (quite a bit!) more than 500MB would probably be sensible in many cases!Velure
This adjustment also made a huge difference for me. Vmmem was consuming all available CPU on my machine while compiling a program during docker build. My machine was literally unresponsive for hours while the compilation ground to a standstill, had to kill -9 the docker processes. After setting memory and processors each to half of what is available on my system, the same build was completed in ~10 mins. Thanks!Sunfish
In my case vmmem process was not stopping by itself. It finally stopped when I executed wsl.exe --shutdownJetton
@Thezozozolino L thx for the infor however when system starts I see System.InvalidOperationException: Failed to deploy distro docker-desktop to C:\Users\usen_name\AppData\Local\Docker\wsl\distro: exit code: -1 stdout: The system cannot find the path specified. How to fix this.Bilbao
swap=0 might help too.Pamela
After stopping Docker, I had to run wsl --shutdown for Vmmem to close. It does not terminate automatically. See superuser.com/questions/1559170/…Mitosis
B
47

You probably have your code stored on the Windows machine in a folder similar to this...

C:\\Users\YourName\projects\blahfu

But you are using Docker on WSL 2 which is a different (Linux) filesystem. So, when you do a Docker build all of the code/context gets copied from the Windows filesystem to Linux filesystem and then from there to the Docker container. This is what takes the most time and is incredibly slow.

Try to put your project into a folder like this...

/home/YouName/projects/blahfu

You should get quite a performance boost.

Bahrain answered 23/7, 2020 at 13:33 Comment(15)
I'm not sure I understand but in my case I have a Linux container with an Oracle Database and all of the data is within the container itself.Tope
@Tope During development you should mount your source code in the docker container (if you don't want to destroy/create your container on every code change)...but you're talking about the db, right!? if the data directory of your database isn't stored locally (within a local mountpoint) it's slow anyway ;)Bahrain
All files are stored in the Linux container and I only access the container via sql*net.Tope
@Andy: Technically, your approach make sense, but idea of WSL is to have the flexibility to work on Windows leveraging power of Linux, and it should take care of performance right. If we are moving all stuff into WSL folder structure, then I doubt.Vanny
@Vanny with their recent updates, Docker said it gave better performances to use WSL2 instead of HyperV. They did not say anything about the use of it, so I understood that it was just more efficient for Docker itself, not especially to work with WSL files or to run Docker inside WSL. If I'm wrong, the communication was unclear, and I'd be curious to know if it's worth switching Docker to WSL2 when you don't use Docker in WSL anyway.Lessee
The official guidance is here: docs.docker.com/docker-for-windows/wsl/#best-practicesBygone
I tried copying the file and update my docker-compose file with the new local /home path but this the apache container stopped working. It's empty. Kind of the source files get not copied over to the apache conainer. What could that be ?Jadajadd
I'm not sure I'm following. I'm using docker to scrape terabytes of data off various internet services onto my external drive. How would I store all that in the Linux filesystem? Wouldn't that just download to some virtual location on my C drive (which is less than 1 terabyte)?Woodprint
@Woodprint I absolutely don't know what that has to do with this topic at all!? Are you doing actual development on the scraper code while scraping these tons of data!? I doubt that. It's a development case here. Hopefully nobody ever is running that for production use!Bahrain
@Bahrain The topic is docker being slow on Windows. Your "solution" is to move everything.. to Linux. So I think my confusion is very much warranted. So what do you do in production? Go back to mounting to the host and everything being slow again?Woodprint
@Woodprint On production I don't use Windows....simple as that. Noone wants to use a windows server. And yes: On production you're mounting a storage. Let it be a gluster or S3 or what else. It#s a windows problem. It has nothing to do with the mount in the docker container. P.S. I don#t have that problem anymore as I can now use a desktop linux for work, too.Bahrain
@Bahrain in other words, your workaround (wouldn't call it a solution) is specific to Linux users (i.e. a minority). Those who use Windows are SOL.Woodprint
The facepalm is strong with this one. If you use a Desktop Linux you don't need WSL. Please have a look at the answer of @akauppi. That's all you need to now. Over and out ;)Bahrain
Moved the code base from Windows Drive to WSL directory, ran docker build, 10x faster!Castellany
Yes @Bahrain it was the case! Thank you a lot for this solution! I moved my project into /home/ directory on ubuntu wsl and got more than 10x speed increase!Perspicacity
O
22

wsl container have they proper filesystem isolated from the windows filesystem. The base idea is to copy your source code from windows file systeme to wsl file systeme.

from window you can acces the wsl container and copy your project to a wslcontainer :

navigate with explorer to \\wsl$

rebuild the container from this location this will do the trick !

Orphrey answered 14/11, 2020 at 1:34 Comment(8)
I do not understand. Could you elaborate on your comment?Tope
As I already mentioned in here, the complete database including all the data files is stored in the container itself and there is no mounted windows file system at all.Tope
ok, so, your computer run windows 10 because you ask about wsl2, right ? so when you say "the data files is stored in the container itself and there is no mounted windows file system at all" the question is where is stored your docker-compose.yml file and all other file that define you docker container ? this fils cant be in the docker container because there is no container without them. so i guess this file from who you made you docker compose up is on your windows fs, right ? yes?-> migrate them to wsl No?->i supose they are already in wsl, so other thing that make docker slowOrphrey
Yes, I'm running on Windows 10 and asking about wsl2 but I'm not sure I understand the other comments. In my specific case the container itself is docker run from an image that is build on a different computer and does contain all files needed to be executed.Tope
ok, so her we are, the doc say : "docker run image-name : image-name could be a docker image on your local machine[...] " when you run your image build on other computer, you still run an image located on your machine. so the question is where is store this image on your computer?Orphrey
In my local Windows filesystem. So you are referring to the location of the image itself and would suggest starting it from a wls2 subsystem? Correct?Tope
yeap ! exactly ! copy it to the wsl and run it from there ! :)Orphrey
I could not copy anything there - seems to be a special folder, read only.Gail
C
13

If the data for the actual docker container is stored on a windows file system (i.e. NTFS) instead of stored on a native Linux filesystem (regardless of what the docker container contents are, which are likely already Linux based), then I think you are going to see slow performance because you're running WSL and using the docker container from a mounted WINDOWS file system (i.e. /c/mnt/...).

If you copy your docker container to something like /usr/local, or /home/<username>/docker on WSL then you may see a 10x performance INCREASE.

Try that and see if it works?

Chrysotile answered 22/9, 2020 at 22:56 Comment(4)
The complete database including all the datafiles is stored in the container itself and there is no mounted windows file system.Tope
those wsl files are stored in C:\ right? if that so, it will make my C drive quickly to be full since program files etc are also stored there :'(Moorman
apart from copying must i change docker-compose as well ? my files somehow even after changing the docker-compose path are not getting copied to the containersJadajadd
Yes, this is documented here docs.docker.com/desktop/windows/wslChaplet
S
6

you need edit "vmmem" resource just add file .wslconfig in path

C:\Users<yourUserName>.wslconfig

Configure global options with .wslconfig

Available in Windows Build 19041 and later

You can configure global WSL options by placing a .wslconfig file into the root directory of your users folder: C:\Users<yourUserName>.wslconfig. Many of these files are related to WSL 2, please keep in mind you may need to run

wsl --shutdown

to shut down the WSL 2 VM and then restart your WSL instance for these changes to take affect.

Here is a sample .wslconfig file:

Console

Copy
[wsl2]
kernel=C:\\temp\\myCustomKernel
memory=4GB # Limits VM memory in WSL 2 to 4 GB
processors=2 # Makes the WSL 2 VM use two virtual processors

see this https://learn.microsoft.com/en-us/windows/wsl/wsl-config

Stinnett answered 22/4, 2021 at 5:19 Comment(4)
What is the kernel path? How to find it?Calling
you can leave blank if you use default like this [wsl2] memory=4GB # Limits VM memory in WSL 2 to 4 GB processors=3 # Makes the WSL 2 VM use two virtual processorsStinnett
Do you mean C:\Users<yourUserName>.wslconfig or C:\Users\<yourUserName>\.wslconfig?Tijuanatike
sure C:\Users\<yourUserName>\.wslconfigStinnett
L
1

If you are using VS Code, there is a command named "Remote-Containers: Clone Repository in Container Volume..." which assures you have full speed file access.

Form the documentation:

Repository Containers use isolated, local Docker volumes instead binding to the local filesystem. In addition to not polluting your file tree, local volumes have the added benefit of improved performance on Windows and macOS.

Limn answered 21/3, 2021 at 16:43 Comment(0)
M
1

Open your wsl2 distribution (Ubuntu for example) and set the ~/.docker/config.json file.
Only you need to change:

{
  "credsStore": "docker.exe"
}

"credsStore": "desktop.exe" : ultra-slow (over 2 minutes)
"credsStore": "wincred.exe" : fast
"credsStore": "" : fast

It works very well.

Maguire answered 26/1, 2023 at 17:13 Comment(0)
E
1

As mentioned by Claudio above, setting below lines in ~/.docker/config.json of wsl ubuntu server solved the problem for me.

{ 
   "credsStore": "wincred.exe"
} 

Earlier it was taking 5-10 min to build any simple image, now it is done in 1-2 seconds.

Downside: You have to make this change every time you open the server. I have tried every solution mentioned in https://github.com/docker/for-win/issues/9843 to solve this but nothing works for me.

Enrollee answered 14/2, 2023 at 7:40 Comment(0)
A
0

I experienced this issue in Docker on a Windows 2019 Container Host. It was taking over 10 minutes to do a restore that would take about 5 seconds on my own machine. I found out that the MsMgEng.exe (Defender) process was scanning the dockerd.exe (Docker daemon). CPU usage was 98%.

To isolate the issue, run task manager while you're doing a very slow docker build. If it's Defender Real-Time scanning you will see the CPU usage through the roof on the dockerd.exe process. Defender is basically choking the Docker build!

I'm pretty sure it was just the Docker daemon but I also added docker.exe and gitlab-runner.exe on the Processor Exclusion List. The magic of process exclusion is that you don't have to exclude any folders, it will automatically refrain from scanning any folders that the process is dealing with.

And 13-minute restores are a thing of the past! That fixed it. You don't need any special params, conditions or flags on your dotnet restore.

Anguiano answered 8/3, 2023 at 19:10 Comment(0)
H
0

The problem is stated clearly in other answers but what wasn't necessarily clear was how to solve the problem.

First, you need to find the linux filesystem in Windows. You can do that by going to your file explorer and typing "Linux". You'll likely see folders similar to docker-desktop, docker-desktop-data and Ubuntu. I clicked into "Ubuntu" and created a "www" folder at /mnt/wsl/www and created my project folder in there.

Then I restarted Docker and was getting some errors where the volumes weren't being found. I had to go into Docker > Settings > Resources > WSL Integration and enable "Ubuntu" then restart docker.

I also reset docker to the factory default, but I don't think that is a necessary step.

Anyways, it is working for me now and it is like 100X faster than it was.

Please comment if you happen to find that any of my steps are not necessary or if you have any improvements.

Haemo answered 25/9, 2023 at 23:49 Comment(0)
K
0

Spring 2024 is here and things have moved on. Following the link that @ViaTech provided in the comments to the OP, there is another link.

Basically, in Settings, make sure Use the WSL 2 base engine is selected, and in Settings -> Resources -> WSL integration, select enable integration with additional distro, which is Ubuntu 20.04 in my case.

Ubuntu must be started before starting Docker Desktop. Also very important is that your project is in the Ubuntu filesystem. Transfer between the Linux and Windows filesystems is very slow by nature.

I put docker-compose.yml in an Ubuntu dir I can write in, and did docker-compose up -d.

The container will appear in Docker Desktop and you can run it from there. Amazing speed increase.

Kansas answered 23/3 at 11:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.