How to deploy correctly when using Composer's develop / production switch?
Why
There is IMHO a good reason why Composer will use the --dev
flag by default (on install and update) nowadays. Composer is mostly run in scenario's where this is desired behavior:
The basic Composer workflow is as follows:
- A new project is started:
composer.phar install --dev
, json and lock files are commited to VCS. - Other developers start working on the project: checkout of VCS and
composer.phar install --dev
. - A developer adds dependancies:
composer.phar require <package>
, add--dev
if you want the package in therequire-dev
section (and commit). - Others go along: (checkout and)
composer.phar install --dev
. - A developer wants newer versions of dependencies:
composer.phar update --dev <package>
(and commit). - Others go along: (checkout and)
composer.phar install --dev
. - Project is deployed:
composer.phar install --no-dev
--dev
flag is used (far) more than the --no-dev
flag, especially when the number of developers working on the project grows.Production deploy
What's the correct way to deploy this without installing the "dev" dependencies?Well, the
composer.json
and composer.lock
file should be committed to VCS. Don't omit composer.lock
because it contains important information on package-versions that should be used.When performing a production deploy, you can pass the --no-dev
flag to Composer:
composer.phar install --no-dev
The composer.lock
file might contain information about dev-packages. This doesn't matter. The --no-dev
flag will make sure those dev-packages are not installed.When I say "production deploy", I mean a deploy that's aimed at being used in production. I'm not arguing whether a composer.phar install
should be done on a production server, or on a staging server where things can be reviewed. That is not the scope of this answer. I'm merely pointing out how to composer.phar install
without installing "dev" dependencies.
Offtopic
The --optimize-autoloader
flag might also be desirable on production (it generates a class-map which will speed up autoloading in your application):
composer.phar install --no-dev --optimize-autoloader
Or when automated deployment is done:composer.phar install --no-ansi --no-dev --no-interaction --no-plugins --no-progress --no-scripts --optimize-autoloader
If your codebase supports it, you could swap out --optimize-autoloader
for --classmap-authoritative
. More info here Do you have to run Composer on localhost and on production?
When you setup your project, you add your dependencies into your composer.json file in your local project directory.
Once you have done this, you will need to run composer update. You can also run composer install, however, without a composer.lock file, composer install actually runs composer update.
Composer update goes out and resolves all the dependencies of all the libraries you are using, downloads them to the /vendor directory, creates an autoloader script and generates the composer.lock file.
For your project what you want to do is version your composer.json AND your composer.lock file.
On your production server, you will always run composer install, which insures that the libraries on your production server are the exact same ones you utilized in your development process.
composer install is also a lot faster as it does not have to do all the dependency management work, and can almost always just pull a specific commit#. It doesn't have to look at version strings. Thus is is usually very fast, once a server has already gone through it once.
In development the only time you should run composer update, is when you introduce a new library OR you have an issue where an underlying library has been changed and you know that you need to have composer go out and re-calculate the dependencies. composer update always recalculates and downloads the latest revisions of any library available even if the version level did not change. This means that there is a potential for something to have become broken, necessitating the potential for as full a set of regression tests as you might have available. In short, something having nothing to do with what you're actually changing could have broken, so you only want to introduce the potential for change when you are forced to.
Of course, if you did introduce a new library, you have no choice but to run composer update.
Once you run composer update, your composer.lock file will be updated (as expected) and the production server will pick this up when you run composer install on it.
As others stated, put the vendors in your gitignore. The point is that these are external libraries that you depend on, but that do not belong in your project, and should not be versioned. In the old days some people utilized git submodules, and it's a big PITA you really want to avoid, not to mention that submodules don't address dependencies of the libraries you included.
Is the --no-scripts option enough to account for the security concerns about running composer as root?
Best practice is not to use sudo
for composer commands at all. If you need sudo
for composer, it usually points at your project's file permissions not being setup correctly.
E.g. you should have a non-root user owning the projects directory, and you should run the needed commands as that user, without requiring sudo
. If you need to run as root
, it probably means that you did so in one of your previous runs, and already messed up your file permissions.
(Best practice is also not running install
in production in any case, but at least you are not running update
)
In the rarer cases where you need to run composer
as a superuser, and you are not on a very constrained environment (say, building a Docker image), you should pay attention to the official guidance and not only use --no-scripts
, but also the parameter --no-plugins
, so you are only doing file copying and not executing other scripts.
What are the differences between composer update and composer install?
composer update
composer update
will update your depencencies as they are specified in composer.json
For example, if you require this package as a dependency:
"mockery/mockery": "0.9.*",
and you have actually installed the 0.9.1
version of the package, running composer update
will cause an upgrade of this package (for example to 0.9.2
, if it's already been released)in detail composer update
will:
- Read
composer.json
- Remove installed packages that are no more required in
composer.json
- Check the availability of the latest versions of your required packages
- Install the latest versions of your packages
- Update
composer.lock
to store the installed packages version
composer install
will not update anything; it will just install all the dependencies as specified in the composer.lock
file
In detail:
- Check if
composer.lock
file exists (if not, it will runcomposer update
and create it) - Read
composer.lock
file - Install the packages specified in the
composer.lock
file
composer update
is mostly used in the 'development phase', to upgrade our project packages according to what we have specified in thecomposer.json
file,composer install
is primarily used in the 'deploying phase' to install our application on a production server or on a testing environment, using the same dependencies stored in the composer.lock file created by composer update.
how shall I run a composer update command
As composer update
command can create additional problem to the server hence i have run composer update only for Recurly as a root
composer update recurly/recurly-client
It is important to run the command from the directory where the composer.lock and composer.json files arefor an example if you have several sites under your server and if you run the command as root it may affect other sites as well.
To prevent that first you have to run
cd /home/websitefolder
thencomposer update recurly/recurly-client
This way you can update only single package and it will not affect the rest of your site composer update on PROD server
You should run on local server.
composer update
Next you should test application and add composer.lock
to repository. And on PROD server you should runcomposer install
Related Topics
Using PHP & Curl to Login to My Websites Form
How to Find "Related Items" in PHP
Extend Request Class in Laravel 5
Converting Float Decimal to Fraction
Str_Replace() for Multiple Value Replacement
Check If Youtube and Vimeo-Clips Are Valid
Converting JSON to CSV Format Using PHP
PHP Flush() Not Working in Chrome
Make Script Execution to Unlimited
Upload Progress Using Pure PHP/Ajax
Yii Framework 2.0 Login with User Database
Call to Undefined Function Curl_Init() - with Wamp
Parsing Xml Data Using PHP to Put into MySQL Database
What Is the Correct Format for a Blowfish Salt Using PHP's Crypt