Independent comparison · no paid rankings
Home / Blog / Composer in production: installing dependencies without surprises
Guide

Composer in production: installing dependencies without surprises

`composer install` in prod is not `composer update`. Lock file, `--no-dev`, optimised autoloader and aligned PHP CLI avoid the classic 500 after deploy.

4 min read Updated Jul 19, 2026

Deploy succeeded. Then a 500 error: class not found. Someone ran composer update directly on the server, CLI PHP is 8.1 while PHP-FPM runs 8.2, and the lock file was not committed. Composer in production is not a live package manager — it is a reproducible installer from a frozen lock validated upstream.

This scene repeats weekly on Laravel, Symfony and custom PHP projects. The good news: the correct path is a handful of simple rules. The bad news: one exception is enough to turn deployment into a lottery.

install vs update: the golden rule

The distinction between composer install and composer update is not syntactic — it separates two worlds.

CommandWhere to runEffect
composer updateLocal or dev CIRecalculates versions from composer.json
composer installBuild CI or productionReproduces the committed lock exactly
install --no-devProductionExcludes require-dev dependencies
install -o / --optimize-autoloaderProductionOptimised PSR autoloader for performance

composer update in production is drawing lots for the versions that will break checkout tonight.

In development you update deliberately, test, commit the new lock. In production you install what was already validated — nothing more, nothing less.

Option A — CI build, artifact deploy. CI runs composer install --no-dev -o then tests. It archives the release (code plus vendor, or vendor separately). Production extracts the artifact and restarts services — without running Composer on the live server. Prefer this as soon as traffic or team size exceeds one person.

Option B — Composer on the server. Pull an immutable Git tag, run composer install --no-dev -o --no-interaction, then migrations, cache clear and PHP-FPM reload. Acceptable for small projects, but fragile if server memory is limited or the network is unstable.

Common production pitfalls

CLI PHP differs from PHP-FPM: a missing extension on the command line blocks install or generates an autoloader incompatible with the web runtime.

Insufficient memory: large Symfony or Laravel projects consume hundreds of megabytes during install. Plan CI or adequate memory limits.

Wrong permissions: a vendor folder writable by the web user becomes a security hole.

Dev package leakage: forgetting --no-dev exposes PHPUnit or other tools if web config is loose.

Platform config: config.platform.php in composer.json aligns dependency resolution with the target version even when the local machine is newer.

What the host must allow

Check that Composer 2.x is available over SSH, CLI PHP matches PHP-FPM, Git or a deploy hook is accessible, and memory suffices for install — or that the host accepts artifact deploy without server-side Composer.

For post-Composer steps, see our Symfony and Laravel in production guides.

The climax: Composer freezes, it does not decide in prod

Decide and move forward without blind spots

Commit composer.lock to the repo and treat any change like code to be tested. Configure CI to run composer install --no-dev -o followed by tests before any deploy. Align CLI PHP and PHP-FPM on the same version and extensions. Prefer artifact deploy as soon as traffic or team size justifies it. Document the exact production command so nobody improvises an update on a Friday evening.

Frequently asked questions

Should you run composer update in production?

No — run install from a committed lock.

Why --no-dev in prod?

Reduces attack surface and vendor size.

Should composer.lock be versioned?

Yes for applications.

composer install memory error?

CI build or COMPOSER_MEMORY_LIMIT.


In production, Composer repeats — it does not improvise. If the lock is missing, so is reliable deployment.

Compare European hosts

Filter by compliance, location and use case — then open the sheets to verify the real scope.

Browse the directory
Blog

Related reading

All articles →