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

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 (not update) installs exactly the versions in composer.lock, so production matches what you tested. Commit composer.lock to your repository.
  • --no-dev skips 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 — install unzip and php-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/bin isn’t on your PATH, or the install step failed; check ls -l /usr/local/bin/composer.
  • Permission denied writing vendor/ — you’re not the project owner; use sudo -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 set config.platform.php in composer.json.

Next steps: deploy a Laravel app with Laravel on Nginx, or set up PHP itself with installing PHP and MySQL.

  • PHP
  • Composer
  • Linux