How to deploy correctly when using Composer's develop / production switch?
composer-php, deployment, php
Solution
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 the `require-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`
As you can see the `--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
Problem
Composer has the option to load several dependencies only while being in development, so the tools will not be installed in production (on the live server). This is (in theory) very handy for scripts that only make sense in development, like tests, fake-data-tools, debugger, etc. The way to go is to add an additional `require-dev` block with the tools you need in dev: ``` "require-dev": { "codeception/codeception": "1.6.0.3" } ``` and then (theoretically) load these dependencies via ``` composer install --dev ``` Problem & Question: Composer has changed the behaviour of `install` and `update` dramatically in 2013, `require-dev`-dependencies are now installed by default (!), feel free to create a composer.json with a `require-dev` block and perform an `composer install` to reproduce. As the most accepted way to deploy is to push the composer.lock (that holds your current composer setup) and then do an `composer install` on the production server, this will also install the development stuff. What's the correct way to deploy this without installing the -dev dependencies ? Note: I'm trying to create a canonical Q/A here to clarify the weird Composer deployment. Feel free to edit this question.