composer: Composer is not working in vagrant synced folders of a virtual machine
Solution and details
If you experience failed to open stream: No such file or directory or Plugin initialization failed or class not found type of issue, and are using VirtualBox / Vagrant, this is caused by the VirtualBox filesystem being buggy and not allowing access to the files right after they have been written (https://www.virtualbox.org/ticket/8761).
The workaround we implemented is the following:
If Composer:
- runs as user
vagrant - or Composer runs on a Linux machine where lsmod lists vboxguest (virtualbox guest additions)
- or you set the
COMPOSER_RUNTIME_ENVenvironment variable tovirtualbox
then Composer does very short sleep() calls right before plugins are initialized to give the filesystem some time to properly acknowledge the files are there, so that the plugins can be initialized.
Initial issue:
[ErrorException]
md5_file(./coffee.api.php): failed to open stream: No such file or directory
This error is only an example for a lot of different error messages of Composer 2 when using it in the Virtual Machine (Drupal VM, drupalvm.com).
Composer has massive problem with the files in the shared folders (virtualbox).
Is there any new dev version that solves the problems? The problem exists for many years.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 2
- Comments: 57 (24 by maintainers)
Commits related to this issue
- Also attempt working around Vagrant filesystem issues when installing plugins initially, refs #9627 — committed to composer/composer by Seldaek 3 years ago
- Tweak virtualbox detection and improve it by detecting vbox additions, refs #9627 — committed to composer/composer by Seldaek 3 years ago
- Update composer fork (#3) * Include stdout as well as stderr if git stash/diff/.. fails, fixes #9720 * Remove version argument from why and enforce it for why-not command, refs #9693 * Fix comp... — committed to cxsca/cx-composer-cli by davidacmoreira-cx 3 years ago
- Also make sure filesystem is up to date before generating binary links, refs #9627 — committed to composer/composer by Seldaek 3 years ago
According to @rpkamp I used the workaround but had to change the script a little for Laravel Homestead.
I had to create a script
/usr/local/bin/unzipwith such content:And remember you have to give it
chmod +x /usr/local/bin/unzip.Create a file
/usr/local/bin/zipin the VM with the following content:It hijacks
zipon your system so that every time composer executeszipit will execute this script rather than the actualzipprogram. This script will then call the actualzipprogram and then wait for 200ms afterzipfinished so that hopefully in that time changes have been really synced to disk. You can of course play with the0.2to see if any other values works better.0.1did not work for me, but that probably also depends on disk speed (I do have an NVMe SSD, but it’s a few years old, so I’m not sure how that would stack up against a more modern SSD).@LanmanGroup thanks! Sorry I completely messed that up and forgot the install step for plugins, only did it the sleep on update. Anyway please try again with latest
composer self-update --snapshot, if that really doesn’t fix it then maybe I’ll give up.Ok it should detect
vagrantusername orCOMPOSER_RUNTIME_ENVenv var set tovirtualbox, and do a few sleeps that are hopefully strategically-enough placed that they fix the issue without causing too much slowdown.Please try it with
composer self-update --snapshotand let me know if it pans out.@tomaszstrojny’s solution above worked for me (Laravel Homestead project, php7.4, virtualbox and vagrant)
Here it is summarized with more details, for those who need it:
unzip, somewhere. May as well be in the root of your project (where composer.json lives), with:Enter the Vagrant instance:
vagrant sshCopy the script to usr/local/bin (of the Vagrant instance):
sudo cp /path/to/unzip /usr/local/binAllow the file to be executeable, with:
sudo chmod +x /usr/local/bin/unzipTry running
composer installagain, in your site root (still in vagrant ssh)So the problem is Composer! Or not?
@webprogrammierer put your
vendorfolder outside the virtualbox shared folders. That’s the workaround I know of (I’m not using virtualbox myself).I don’t think composer can do anything here. That’s an issue coming from the virtualbox shared folder filesystem, where files are reported as non-existent in PHP filesystem APIs. This issue has been reported to virtualbox since years AFAIK but does not seem to have been fixed. And the faster composer becomes, the more likely it is to trigger this virtualbox issue (which seem to appear when trying to read from the filesystem too soon after writing to it).
@hochleitner https://github.com/composer/composer/commit/8427b6c8ed335a09a7b03e8ee45bd12c788135ad hopefully fixes it for the binaries too. Can you check with
composer self-update --snapshot?My gut says my old issue was also somehow related to my old issue which was about running >=15 (Drupal) Composer installations on a dedicated AWS instance in parallel. So probably this issue is not about Vagrant or Virtualbox, it is more like about parallelism and filesystems. We tried to tweak inode size on the AWS instance but that did not help. The only currently working solution is not sharing Composer cache between those parallel builds, which increases network traffic and kinda eliminates the purpose of Composer package caching. I wonder if this fix would also solve that problem, I may give it once. https://github.com/composer/composer/issues/9568
A workaround and not a solution, but in case anyone reads up to here, and still has problems with VirtualBox shared-filesystem being both slow and unreliable, for apps other than composer:
my goto solution for running php-on-linux on a windows host has been for years to
pros:
cons:
Please beware:
COMPOSER_RUNTIME_ENVnow expectsvirtualboxinstead ofvagrant. But I also added support for lsmod to detect vbox guest additions so it should hopefully not be needed at all to set the environment variable.All this is now part of Composer 2.0.12 which was just released.
@Gamblt you can try to run composer with
COMPOSER_RUNTIME_ENV=vagrantset in the env, likeCOMPOSER_RUNTIME_ENV=vagrant composer installshould do. I am not fully convinced it’s the same issue though as it’s another environment and another error message. Maybe best report this in a new issue and include all the output we request in the issue template.@enursed that’s an unrelated issue, and is due to filesystem performance, to which frankly the only solution is getting rid of your slow filesystem. Please do not side-track this issue.
@LanmanGroup @inverse great to hear the vagrant/vbox issue appears fixed!
@viliusle trying out if my fix helps would be more helpful than asking me if it’s fixed 😉 I don’t have vagrant, I don’t know. I’m just trying to help here.
@webprogrammierer no. the issue is with the shared filesystem of the VM (IIRC, Docker for Windows relies on a VM running Linux and so involves such shared folder).
@phpguru try to write a simple PHP script using
\FilesystemIteratorto iterate over the files in your big folders and count them. I suspect that you might face the same issue than the one faced by composer (but maybe there’s a timing condition involved, as it is not clear whether some files are never synced to the VM or whether they only have a delay before appearing)