composer update spend much time - php

I use Windows 7 operating system. I have a problem when I try to launch command like :
php composer.phar update
15 minutes to launch update and I have a good internet connection (maybe more !). It happen when I use another internet connections.
What happen ?

Composer update can be a slow operation, because it takes a lot of time to resolve dependencies in projects with big dependency graphs. If you open system monitor at some point while composer is updating, you will probably see 100% CPU utilisation on one core at least.
If you have XDebug enabled, disable it because it degrades composer performance significantly.
Whenever you have composer.lock file and you don't actually want to update your project's dependencies, it is best to use composer install, as it will just install versions of libraries defined in composer.lock and will be finished a lot faster.

Related

How to update symfony flex on production [duplicate]

composer install will install whenever stated in the composer.lock file, but composer update will update all the dependencies and create a new composer.lock file based on what is required in composer.json.
So many said only run composer update in development. But my question is doing composer update did replaced the old composer.lock file, if your app is going to break it will break, because there might be conflict with the new updated dependencies.
I came across with a situation where I must do composer update, the issue is related to pcntl extension. The only solution is to do composer update PHP pcntl module installation
I don't understand why people are afraid of running composer update on production.
TLDR;
Do not run composer update nor composer install in production. Execute it somewhere else and upload the result to the production server, but not to the same directory where the application is hosted. As a general rule, you shouldn't modify the application that's being served while it's being served. Create a different copy of the application and when it's ready replace it with the closest to instantaneous command you can (e.g. mv or ln -s).
But if you HAVE to run either: always run install and create a fresh installation; and never update. install is more predictable and reliable, with update you are at the mercy of any of the project's dependencies.
Composer works recursively. So even if you have very tight version constraints in your composer.json, by running composer update you would be updating not only your dependencies, but your dependencies' dependencies.
While most of the time this won't introduce breakage, sometimes it will. One dependency down the line may introduce a change of behaviour that may impact your code in a way you may have not tested against.
Also, it's basically using the wrong tool for the job. Composer is a dependency management tool, not a deployment tool. To deploy your code to production you should be using some sort of code deployment tool (even if that "tool" is as simple as an FTP upload and a couple of scripts).
The appropriate flow is:
Do all the require and update calls on your development machine, where you can test the project without risk. This generates a composer.lock, which is a known state for the whole project, with discrete installed versions.
Create a new installable version doing install --no-dev. On this step you also should dump an optimized autoloader, run after-install scripts, etc. I usually separate this in more than one step:
composer install --prefer-dist --no-scripts --no-progress --no-suggest --no-interaction --no-dev:
^^ This for a complete, silent installation of everything, excluding development dependencies.
composer dump-autoload --optimize --no-dev
^^ To dump an optimized autoloader script suitable for production.
composer run-script --no-dev post-install-cmd
^^ This is mostly for Symfony, but if you have any post-install scripts to run (e.g. to copy assets to your "public" directory, warm-up some type of cache, anything like that), this would be a good moment to do it.
The result of the above step should be tested (in what typically is a staging environment), and then pushed to production whole (your client code, the vendor folder, the configuration tailored for prod, etc); using whatever deployment method you prefer.
Note that if you use any "slow" push method (FTP, copy, rsync, etc), you shouldn't write directly to the application filesystem, but create a fresh copy of the application and once the file transfer is ready, use a quick method to replace "production" with the new release. A popular and effective way is use a symlink as "production" root, so you only need to update the symlink once all of the above is done and ready, without impacting a running application (that otherwise could be temporarily broken, by virtue of suddenly containing files that belong to different versions of the application).
My thoughts about this are,
The current working state of the system is very important as I would assume some tests have been run against it.
To do composer update would mean that, libraries that are part of the app would have their updates and which may lead to breakage in the system. Because they are libraries that depends on libraries that depends on libraries.
Finally, I would rather do this if composer-update is needed:
Checkout on a dev environment and composer update,
Ensure the app is thoroughly tested on a dev environment
then install on live/production with composer install
My thoughts here :
You should never use composer update without argument.
composer update reads every package listed on composer.json, and updates it to the latest available version compatible with the specified version constraints.
In a perfect world, all librairies would follow semver correctly, and it shouldn't have any side effects. But technically, that is never always true, and you could download a version incompatible with the previous one, or just a version with uncorrected bugs.
So, updating all your packages at once would probably lead to some issues, unless you have the time to check everything on your website to ensure nothing went wrong.
But of course, you'll have to update specific packages sometimes, so using composer update xxx/xxx is useful, assuming you'll check all your implementations of the package.
When the updated package is fully tested, you can commit your code to staging/production, and then run composer install to ensure you'll have the same exact version of package and dependencies on all your platforms.
Long story short, here's the process I use :
composer require xxx/xxx to install new packages
composer update xxx/xxx to update a specific package
composer install on all environments when the package.lock file has been updated.
Additional thoughts
I stumbled once upon an implementation which would give the exact version of the package in composer.json. The developer explained that this way you could use composer update without damage.
I disagree with this option, since even with the exact versions in composer.json, the dependencies are not fixed, and a composer update could lead to potential bugs in them.

Uninstall Composer while keeping dependancies

I was wondering if it is possible to use Composer to install dependencies for a script and then uninstall composer, as it is known to be a big RAM hogger.
Would this work?
Thanks
Once the Composer has downloaded the dependencies, it has nothing to do with the them. They remain in your local directory.
I have not personally experienced the RAM hogging of composer. So no idea about that. As far as my knowledge is concerned, composer downloads the dependencies and stops working until it gets another command!
You can feel free to uninstall it after you've got all libraries set in place.

How to stop wasting time updating dependencies with composer?

I am building a small app with some dependencies and my back-end is in PHP with composer and I use many dependencies.
I used to keep the project up-to-date but sometimes, composer update is just to long!
Anyone have some good tips to help me updating my dependencies? any automated service that can run them for me without breaking my code?
I built Dependabot to do exactly this. Every morning it will check with packagist whether there are any new versions, and if there are it will create a pull request to update you to the latest and greatest.
The core of the app is open source here and it's relatively popular with Ruby and JavaScript programmers. The PHP beta is fully functional, and I'm looking for more people to give it a try!
I use prestissimo for a much faster composer update/install process.
It's a composer plugin aka composer global require hirak/prestissimo
and you are done.
It downloads all ur packages simultaneously and installs them!
This will make composer insanely fast.
Benchmark on a Laravel install without prestissimo 288s =>
with prestissimo 26s!!!
For automating ur Process you could set up a cronjob and let it run a bash script with something like this inside:
Filename in example = composer_update.sh. Content:
#!/bin/bash
composer update --no-progress --profile --prefer-stable
For not breaking ur code I recommend setting a minimum stability in ur composer.json
The cronjob for updating once a month could look like this
*/0 0 1 * * /PROJECT_ROOT/composer_update.sh >> update.log
This article might further help you with cron.
Hope I could help you.
I heard a currently work in progress project wanted to solve this issue.
They link to your github account (you must have one in order for this to work) they want to keep your libraries up-to-date if you're using composer, npm or gem I think.
The thing is, they create a pull-request showing you what will be updated and show you the changelog if there is one for the update.
Take a look at upgator.io

Why should I never run 'composer update' in production?

composer install will install whenever stated in the composer.lock file, but composer update will update all the dependencies and create a new composer.lock file based on what is required in composer.json.
So many said only run composer update in development. But my question is doing composer update did replaced the old composer.lock file, if your app is going to break it will break, because there might be conflict with the new updated dependencies.
I came across with a situation where I must do composer update, the issue is related to pcntl extension. The only solution is to do composer update PHP pcntl module installation
I don't understand why people are afraid of running composer update on production.
TLDR;
Do not run composer update nor composer install in production. Execute it somewhere else and upload the result to the production server, but not to the same directory where the application is hosted. As a general rule, you shouldn't modify the application that's being served while it's being served. Create a different copy of the application and when it's ready replace it with the closest to instantaneous command you can (e.g. mv or ln -s).
But if you HAVE to run either: always run install and create a fresh installation; and never update. install is more predictable and reliable, with update you are at the mercy of any of the project's dependencies.
Composer works recursively. So even if you have very tight version constraints in your composer.json, by running composer update you would be updating not only your dependencies, but your dependencies' dependencies.
While most of the time this won't introduce breakage, sometimes it will. One dependency down the line may introduce a change of behaviour that may impact your code in a way you may have not tested against.
Also, it's basically using the wrong tool for the job. Composer is a dependency management tool, not a deployment tool. To deploy your code to production you should be using some sort of code deployment tool (even if that "tool" is as simple as an FTP upload and a couple of scripts).
The appropriate flow is:
Do all the require and update calls on your development machine, where you can test the project without risk. This generates a composer.lock, which is a known state for the whole project, with discrete installed versions.
Create a new installable version doing install --no-dev. On this step you also should dump an optimized autoloader, run after-install scripts, etc. I usually separate this in more than one step:
composer install --prefer-dist --no-scripts --no-progress --no-suggest --no-interaction --no-dev:
^^ This for a complete, silent installation of everything, excluding development dependencies.
composer dump-autoload --optimize --no-dev
^^ To dump an optimized autoloader script suitable for production.
composer run-script --no-dev post-install-cmd
^^ This is mostly for Symfony, but if you have any post-install scripts to run (e.g. to copy assets to your "public" directory, warm-up some type of cache, anything like that), this would be a good moment to do it.
The result of the above step should be tested (in what typically is a staging environment), and then pushed to production whole (your client code, the vendor folder, the configuration tailored for prod, etc); using whatever deployment method you prefer.
Note that if you use any "slow" push method (FTP, copy, rsync, etc), you shouldn't write directly to the application filesystem, but create a fresh copy of the application and once the file transfer is ready, use a quick method to replace "production" with the new release. A popular and effective way is use a symlink as "production" root, so you only need to update the symlink once all of the above is done and ready, without impacting a running application (that otherwise could be temporarily broken, by virtue of suddenly containing files that belong to different versions of the application).
My thoughts about this are,
The current working state of the system is very important as I would assume some tests have been run against it.
To do composer update would mean that, libraries that are part of the app would have their updates and which may lead to breakage in the system. Because they are libraries that depends on libraries that depends on libraries.
Finally, I would rather do this if composer-update is needed:
Checkout on a dev environment and composer update,
Ensure the app is thoroughly tested on a dev environment
then install on live/production with composer install
My thoughts here :
You should never use composer update without argument.
composer update reads every package listed on composer.json, and updates it to the latest available version compatible with the specified version constraints.
In a perfect world, all librairies would follow semver correctly, and it shouldn't have any side effects. But technically, that is never always true, and you could download a version incompatible with the previous one, or just a version with uncorrected bugs.
So, updating all your packages at once would probably lead to some issues, unless you have the time to check everything on your website to ensure nothing went wrong.
But of course, you'll have to update specific packages sometimes, so using composer update xxx/xxx is useful, assuming you'll check all your implementations of the package.
When the updated package is fully tested, you can commit your code to staging/production, and then run composer install to ensure you'll have the same exact version of package and dependencies on all your platforms.
Long story short, here's the process I use :
composer require xxx/xxx to install new packages
composer update xxx/xxx to update a specific package
composer install on all environments when the package.lock file has been updated.
Additional thoughts
I stumbled once upon an implementation which would give the exact version of the package in composer.json. The developer explained that this way you could use composer update without damage.
I disagree with this option, since even with the exact versions in composer.json, the dependencies are not fixed, and a composer update could lead to potential bugs in them.

Composer & composer.lock in GIT and merge conflicts

Here's our situation :
We have 3 different Laravel projects and all 3 projects rely on our Core project.
This Core project is a separate Laravel package hosted on our private repo and is used as a dependency for other projects.
Before, whenever something would change in the Core project we woud just run a composer update ourvendor/ourcorepackage on our servers for each project to pull in the core changes. However as of lately composer seems to suffer from serious memory issues when we try to run the update on our Digital Ocean staging environment with 512 MB Ram. See : https://github.com/composer/composer/issues/1898
The solution I always come across is people saying that you should always run composer install on your production servers. I can relate to that in terms of security because it can be dangerous if you update to a new version of some 3rd party package that can possibly break your code. But in our case we only update our own core package so we know what we're doing but this memory issue forces us to use the composer install method because it is less memory demanding.
So basically this is our current workflow :
When something changes in our core package we need to run a composer
update ourvendor/ourpackage on each project LOCALLY This generates a
composer.lock file
We commit the composer.lock file in our repo
On the servers for each project we run a git pull and run a composer
install. This will only update our core package and runs much faster
and has no memory issues vs composer update
However this solution raises 2 issues :
Since we're working with multiple devs on the same project we sometimes end up having merge conflicts for the composer.lock file when pulling in the changes locally.
Running a git pull on the server gives an error : Your local changes to the following files would be overwritten by merge: composer.lock
Please, commit your changes or stash them before you can merge.
So what am I supposed to do here? Before the pull on the server remove the composer.lock file?
How should we handle the merge conflicts for the composer.lock file?
It's a shame that composer update suffers from memory issues because that method seems much more logical. Just update the package you want and no hassle with the composer.lock file..
Please advice how a correct workflow with GIT and composer should be in our case and how to solve the conflicts above ?
Many thanks for your input
How can you test that a core update (or any other dependency that gets updated) doesn't break things in the projects using it if the developer don't do this step themselves?
That's why the usual workflow is expecting the composer update being run on a development machine having enough RAM (i.e. probably more than 1GB set as memory limit for PHP), and the update should be triggered manually by the developer (and if triggered automatically by a continuous integration build, the memory requirements apply to this machine as well).
There is no way around this memory requirement. A web server with only 512 MB RAM installed might be able to function as a staging server with barely any concurrent users present, but it shouldn't be used to update the Composer dependencies.
Personally I fix the merge conflicts in the composer.lock with a very easy system: Delete the lock file and run composer update. This will update all dependencies to the latest versions that satisfy the version requirements, and create a new working composer.lock file that get's committed during the merge.
I am not afraid to potentially update everything, because either it works as expected, or my tests will catch errors quickly.
I do select the 3rd party packages I use carefully:
they have to tag their versions, preferably using semantic versioning.
I do not use any branches for release versions (the rare occasions that someone used them during development were painful)
they should ship a new major version if they make backwards incompatible changes
the locally developed packages also follow these requirements
This works with around 270 packages served by our local Satis instance (probably also a factor to consider when trying to reduce memory footprint - only the packages known to Composer can end up in memory: Compare the ten thousand packages potentially available on packagist.org with 270 local packages). 60 packages of the 270 are locally developed by 20 developers, and randomly releasing new versions. The update failures in the last 2 years are very rare, and should be handled like other bugs: If a tagged version is detected to be incompatible, we release a bugfix release reverting the change, and tag the original change with a new major release, if the incompatible change is necessary.
So the workflow you ask for is probably like this:
Anytime, any developer should be able to run composer update on their local machine.
They should be able to detect if this breaks things on their local machine.
If nothing is broken, they commit the changes including the composer.lock file to Git
The staging server only runs composer install and will use exactly the versions that the developer used on his machine.
If nothing is broken on staging, that version is ready to be used on production.
Merging an already committed version on another developers machine will likely show merge conflicts with composer.lock.
Resolve conflicts on all other files.
The composer.lock file should be deleted.
From here, the workflow is like above, i.e.:
The developer should be able to run composer update on his local machine.
They should be able to detect if this breaks things on his local machine.
If nothing is broken... and so on.
Another approach (without doing composer update):
Copy your new (and deleted) lines from composer.json into a separate text file.
Use entire remote composer.json and composer.lock files.
During merge conflict mode do:
composer install
For every new package your wrote down in step 1 run composer require vendor/package:version
For every removed package your wrote down in step 1 run composer remove vendor/package
Testing!, Commiting, done!
This method will keep locks from remote branch (maybe master or develop branches), and only updates your new packages.
Sometime composer update can break things.
What I do is.
Discard all of my changes on composer.lock
Merge composer.json
Run composer install so that packages get installed according to composer.lock.
Take one of your package and run composer require vendor/package if you
added that package or composer remove vendor/package if you removed it.
if there are multiple packages it will be installed automatically from composer.json

Categories