В каких-то проектах Composer запускается пару раз в месяц, а где‑то он крутится в каждом CI job и на каждом деплое. Как только размер vendor переваливает за сотни мегабайт, а composer.lock — за пару тысяч строк, любая просадка по скорости начинает раздражать и разработчиков, и devops.
Особенно хорошо это видно на PHP VDS: диски NVMe есть, CPU есть, память есть — а composer install все равно может тянуться минуты. Ниже разберёмся, как ускорить Composer за счёт:
- умной конфигурации на VDS (PHP, кеши, права);
- использования packagist mirror (локального зеркала);
- оптимизации autoloader (включая «shm»-подход и работу с OPcache/APCu);
- минимизации лишней работы в CI/CD.
Материал ориентирован на админов и devops, которые отвечают за инфраструктуру, а не только за код.
Базовая гигиена Composer на VDS
Прежде чем городить packagist mirror и заморачиваться с «shm»-подходом и кешами, проверьте, что Composer на вашем PHP VDS не тормозит из‑за банальных ошибок.
Проверяем версию Composer и PHP
На старых версиях Composer и PHP вы теряете производительность на ровном месте. На проде и в CI используйте Composer 2.x и актуальную ветку PHP.
composer --version
php -v
Если по историческим причинам в системе живут несколько версий PHP, жёстко привяжите Composer к нужному бинарю через PATH или используйте «обёртку», которая запускает Composer через нужный бинарь (php81, php82 и т.п.). Важно, чтобы Composer работал ровно на той версии PHP, на которой крутится продакшен‑код.
Глобальный кеш Composer
По умолчанию Composer хранит кеш в домашней директории пользователя (например, /home/deploy/.cache/composer или /root/.cache/composer). На VDS это может быть:
- медленный HDD‑том;
- общая директория, к которой нет прав у пользователя деплоя;
- каталог, который чистит
tmpreaperили cron‑скрипты.
Посмотрите, где находится кеш:
composer config --global cache-dir
Если нужно, перенесите его на быстрый локальный диск (NVMe на самом VDS или быстрый локальный том):
composer config --global cache-dir /var/cache/composer
Убедитесь, что у пользователя деплоя есть права на запись в этот каталог, и что он не попадает под агрессивные чистилки временных файлов.
Забудьте про composer update на проде
На боевых серверах и в CI/CD pipeline Composer должен работать строго в режиме install с существующим composer.lock:
composer install --no-dev --optimize-autoloader --classmap-authoritative
composer update оставьте только для локальной разработки и, максимум, для специального job в CI (обновление зависимостей и пуш composer.lock в репозиторий). Это избавит вас от непредсказуемых обновлений пакетов на проде и уменьшит время установки.
Права на vendor и пользователя деплоя
Классическая проблема на многопользовательских VDS — запуск Composer от root. В итоге vendor принадлежит root, а FPM‑пул под веб‑пользователем не может ничего ни обновить, ни удалить.
Лучше практики:
- выполняйте Composer от того же пользователя, под которым работает PHP‑приложение;
- избегайте
sudo composerи любых сценариев, где Composer меняет владельца файлов «за спиной» у CI; - не монтируйте
vendorна медленном NFS, если есть выбор: лучше локальный том на VDS.
packagist mirror: зачем он нужен и когда окупается
Главный узкий момент при работе Composer — это не только дисковый ввод‑вывод, но и сетевой доступ к Packagist и Git‑репозиториям. Если вы часто запускаете Composer на CI, на нескольких VDS или в Kubernetes‑кластере, имеет смысл развернуть packagist mirror или хотя бы HTTP‑кеш.
Что даёт packagist mirror
Локальное зеркало Packagist даёт сразу несколько плюсов:
- уменьшение сетевой задержки (запрос к зеркалу внутри датацентра быстрее, чем до внешнего Packagist);
- снижение зависимости от внешнего интернета (актуально для закрытых контуров и строгих outbound‑правил);
- предсказуемая скорость CI:
composer installперестаёт «гулять» от запуска к запуску; - возможность централизованно кешировать артефакты для многих проектов.
Минус — нужно выделить отдельный VDS (или хотя бы контейнер) и время на первоначальную настройку и репликацию индексных данных Packagist.
Подходы к зеркалированию Packagist
Чаще всего встречаются три подхода:
- HTTP‑прокси/кеш (например, через Nginx с
proxy_cache): быстро стартует, кеширует HTTP‑ответы Packagist. - Специализированный packagist mirror (open source‑решения, которые синхронизируют
packages.jsonи метаданные, а исходники тянут из Git по мере запросов). - Полный внутренний репозиторий (Satis, аналоги Private Packagist) — когда вы не только зеркалируете публичный Packagist, но и храните приватные пакеты.
Для классического проекта на PHP VDS, где главное — ускорить CI и деплой, обычно достаточно HTTP‑кеша или специализированного зеркала. Полный приватный репозиторий нужен, если вы активно публикуете свои пакеты и хотите строгий контроль зависимостей.
Настройка HTTP‑кеша для Packagist
Простейший и очень быстрый вариант — поставить Nginx в режиме обратного прокси к Packagist и включить proxy_cache. Идея:
- На отдельном VDS поднимаете Nginx.
- Настраиваете upstream на Packagist.
- Включаете долговременный кеш
packages*.json,provider-файлов и сопутствующих метаданных. - В проектах прописываете этот сервер через
composer config.
На уровне Composer это выглядит так (URL зеркала — ваш внутренний домен или IP):
composer config --global repos.packagist composer
composer config --global repos.packagist.url packagist-mirror.internal
Даже простая HTTP‑прослойка даёт заметный выигрыш, если у вас десятки запусков Composer в час. Но у подхода есть минус: это всё ещё не настоящий packagist mirror, а просто HTTP‑кеш. При массовой загрузке Git‑репозиториев с GitHub или GitLab вы всё равно будете упираться во внешний интернет.
Если вам интересна именно тонкая настройка кешей и работы с дистрибутивами, загляните в статью про оптимизацию Composer кэша и флага --prefer-dist: подробный разбор кеширования Composer.

Оптимизация Composer autoloader на VDS
Время установки пакетов — только половина картины. Вторая половина — это работа автозагрузчика в рантайме. Неправильно собранный autoloader бьёт по latency каждого запроса PHP‑приложения, особенно на небольших VDS с ограниченным CPU и сетевым хранилищем под код.
Режимы генерации autoloader
Composer умеет генерировать автозагрузчик в разных режимах:
--optimize-autoloader— строит оптимизированную classmap, уменьшая количество обращений к файловой системе;--classmap-authoritative— делает classmap «авторитетной»: если класс не найден в карте, он считается отсутствующим, и Composer не бегает по диску в поисках файлов;--apcu-autoloader— использует APCu для кеширования результатов поиска классов между запросами.
Типичная команда для продакшена на VDS выглядит так:
composer install --no-dev --optimize-autoloader --classmap-authoritative --apcu-autoloader
Обратите внимание: --apcu-autoloader имеет смысл только в FPM/модульном режиме PHP (каждый HTTP‑запрос — новый процесс). Для чисто CLI‑сценариев он почти бесполезен.
Где здесь «shm» и причём тут OPcache/APCu
Строгой опции --shm в Composer нет, но практический «shm autoloader» для PHP — это использование общих областей памяти (shared memory) через OPcache и APCu для хранения:
- кеша байткода (
opcache); - карт классов, маппингов и метаданных (APCu или собственные механизмы фреймворка);
- результатов поиска файлов и пространств имён.
Идея в том, чтобы минимизировать обращения к файловой системе: и Composer, и рантайм автозагрузчика должны работать как можно больше из памяти. На VDS это особенно важно, потому что часто используется сетевое хранилище или облачные диски с более высокой латентностью файловых операций.
Поэтому «shm autoloader» в контексте этой статьи — это набор практик, как сделать так, чтобы:
- композеровский autoloader был максимально оптимизирован (classmap, authoritative);
- чтение карт классов кэшировалось в shared memory (APCu);
- PHP‑код лежал в OPcache и не перечитывался с диска.
Настройка OPcache на PHP VDS
Проверьте, что у вас включен OPcache и он адекватно настроен под размер проекта и количество PHP‑воркеров:
php -i | grep -i opcache
Минимальный адекватный набор для продакшена:
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
Значения зависят от размера проекта: для больших монолитов выделять под OPcache 512 МБ и больше — нормальная практика. Важно, чтобы OPcache не «выселял» скрипты; это сразу бьёт по производительности и сказывается на времени первого запроса после деплоя.
Настройка APCu для автозагрузчика
Чтобы --apcu-autoloader приносил пользу, нужно:
- включить APCu в FPM (и, по желанию, в CLI для воркеров или демонов);
- выделить под него достаточный объём памяти;
- не выставлять слишком агрессивный TTL и не чистить кеш на каждом деплое без необходимости.
Пример настроек:
apc.enabled=1
apc.enable_cli=0
apc.shm_size=128M
apc.ttl=0
apc.gc_ttl=0
apc.entries_hint=4096
После этого Composer‑автозагрузчик сможет складывать в APCu информацию о том, где найти тот или иной класс. Это и есть практическая реализация «shm autoloader» поверх Composer: маппинги и результаты поиска классов оказываются в общей памяти, доступной всем FPM‑воркерам.
Более тонкую настройку TTL и инвалидации APCu в связке с деплоем и автозагрузчиком мы отдельно разбирали в статье про APCu: как правильно настроить APCu и TTL.
Когда использовать classmap-authoritative
Опция --classmap-authoritative ускоряет загрузку, но добавляет ограничения:
- Composer больше не лезет на диск, чтобы поискать классы вне
classmap; - динамически подцепляемые классы (например, через автогенерацию файлов) могут не находиться;
- нужно следить, чтобы
composer dump-autoloadвыполнялся после любых изменений в структуре классов.
На продакшене это обычно не проблема: деплой идёт через CI, который всегда запускает composer install или composer dump-autoload -o. На dev‑окружениях всё проще: можно не использовать authoritative‑режим, чтобы не ловить загадочные Class not found после ручного добавления файлов.

CI/CD: экономим минуты на каждом job
В CI Composer и autoloader — один из главных потребителей времени. На PHP VDS, который используется как runner (GitLab Runner, GitHub Actions self-hosted, Drone и т.п.), можно существенно выиграть по времени job, если грамотно кешировать зависимости и использовать packagist mirror.
Кеш vendor и кеш Composer — это разные вещи
В CI обычно кешируют:
- глобальный кеш Composer (
~/.cache/composerили переопределённый каталог); - директорию
vendorкак артефакт между job или между пайплайнами.
Кеш vendor часто ломается (версии пакетов не совпадают, изменения в composer.lock и т.п.), поэтому он даёт выигрыш только при коротком цикле между билдами. А вот кеш Composer даёт стабильный плюс, особенно вместе с packagist mirror или его HTTP‑кешем.
Пример pipeline с оптимизированным Composer
Условная логика пайплайна может быть такой:
- На VDS‑runner заранее настроен
composer config --global cache-dirна быстрый диск. - В пайплайне кешируете каталог кеша Composer по ключу, завязанному на хэш
composer.lock. - Выполняете
composer install --no-dev --prefer-dist --optimize-autoloader --classmap-authoritative. - Собираете артефакты (в том числе
vendor, если это нужно деплою).
Опция --prefer-dist обычно уменьшает количество Git‑операций, что особенно заметно, когда репозитории большие или лежат на внешних сервисах.
Инкрементальная сборка autoloader
Если у вас монорепозиторий или много модулей, можно разделить Composer‑установку и генерацию autoloader на этапы:
- один job собирает и кеширует
vendor(например, по nightly‑расписанию); - другой job, ближе к деплою, только обновляет autoloader (
composer dump-autoload -o), не перекачивая все зависимости.
Так вы уменьшаете количество полных composer install и ускоряете критический путь деплоя.
Особенности Composer на многопользовательском VDS
Когда один VDS обслуживает несколько проектов или команд, типичная ошибка — запускать Composer от root или от общего пользователя, который владеет всем vendor. Это создаёт проблемы с правами и безопасностью и может вредить производительности из‑за постоянного пересоздания файлов и смены владельцев.
Отдельный системный пользователь на проект
Для каждого проекта имеет смысл завести отдельного UNIX‑пользователя (webapp1, projectX и т.п.):
- Composer работает от этого пользователя;
- PHP-FPM пул запускается от этого же пользователя;
- кеш Composer и
vendorпринадлежат ему же.
Так вы убираете накладные расходы на постоянные chown и chmod и избегаете ситуаций, когда Composer не может обновить кеш или записи в vendor из‑за прав.
Совместный кеш Composer для многих проектов
Если на VDS десятки проектов, можно вынести кеш Composer в общую директорию и дать к ней доступ нескольким пользователям (через группу и umask). Это позволяет делиться скачанными пакетами между проектами, что повышает эффективность:
- не нужно по новой качать один и тот же архив из Packagist;
- CI job для разных репозиториев используют один и тот же локальный кеш.
Но важно правильно настроить права и не забывать о безопасности: не все проекты должны иметь возможность читать чужие auth.json и любые потенциально чувствительные данные.
Диагностика: как понять, где именно тормозит Composer
Чтобы оптимизация была осмысленной, полезно сначала померить, в чём именно проблема — сеть, диск, CPU, PHP или сама конфигурация Composer.
Подробный вывод Composer
У Composer есть режим verbose, который помогает увидеть, на каких шагах тратится время:
composer install -vvv
Обратите внимание на:
- длительные HTTP‑запросы к Packagist и репозиториям;
- медленные Git‑операции (
git clone,git checkout); - время генерации autoloader (особенно с большим количеством классов).
Нагрузочные тесты на VDS
Можно сделать упрощённый тест, чтобы сравнить разные конфигурации Composer и autoloader:
- Развернуть копию проекта на тестовом VDS.
- Очистить кеш Composer и удалить
vendor. - Замерить время
composer installс разными флагами (--prefer-dist,--optimize-autoloaderи т.п.). - Поиграться с настройками OPcache и APCu и повторить замеры.
Также полезно посмотреть системные метрики во время установки: iowait, нагрузку на сеть, использование памяти. Это подскажет, куда именно имеет смысл инвестировать время — в packagist mirror, в улучшение диска на VDS или в тюнинг PHP и кешей.
Практическое резюме
Для devops и админов, которые хотят ускорить Composer и autoloader на PHP VDS, рабочий чек‑лист выглядит так:
- Убедитесь, что используете Composer 2.x и актуальный PHP.
- Вынесите кеш Composer на быстрый диск и включите глобальный кеш.
- Запускайте на проде только
composer installс--no-dev,--optimize-autoloaderи, по возможности,--classmap-authoritative. - Включите OPcache и APCu, выделите им достаточный объём памяти.
- Используйте
--apcu-autoloaderна продакшен‑VDS, чтобы автозагрузчик работал из shared memory. - При большой нагрузке или множестве проектов поднимите packagist mirror или хотя бы HTTP‑кеш для Packagist.
- На CI кешируйте директорию кеша Composer и обдуманно подходите к кешу
vendor. - Для многопользовательского VDS заведите отдельные аккаунты под проекты и не запускайте Composer от root.
Так вы одновременно ускорите сборку, сделаете автозагрузчик ближе к «shm‑идеалу» (максимум работы в общей памяти) и разгрузите сеть и диск на своём VDS.


