Docker is extremely slow when running Laravel on Nginx container wsl2
Solution 1
It looks like you are mounting your Laravel project in your container. This could result in very poor file I/O if you are mounting these files from your Windows environment to WSL 2, since WSL 2 currently has a lot of problems accessing files that are on the Windows environment. This I/O issue exists as of July 2020, you can find the ongoing status of the issue on Github here.
There are three possible solutions I can think of that will resolve this issue for now.
Disable WSL 2 based engine for docker until the issue is resolved
Since this issue only occurs when WSL 2 tries to access the Windows filesystem, you could choose to disable WSL 2 docker integration and run your containers on your Windows environment instead. You can find the option to disable it in the UI of Docker Desktop here:
Store your project in the Linux filesystem of WSL 2
Again, since this issue occurs when WSL 2 tries to access the mount points of the Windows filesystem under /mnt
, you could choose to store your project onto the Linux filesystem of WSL 2 instead.
Build your own Dockerfiles
You could choose to create your own Dockerfiles and instead of mounting your project, you can COPY
the desired directories into the docker images instead. This would result in poor build performance, since WSL 2 will still have to access your Windows filesystem in order to build these docker images, but the runtime performance will be much better, since it won't have to retrieve these files from the Windows environment everytime.
Solution 2
I experienced the same problem with mysql database requests and responses taking about 8 to 10 seconds for each request/response. The problem definitely relates to the mounting of files between the Windows file system and Windows WSL2. After many days of trying to resolve this issue, I found this post:
https://www.createit.com/blog/slow-docker-on-windows-wsl2-fast-and-easy-fix-to-improve-performance/
After implementing the steps specified in the post, it totally eliminated the problem, reducing database requests/responses to milliseconds. Hopefully this will assist someone experiencing the same issue.
Solution 3
You are running your project on the /mnt/xxx
folder, isn't it?
This is because wsl2 filesystem performance is much slower than wsl1 in /mnt.
If your want a very short solution, it is here. Works on Ubuntu 18.04 and Debian from windows store:
- Go to the docker settings and turn on
Expose daemon on tcp://localhost:2375 without TLS
and turn offUse the WSL 2 based engine
. - Run this command:
clear && sudo apt-get update && \
sudo curl -fsSL https://get.docker.com -o get-docker.sh && sudo sh get-docker.sh && sudo usermod -aG docker $USER && \
sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && sudo chmod +x /usr/local/bin/docker-compose && \
echo "export PATH=\"$PATH:$HOME/.local/bin\"" >> ~/.profile && source ~/.profile && \
echo "export DOCKER_HOST=tcp://localhost:2375" >> ~/.bashrc && source ~/.bashrc && \
printf '[automount]\nroot = /\noptions = metadata' | sudo tee -a /etc/wsl.conf
I wrote the instuction how to integrate the Docker Desktop with WSL 1: https://github.com/CaliforniaMountainSnake/wsl-1-docker-integration
Solution 4
You just move all source project to folder
\\wsl$\Ubuntu-20.04\home\<User Name>\<Project Name>
The speed will be to very fast such run on Linux Native
Before
After
Solution 5
Ok, so i got an interesting fact :))
Running docker on windows without WSL2.
A request has TTFB 5.41s. This is the index.php file. I used die() to check where the time is bigger and i found that if i use die() after terminate, the TTFB becomes ~2.5s.
<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
* @author Taylor Otwell <[email protected]>
*/
define('LARAVEL_START', microtime(true));
require __DIR__.'/../../application/vendor/autoload.php';
$app = require_once __DIR__.'/../../application/bootstrap/app.php';
#die(); <-- TTFB 1.72s
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
$response->send();
#die(); <-- TTFB 2.67s
$kernel->terminate($request, $response);
#die(); <-- TTFB 2.74s
#if there is no die in the file then TTFB is ~6s
Wail Hayaly
Updated on January 03, 2022Comments
-
Wail Hayaly over 2 years
I've updated Windows 10 to 2004 latest version, installed wsl2 and updated it, installed docker, and ubuntu.
When I create a simple index.php file with "Hello World" it's working perfectly ( response: 100-400ms ) but when I added my Laravel project it becomes miserable as it loads for 7sec before performing the request and the response is 4 - 7 seconds😢, even though PHPMyAdmin is running very smoothly ( response: 1 - 2 seconds ).
my docker-compose.yml file:
version: '3.8' networks: laravel: services: nginx: image: nginx:stable-alpine container_name: nginx ports: - "8080:80" volumes: - ./src:/var/www/html - ./nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - php - mysql - phpmyadmin networks: - laravel mysql: image: mysql:latest container_name: mysql restart: unless-stopped tty: true ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: secret SERVICE_TAGS: dev SERVICE_NAME: mysql networks: - laravel phpmyadmin: image: phpmyadmin/phpmyadmin restart: always depends_on: - mysql ports: - 8081:80 environment: PMA_HOST: mysql PMA_ARBITRARY: 1 php: build: context: . dockerfile: Dockerfile container_name: php volumes: - ./src:/var/www/html ports: - "9000:9000" networks: - laravel composer: image: composer:latest container_name: composer volumes: - ./src:/var/www/html working_dir: /var/www/html depends_on: - php networks: - laravel npm: image: node:latest container_name: npm volumes: - ./src:/var/www/html working_dir: /var/www/html entrypoint: ['npm'] artisan: build: context: . dockerfile: Dockerfile container_name: artisan volumes: - ./src:/var/www/html depends_on: - mysql working_dir: /var/www/html entrypoint: ['php', '/var/www/html/artisan'] networks: - laravel
I've been trying to fix this issue for 2 days but couldn't find the answer.
Thanks
-
octagon_octopus almost 4 yearsDid this not happen when you weren't using WSL 2? You could try disabling WSL 2 integration in Docker Desktop and check if the issue still persists. That would at least show whether the problem lies with WSL 2 or not.
-
Wail Hayaly almost 4 yearsI believe it was slightly better with hyper-v (before installing wsl2), but when I run PHPMyAdmin it works perfectly so maybe the problem is within the Laravel files as it asks me for sharing these files every time I build docker-compose.
-
octagon_octopus almost 4 yearsAhh, I maybe see what could be going wrong. Are you mounting your files from the windows file system? It could result in very poor i/o.
-
Wail Hayaly almost 4 yearsSo what should I do?
-
user3529607 over 3 yearsSame issue here. Have you found an answer?
-
Yszty almost 3 yearsSame issue here. Laravel 14sec (mounted from windows) loading vs 500ms(copied to container). In this case we reinvented the wheel. I mounted network drive as file system 15 years ago and had same performance....
-
Luis Cruz almost 3 yearsDid you fix it? How?, please share it
-
-
Wail Hayaly almost 4 yearsTried to copy project files to
mnt/wsl
but failed (can't read from the source file or disk) the same thing when I copy to images containers, I ended up disabling wsl2 and removing ubuntu. :( -
octagon_octopus almost 4 yearsYour WSL filesystem isn't under
mnt/WSL
. It's that entire filesystem itself. -
wasabi over 3 yearsI found the same thing in our project. I have no idea why
die()
does anything but it took our nginx + php stack from 6s per response to 200ms per response. -
user3529607 over 3 yearsCould you please elaborate on "Store your project in WSL 2" How can I do it?
-
octagon_octopus over 3 years@user3529607 Within WSL you have the Linux filesystem (e.g. directory
\\wsl$\Ubuntu-18.04
) and the Windows filesystem as a mount point (e.g.\\wsl$\Ubuntu-18.04\mnt\c
). In a nutshell, place your project files somewhere other than a subdirectory of/mnt/
, otherwise there is a good chance you will place your project files within the Windows filesystem, which is what causes the bad IO. -
xlad over 3 yearsnice, but really sketchy, hope there is another way
-
Dmitry over 3 yearsHow this disabled on windows 10 home?
-
Gul Muhammad about 3 yearsCan some one explain all the above steps in an easy matter/words
-
waterloomatt about 3 yearsPoints 2 and 3 are fine for running applications but what about developing applications on Windows? Do we have to edit, save, and copy the file into the container each time? Sticking with option 1 until they have this resolved.
-
Bechilled about 3 yearsDisable WSL 2 based engine works for me, thanks !
-
octagon_octopus about 3 years@waterloomatt I'm not following completely. Point 2 and 3 shouldn't require you to edit, save and copy files into a container each time. Point 2 is just as simple as moving your project to a different directory and continuing to develop from there, although you will probably need an editor that supports developing in WSL to continue working (e.g. VSCode). Point 3 uses the COPY instruction in your Dockerfile, so you aren't copying files manually.
-
Andrii Sukhoi over 2 yearsDisabling WSL2 works perfectly! Thank you very much!
-
M P over 2 yearsHad to downgrade from wsl2 to wsl1 with hyper-v and spent hours trying various fixes. These are the only instructions that worked. Life saving!
-
Ahmed Sayed Sk over 2 yearsThanks, This solution works for me.
-
Matěj Račinský over 2 yearsI excluded vendor from mounted volumes and it started running fast againg for me. It's a bit pain that I have different vendor in host and inside docker container, but it's good wnough workaround imho.
-
Claudio Ferraro over 2 yearsI copied the files and updated my docker-compose in this way /var/www:/var/web/www:rw but they files seems not to be linked between docker windows and ubuntu. the folder in docker looks to be empty
-
Claudio Ferraro over 2 yearsI tried point 2 , moved the files but after updating my docker-compose file with the new path the files seems to not be visible anymore by windows docker installation and i get an empty folder and cannot execute the project anymore. any hint ?
-
Aarony over 2 yearsDisabling WSL2 docker engine and enabling Hyper-V in windows 10 pro edition, worked for me, thanks. :-)
-
Krol over 2 yearswhy minus :( ???
-
mouchin777 over 2 yearsThis has improved the performarnce greatly. But i also have to limit the memory that docker uses otherwise it eats all the ram and the system goes slow
-
zardoz about 2 yearsi disabled WSL2 in Docker for Windows and got the same effect. 7,5s vs 1,7s. Linux Mint native docker time is 0,8s.
-
Thinh Nguyen about 2 years@zardoz So you don't get a power of wsl