Мы все любим Composer. Он значительно изменил способ как мы создаем PHP приложения, основываясь на маленьких и повторно используемых компонентах, но это создает новые проблемы, особенно когда мы имеем единую точку отказа (SPO).
Вместе с Satis процесс деплоя может быть сделан надежным с добавлением избыточности во все потенциальные точки отказа (Packagist и Github).
Давайте посмотрим как это работает.
Как работает Composer?
Следующая схема демнстрирует, как работает Composer когда использует Packagist как центральный репозиторий:
Пока мы явно не указываем, что мы хотим использовать другой репозиторий, Composer использует репозиторий по умолчанию: Packagist. Composer будет спрашивать с Packagist информацию обо всех пакетах требуемых в composer.json файле, так и зависимости требуемые этими пакетами. Когда композер получает всю эту информацию, он решает граф зависимостей применяя SAT (прим. : Задача выполнимости булевых формул) алгоритм и генерирует composer.lock файл с определенными пакетами, которые должны быть установлены, чтобы выполнить требования определенные в composer.json файле. В конце концов Composer загружает эти пакеты из разных источников: GitHub, Bitbucket, PEAR или из любых GIT/SVN/Mercurial репозиториев.
Эта архитектура имеет несколько проблем: что произойдет, если Packagist лежит? Ничего не будет работать. Composer не будет иметь возможности решить граф зависимостей. В дополнение к этйо проблеме, что случиться если требуемые пакеты хостятся на GitHub и он сейчас лежит? Так же ничего не сработает. Пакеты не будут загружены, затрагивая вашу разработку и развертывание.
Как мы можем минимизировать все эти проблемы? Путем добавления избыточности. Мы можем создать наш личный репозиторий с Satis, чтобы использовать этот репозиторий вместо (или в дополнение к) Packagist. Следующая схема показывает такую же схему, но с использованием своего репозитория:
Теперь Composer спрашивает наш личный репозиторий об информации о требуемых пакетах, и только в случае, если наш репозиторий не имеет такой информации, спрашивает Packagist. Мы можем даже отключить Packagist и сконфигурировать наш репозиторий загружать все зависимости пакетов, как мы увидим позже. В дополнение, наш репозиторий может загрузить пакеты и выступать как обратный прокси. Таким образом мы больше не зависим от GitHub для загрузки пакетов.
Установка
Мы можем установить Satis используя Composer:
1 2 3 |
composer create-project composer/satis --stability=dev |
Файл конфигурации репозитория
Давайтепритворимся, что мы компания с несколькими разработчиками и все наши проекты нуждаются только в двух зависимостях: компонент Symfony HttpFoundation и Twig. Мы хотим иметь свой репозиторий со всеми версиями (исключая версии в разработке) этих двух пакетов, чтобы не надеяться на GitHub:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
{ "name": "ServerGrove repository", "homepage": "http://149.5.47.251:8001", "repositories": [ { "type": "vcs", "url": "git@github.com:symfony/HttpFoundation.git" }, { "type": "vcs", "url": "git@github.com:twigphp/Twig.git" } ], "require-all": true, "require-dependencies": true, "archive": { "directory": "dist", "format": "tar", "skip-dev": true } } |
Формат файла достаточно простой, но давайте посмотрим что означает каждое поле:
- “name”: имя репозитория.
- “homepage”: URL репозитория.
- “repositories”: содержит список репозиториев, которые мы хотим зазеркалить.
- “require-all”: загрузить все пакеты, а не только отмеченные.
- “require-dependencies”: когда “true”, Satis разрешает и добавляет все зависимости, чтобы Composer не нуждался в использовании Packagist.
- “archive”: файлы “tar” будут сохранены в директории “dist” и “dev” пакеты не будут загружены.
Далее мы говорим Satis собрать репозиторий:
1 2 3 |
./bin/satis build satis.json servergrove-satis/ |
После этого мы имеем новую директорию с названием servergrove-satis, которая содержит два файла: packages.json и index.html. Предшествующий является конфигурационным файлом репозитория, который будет читаться Composer для определения какие пакеты репозиторий предоставляет. Файл index.html просто статический файл с информацией о репозитории. Так же имеется dist директория со всеми пакетами, так что они больше не должны будут загружаться с GitHub.
И в завершение мы публикуем наш репозиторий используя встроенный сервер PHP (для реальных репозиториев рекомендуется использовать Apache или nginx):
1 2 3 |
php -S localhost:8001 -t servergrove-satis/ |
Теперь если мы перейдем на http://localhost:8001/, мы должны увидеть что-то вроде:
Использование репозитория в Composer
Как только мы имеем репозиторий готовый к работе, последний шаг это сообщить Composer, что мы хотим использовать его. Это может быть выполнено с добавлением следующих строк в файл composer.json нашего проекта.
1 2 3 4 5 6 7 8 |
{ "repositories" : [ {"type" : "composer", "url" : "http://localhost:8001/"} ], ... } |
Далее мы выполняем composer install, наш репозиторий должен быть использован:
1 2 3 4 5 6 7 8 9 10 |
composer install Loading composer repositories with package information Installing dependencies (including require-dev) - Installing symfony/http-foundation (v2.6.6) Downloading: 100% Writing lock file Generating autoload files |
Мы должны видеть в файле composer.lock что ссылки для скачивания больше не с GitHub, а с нашего репозитория:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
{ ... "packages": [ { "name": "symfony/http-foundation", "version": "v2.6.6", "target-dir": "Symfony/Component/HttpFoundation", "source": { "type": "git", "url": "https://github.com/symfony/HttpFoundation.git", "reference": "8a6337233f08f7520de97f4ffd6f00e947d892f9" }, "dist": { "type": "tar", "url": "http://localhost:8001/dist/symfony-http-foundation-8a6337233f08f7520de97f4ffd6f00e947d892f9-zip-3c2665.tar", "reference": "8a6337233f08f7520de97f4ffd6f00e947d892f9", "shasum": "04c8f9c294585c8fc982762f5181eab0083fdf3a" } } ... } |
Так же мы можем видеть запросы, которые Composer выполнил в порядке сначала получения репозитория (packages.json includes/include/all$e0f2af5bfe26328fcc97241cbd95de682f4fbfaa.json) и потом самого пакета:
1 2 3 4 5 |
[Wed Apr 29 13:38:56 2015] x.x.x.x:64826 [200]: /packages.json [Wed Apr 29 13:38:56 2015] x.x.x.x:64827 [200]: /include/all$e0f2af5bfe26328fcc97241cbd95de682f4fbfaa.json [Wed Apr 29 13:39:13 2015] x.x.x.x:64839 [200]: /dist/symfony-http-foundation-8a6337233f08f7520de97f4ffd6f00e947d892f9-zip-3c2665.tar |
Больше информации
- Handling private packages with Satis or Toran Proxy
- Using Satis for fast and reliable software deployment
- Satis – Composer repository for your private packages
- Setting Up a Local Mirror for Composer Packages With Satis
Оригинал на английском:
http://blog.servergrove.com/2015/04/29/satis-building-composer-repository/
Это мой перевод. Если вы заметили ошибки или считаете, что какие-то части можно перевести лучше – пишите в комментарии.
От себя:
Satis это отличный инструмент не только в качестве обратного прокси, но и для предоставления своих Composer пакетов внутри компании. Очень легко организовать защиту публичной части, или просто убрать возможность скачивать dist и сделать источник репозиториев (bitbucket) приватным.
Так же я рекомендую к использованию набор иснталляторов пакетов Composer под различные фреймворки и CMS системы – https://github.com/composer/installers.
Вот пример определения пакета для Kohana, обратите внимание на type:
1 2 3 4 5 6 7 8 9 10 |
{ "name": "seyfer/kohana-mpdf", "version": "3.3", "type": "kohana-module", "description": "Kohana module to manage pdf quick and easy", //... } |
Далее в composer.json проекта:
1 2 3 4 5 6 7 8 9 10 11 12 |
//... "extra": { "installer-paths": { "vendor/kohana/modules/{$name}/": [ "type:kohana-module" ] } } } |
Таким обраом все Kohana пакеты будут устанавливаться в vendor/kohana/modules/ и автоматически загружаться оттуда, если это настроено в index.php.
Так же для автоматического билда репозитория через cron я использую следующий bash скрипт, в котором можно жестко задать имя папки:
1 2 3 4 5 6 |
#!/bin/bash cd /var/www/satis/ php bin/satis build satis.json ../packages.site.ru/ |