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_ENV
environment 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/unzip
with such content:And remember you have to give it
chmod +x /usr/local/bin/unzip
.Create a file
/usr/local/bin/zip
in the VM with the following content:It hijacks
zip
on your system so that every time composer executeszip
it will execute this script rather than the actualzip
program. This script will then call the actualzip
program and then wait for 200ms afterzip
finished so that hopefully in that time changes have been really synced to disk. You can of course play with the0.2
to see if any other values works better.0.1
did 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
vagrant
username orCOMPOSER_RUNTIME_ENV
env 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 --snapshot
and 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 ssh
Copy the script to usr/local/bin (of the Vagrant instance):
sudo cp /path/to/unzip /usr/local/bin
Allow the file to be executeable, with:
sudo chmod +x /usr/local/bin/unzip
Try running
composer install
again, in your site root (still in vagrant ssh)So the problem is Composer! Or not?
@webprogrammierer put your
vendor
folder 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_ENV
now expectsvirtualbox
instead 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=vagrant
set in the env, likeCOMPOSER_RUNTIME_ENV=vagrant composer install
should 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
\FilesystemIterator
to 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)