Composer is PHP’s dependency manager: it reads composer.json, downloads the libraries your project needs into vendor/, and generates an autoloader. Laravel, Symfony, Drupal and most modern PHP software depend on it. Here’s how to install it properly on a Linux server and use it safely in production.
Prerequisites
PHP CLI with a few extensions, plus unzip (Composer extracts packages much faster with it):
sudo apt update
sudo apt install -y php-cli php-zip php-curl php-mbstring php-xml unzip curl
php -v
Option 1: the official installer (recommended)
The installer is verified against a published checksum so you know it hasn’t been tampered with:
cd /tmp
EXPECTED_CHECKSUM="$(php -r 'copy("https://composer.github.io/installer.sig", "php://stdout");')"
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]; then
echo 'ERROR: Invalid installer checksum'; rm composer-setup.php; exit 1
fi
sudo php composer-setup.php --quiet --install-dir=/usr/local/bin --filename=composer
rm composer-setup.php
composer --version
Composer is now available system-wide as composer.
Option 2: distribution package
sudo apt install composer
Simple, but often a major version or more behind. For current Laravel or Symfony, the official installer is the safer bet.
Don’t run Composer as root
Composer runs scripts defined by packages (post-install-cmd and friends). Running it as root gives every dependency’s scripts root access, and leaves root-owned files the web server can’t manage. Run it as the user who owns the project:
cd /var/www/myapp
sudo -u deploy composer install
If you run it as root anyway, Composer warns: “Do not run Composer as root/super user!”.
Install dependencies for production
composer install --no-dev --optimize-autoloader --no-interaction
install(notupdate) installs exactly the versions incomposer.lock, so production matches what you tested. Commitcomposer.lockto your repository.--no-devskips development packages like test frameworks and debug toolbars.--optimize-autoloader(-o) builds a class map for faster autoloading.
For Laravel, follow with the framework’s caches:
php artisan config:cache
php artisan route:cache
php artisan view:cache
Everyday commands
composer require guzzlehttp/guzzle # add a package
composer require --dev phpunit/phpunit # add a dev-only package
composer remove vendor/package
composer update # update within constraints, rewrite composer.lock
composer update vendor/package # update one package
composer outdated --direct # what's out of date
composer audit # check for known security advisories
composer show -i # installed packages
composer dump-autoload -o # rebuild the autoloader
Run composer update on your development machine, test, commit the new composer.lock, then composer install on the server.
Keep Composer itself updated
sudo composer self-update
composer self-update --rollback # if a new version causes trouble
Memory and performance
Dependency resolution can need a lot of memory on large projects. If you see Allowed memory size … exhausted:
COMPOSER_MEMORY_LIMIT=-1 composer update
That mostly affects update; install from a lock file is light. On a small VPS, running update locally and only install on the server avoids the issue altogether.
Private packages and authentication
For private Git repositories or Packagist mirrors, store tokens outside the project:
composer config --global github-oauth.github.com ghp_xxx
composer config --global http-basic.repo.example.com user token
These go into ~/.composer/auth.json (or ~/.config/composer/auth.json), which should never be committed.
Troubleshooting
The zip extension and unzip/7z commands are both missing— installunzipandphp-zip.Your requirements could not be resolved…— a package needs a newer PHP or a missing extension. Read the message: it lists e.g.requires ext-intl→sudo apt install php-intl.composer: command not found—/usr/local/binisn’t on your PATH, or the install step failed; checkls -l /usr/local/bin/composer.- Permission denied writing
vendor/— you’re not the project owner; usesudo -u <owner>or fix ownership with chown. - Different PHP version for CLI and web —
php -v(CLI) may differ from PHP-FPM; Composer checks the CLI version. Align them or setconfig.platform.phpincomposer.json.
Next steps: deploy a Laravel app with Laravel on Nginx, or set up PHP itself with installing PHP and MySQL.