Кэш пакетов для Composer
Sep 25, 2017 14:54 · 899 words · 5 minute read
При современном подходе к разработке проектов не обойтись без менеджера пакетов — в случаe с разработкой на PHP это Composer. В данной статье пойдёт речь о настройке локального кэша пакетов для Composer.
Решать данную задачу будем с помощью Satis (естественно в docker-контейнере) — давайте разберемся!
Проблема заключается в частой установке одних и тех же пакетов. Каждая новая установка проекта, это обращение к packagist.org для нахождения источников зависимостей вашего пакета, зависимостей зависимостей и т.д. и скачивание необходимых пакетов. Конечно, у Composer есть встроенный кэш, но он хранится в ~/.composer/cache
, индивидуален для каждого пользователя и не доступен для других разработчиков, QA и окружений разработки.
Satis — статическое хранилище Composer пакетов, ультра-легкая версия Packagist, которая также может быть использована для размещения приватных пакетов вашей компании.
Поднимать локальную версию хранилища пакетов будем с помощью docker-контейнера, сам контейнер будет запускаться с помощью файла docker-compose.yml
следующего содержания:
version: "2"
services:
satis:
image: ealebed/satis:1.0
container_name: satis
hostname: satis
volumes:
- "/srv/satis/COMPOSER_CACHE:/root/.composer"
- "/srv/satis/satis.json:/app/config.json"
- "/srv/satis/dist:/satisfy/web/dist"
- "/srv/satis/include:/satisfy/web/include"
environment:
CRONTAB_FREQUENCY: "*/10 * * * *"
VIRTUAL_HOST: satis.lc
ports:
- 3333:3000
- 8181:80
Перед запуском docker-контейнера в каталоге /srv/satis/www
на хост-машине создаем конфигурационный файл satis.json
примерно с таким содержимым:
{
"name": "Satis",
"homepage": "http://satis.lc:8181",
"archive": {
"directory": "dist",
"format": "zip",
"skip-dev": false
},
"repositories": [
{
"type": "composer",
"url": "https://packagist.org"
}
],
"require": {
"league/fractal": "^0.15.0",
"psr/container": "^1.0",
"roave/security-advisories": "dev-master",
"zendframework/zend-component-installer": "^1.0 || ^0.7.0",
"zendframework/zend-config-aggregator": "^0.2.0",
"zendframework/zend-expressive": "^2.0.2",
"zendframework/zend-expressive-fastroute": "^2.0",
"zendframework/zend-expressive-helpers": "^4.0",
"zendframework/zend-http": "^2.6",
"zendframework/zend-log": "^2.9",
"zendframework/zend-servicemanager": "^3.3",
"zendframework/zend-stdlib": "^3.1",
"phpunit/phpunit": "^6.0.8 || ^5.7.15",
"squizlabs/php_codesniffer": "^2.8.1",
"zfcampus/zf-development-mode": "^3.1",
"zendframework/zend-expressive-tooling": "^0.3.2"
},
"require-dependencies": true
}
Здесь:
name:
имя локального хранилища;homepage:
линк по которому будет доступна/srv/satis/web
директория;archive.directory:
путь где будут храниться пакеты;archive.format:
сжимаем пакеты для экономии места;archive.skip-dev:
пропускать ли дев пакеты. Если мы хотим полностью избавиться от зависимости от packagist.org, github, bitbucket и т.д. то ставимfalse
;repositories:
список хранилищ, их может быть несколько. Можно указывать прямые линки пакетов на github и т.д;{ "type": "composer", "url": "https://packagist.org" }:
указываем оригинальное для Composer хранилище пакетов — Packagist;require:
список пакетов кэш которых мы хотим использовать в своих проектах — здесь список значительно сокращен;require-dependencies:
нужно ли скачивать зависимости зависимостей. Опять же, для полной независимости ставимtrue
;
Теперь, находясь в каталоге с конфигурационным файлом docker-compose.yml
выполняем команду:
docker-compose up -d
При первом запуске контейнера будет скачаны и упакованы все зависимости (и их зависимости), указанные в секции "require": { }
. Если их много, то процесс займет довольно продолжительное время, поэтому можно наблюдать за прогрессом с помощью команды:
docker logs -f satis
Пример вывода логов:
...
Dumping 'symfony/dependency-injection'.
Dumping 'symfony/yaml'.
wrote packages to /var/www/mirror/include/all$133181d2d1ff19075832276e1ade0a6499395e5d.json
Writing packages.json
Pruning include directories
Deleted /var/www/mirror/include/all$f77decc941e6a091ed3c3abe89dafd6343a053f3.json
Writing web view
Rather than invoking init scripts through /etc/init.d, use the service(8)
utility, e.g. service cron start
Since the script you are attempting to invoke has been converted to an
Upstart job, you may also use the start(8) utility, e.g. start cron
После скачивания и упаковки зависимостей в браузере открываем адрес, который указывали в homepage
и проверяем список имеющихся пакетов
Теперь в проектах, для которых мы хотим использовать локальное хранилище пакетов, в файле composer.json
вставляем:
{
"repositories": [
{
"type": "composer",
"url": "http://satis.lc:8181"
}
]
}
В таком случае, нужные зависимости сначала будут браться из локального хранилища, а если их там нет — то из packagist.org. Запретить использование официального репозитория пакетов можно добавив такие строки в composer.json
проекта:
{
"repositories": [
{
"type": "composer",
"url": "http://satis.lc:8181"
},
{
"packagist":false
}
]
}
Далее следует очистить индивидуальный кэш Composer и удалить файл composer.lock
, после чего можно протестировать работоспособность созданного хранилища.
Несколько тестов (вывод сокращен).
- Установка зависимостей из официального репозитория packagist.org:
time composer install
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them.
Package operations: 59 installs, 0 updates, 0 removals
- Installing zendframework/zend-component-installer (0.7.1): Downloading (100%)
- Installing league/fractal (0.15.0): Downloading (100%)
...
Generating autoload files
real 2m0.982s
user 0m2.460s
sys 0m0.496s
- Установка зависимостей из локального satis-репозитория:
time composer install
Loading composer repositories with package information
Warning: Accessing satis.lc over http which is an insecure protocol.
Updating dependencies (including require-dev)
Package operations: 60 installs, 0 updates, 0 removals
- Installing zendframework/zend-component-installer (0.7.1): Downloading (100%)
- Installing league/fractal (0.15.0): Downloading (100%)
...
Writing lock file
Generating autoload files
real 0m12.749s
user 0m3.640s
sys 0m1.404s
- Установка зависимостей при недоступном локальном репозитории (попытка подключиться к satis’у, после чего загрузка и установка из официального packagist.org):
time composer install
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Package operations: 60 installs, 0 updates, 0 removals
- Installing zendframework/zend-component-installer (0.7.1): Warning: Accessing satis.lc over http which is an insecure protocol.
Downloading (failed)
Downloading (failed)
Downloading (failed) Failed to download zendframework/zend-component-installer from dist: The "http://satis.lc:8181/dist/zendframework-zend-component-installer-700a22e4791daa1110be06f2fb055dc678d2b7ff-zip-5e33b1.zip" file could not be downloaded: failed to open stream: Connection refused
Now trying to download from source
- Installing zendframework/zend-component-installer (0.7.1): Cloning 700a22e479 from cache
- Installing league/fractal (0.15.0): Downloading (100%)
- Installing zendframework/zend-config-aggregator (0.2.1): Downloading (failed)
Downloading (failed)
Downloading (failed) Failed to download zendframework/zend-config-aggregator from dist: The "http://satis.lc:8181/dist/zendframework-zend-config-aggregator-633a0bf3030a68d2a71cb41a121ad930a52041ea-zip-84656d.zip" file could not be downloaded: failed to open stream: Connection refused
Now trying to download from source
- Installing zendframework/zend-config-aggregator (0.2.1): Cloning 633a0bf303 from cache
...
Generating autoload files
real 5m5.170s
user 0m22.544s
sys 0m4.496s
Также есть возможность обновлять локальный кэш для композера по крону или вручную, больше подробностей и готовый проект есть на github.