Composer resuelve dependencias, y eso requiere memoria y acceso a la red, dos cosas limitadas en el alojamiento compartido. Además descarga código directamente sobre un servidor en producción, que no es donde quieres descubrir que un paquete ha cambiado.

La forma mejor

Resuelve las dependencias donde tengas recursos y envía el resultado. Así el servidor no ejecuta Composer nunca.

# on your machine or in CI
composer install --no-dev --optimize-autoloader --classmap-authoritative
rsync -az --delete vendor/ user@server:/var/www/site/vendor/
  • --no-dev: los marcos de pruebas y los depuradores no pintan nada en producción.
  • --optimize-autoloader: un mapa de clases en vez de consultas al sistema de archivos, y una mejora de velocidad medible.
  • --classmap-authoritative: ninguna llamada stat de reserva. Úsalo solo cuando nada genere clases en tiempo de ejecución.

Si no queda más remedio que ejecutarlo en el servidor

php -d memory_limit=-1 /usr/local/bin/composer install --no-dev --optimize-autoloader

El límite de memoria es el obstáculo habitual. Subirlo solo para esa orden evita subirlo para todo el sitio.

Versiona el archivo de bloqueo, nunca el directorio vendor

composer.lock pertenece a git: es lo que hace idénticas dos instalaciones. El directorio vendor no: engorda el repositorio hasta lo absurdo y vuelve imposibles las fusiones.

Despliega sin ventana rota

Copiar archivos en un directorio en servicio significa que algunas peticiones ven la mitad del código nuevo. Construye en un directorio nuevo y cambia un enlace simbólico: así el cambio es atómico.

ln -sfn /var/www/releases/2026-09-05 /var/www/current
sudo systemctl reload php8.3-fpm       # clear the opcache of the old paths
Recarga PHP-FPM tras un despliegue o opcache seguirá sirviendo el código anterior desde memoria; consulta Qué guarda opcache.