Summary
The issue stems from Deployer’s cache and lock mechanism.
Deployer stores the resolved composer.lock in the repository and, during deployment, it forcibly restores the exact version recorded there. Updating composer.json without updating the corresponding composer.lock or the cached artifacts leaves Deployer pointing back to the older module version.
Root Cause
composer.lockis not regenerated after thecomposer.jsonchange.- Deployer’s
cache(if “composer-enabled”) pulls the lock file from the repository and does not honour the updatedcomposer.json. - The deployed server still holds the old lock in its vendor directory, causing
composer installto reinstall 1.25.1.
Why This Happens in Real Systems
- Version pinning is required for reproducible builds.
- Deployer pulls the lock file from the repo to guarantee that every environment runs the same code.
- If a developer updates only
composer.json, the lock file becomes stale; subsequent deployments revert to the committed lock state.
Real-World Impact
- Security loopholes: old modules may miss critical patches.
- Feature gaps: newer APIs or bug fixes are unavailable.
- Test failures: CI can pass while production uses an older library.
- Deployment churn: repeated updates create confusion in version history.
Example or Code (if necessary and relevant)
# What you did
composer update path/to/module
# What should happen
git commit composer.lock
git push
# Deployer’s default behaviour
deployer deploy -f deploy.php
Illustration only – no explanation inside code block.
How Senior Engineers Fix It
- Generate a fresh lock file:
composer update path/to/module - Commit the updated
composer.lockto the repository. - Clear Deployer’s cache (if enabled) before deployment:
dep cache:clear --composer - Review the Deployer recipe: ensure it doesn’t force install from a hardcoded lock path.
- Add a pre-deploy hook to enforce lock file integrity.
- Automate lock validation in CI: fail the build if
composer.lockandcomposer.jsonare out of sync.
Why Juniors Miss It
- Assuming
composer updatealone is sufficient without realizing the lock file’s role. - Ignoring Deployer’s cache configuration, thinking it’s unused.
- Lack of familiarity with deployment pipelines that tie source control, lock files, and runtime environments together.
- Overlooking the difference between local dev artifacts and remote production artifacts.
- Missing the audit trail: a junior might not inspect the commit history for related lock file changes.