Как правильно выполнить развертывание при использовании коммутатора разработки / производства Composer?

180

Composer имеет возможность загружать несколько зависимостей только в процессе разработки, поэтому инструменты не будут установлены в производственной среде (на работающем сервере). Это (теоретически) очень удобно для сценариев, которые имеют смысл только при разработке, таких как тесты, fake-data-tools, отладчик и т. Д.

Для этого нужно добавить дополнительный require-devблок с инструментами, которые вам нужны в dev:

"require-dev": {
    "codeception/codeception": "1.6.0.3"
}

а затем (теоретически) загрузить эти зависимости через

composer install --dev

Проблема и вопрос:

Composer изменил поведение installи updateв 2013 году резко изменил require-dev-dependencies (!), Не стесняйтесь создавать composer.json с require-devблоком и выполнять composer installвоспроизведение для воспроизведения.

Как наиболее приемлемый способ развертывания, это нажать композитора. Блокировка (которая содержит ваши текущие настройки композитора), а затем выполнить composer installна рабочем сервере, это также установит материал для разработки.

Как правильно развернуть это, не устанавливая зависимости -dev?

Примечание: я пытаюсь создать канонический Q / A здесь, чтобы прояснить странное развертывание Composer. Не стесняйтесь редактировать этот вопрос.

SliQ
источник
@all: Не знаю, где щедрость :( Я начну другой подход.
Sliq
1
Если вы активно не присуждаете его, и ни один ответ не будет принят или получит достаточно голосов, никто не получит награду.
Свен
2
Мне лично этот подход не нравится вообще. composer.lockНикогда не должны быть добавлены в репозиторий Git, НИКОГДА. Правильный подход состоит в том, чтобы использовать обновление композитора при подготовке и затем синхронизировать файл в производство (если все работает, конечно). Постановка должна быть точной копией производственной среды. composer.lockдолжен быть частью .gitignore.
существительное
6
composer.lock обязательно должен быть включен в ваш CSV !!! Как еще вы убедитесь, что все используют одну и ту же версию? Так что НИКОГДА не исключайте composer.lock из вашего CSV !!!
Тобиас Гертнер
3
@TobiasGaertner Я думаю, что вы имеете в виду VCS (программное обеспечение для контроля версий), но в остальном вы правы и согласны с официальными рекомендациями проекта .
Сюн Чиамов

Ответы:

327

Зачем

ИМХО есть веская причина, почему Composer в настоящее время будет использовать этот --devфлаг по умолчанию (при установке и обновлении). Composer в основном запускается в сценариях, где это желаемое поведение:

Основной рабочий процесс Composer выглядит следующим образом:

  • Запущен новый проект: composer.phar install --devфайлы JSON и Lock передаются в VCS.
  • Другие разработчики начинают работать над проектом: проверка VCS и composer.phar install --dev .
  • Разработчик добавляет зависимости:, composer.phar require <package>добавить--dev если хотите, пакет в require-devразделе (и подтвердите).
  • Другие идут вместе: (оформить заказ и) composer.phar install --dev .
  • Разработчик хочет более новые версии зависимостей: composer.phar update --dev <package> (и коммит).
  • Другие идут вместе: (оформить заказ и) composer.phar install --dev .
  • Проект развернут: composer.phar install --no-dev

Как вы можете видеть --dev флаг используется (гораздо) больше, чем --no-devфлаг, особенно когда число разработчиков, работающих над проектом, растет.

Развертывание производства

Как правильно развернуть это без установки зависимостей «dev»?

Ну composer.jsonи composer.lockфайл должен быть зафиксирован в VCS. Не опускайтеcomposer.lock потому что он содержит важную информацию о версиях пакетов, которые следует использовать.

При выполнении производственного развертывания вы можете передать --no-devфлаг Composer:

composer.phar install --no-dev

composer.lockФайл может содержать информацию о Dev-пакетах. Это не важно --no-devФлаг будет убедиться , что эти DEV-пакеты не установлены.

Когда я говорю «развертывание производства», я имею в виду развертывание, нацеленное на использование в производстве. Я не спорю, composer.phar installследует ли делать это на рабочем сервере или на промежуточном сервере, где можно что-то проверить. Это не предмет этого ответа. Я просто указываю, как composer.phar installбез установки "dev" зависимостей.

Не по теме

--optimize-autoloaderФлаг может быть также желателен на производстве (он генерирует класс-карту , которая ускорит самозарядную в приложении):

composer.phar install --no-dev --optimize-autoloader

Или когда автоматическое развертывание выполнено:

composer.phar install --no-ansi --no-dev --no-interaction --no-plugins --no-progress --no-scripts --no-suggest --optimize-autoloader

Если кодовая поддерживает это, вы могли бы поменять --optimize-autoloaderна --classmap-authoritative. Больше информации здесь

Джаспер Н. Брауэр
источник
5
Я согласен с большей частью того, что сказано с одним исключением. "composer install --no-dev" должен выполняться только в промежуточной среде, и эта среда должна считаться неизменной. Я бы не хотел, чтобы какая-либо зависимость загружалась прямо на мой рабочий сервер и без предварительного просмотра / постановки. Это просто дополнительная осторожность.
Масштабируемый
3
@Scalable: Хотя я согласен с вами (и Свен хорошо описывает это в своем ответе), это не сфера моего ответа и не то, что я имел в виду под «производственным развертыванием». Я добавил параграф, чтобы прояснить это.
Джаспер Н. Брауэр
5
На самом деле я думаю, что дефолт должен быть менее опасным вариантом. Установка --dev по умолчанию и случайная установка композитора в производство могут быть фатальными.
Гектор Ордоньес
3
Хороший вопрос в --optimize-autoloader. Также обратите внимание: --classmap-authoritativeиз документации по getcomposer.org/doc/03-cli.md вы можете увидеть это: «Автозагрузка классов только из карты классов. Неявно включает --optimize-autoloader, так что вы можете использовать, если вы знаете, что классы» там ", что, вероятно, должно произойти в вашей среде prod, если вы не генерируете классы динамически.
Хави Монтеро
6
Отличный ответ, я бы предложил добавить optimize-autoloaderпрямо в composer.json:{"config": { "optimize-autoloader": true } }
Иван
79

На самом деле, я очень рекомендую ПРОТИВ установки зависимостей на рабочий сервер.

Моя рекомендация состоит в том, чтобы извлечь код на компьютере развертывания, установить необходимые зависимости (это НЕ включает установку зависимостей dev, если код поступает в производство), а затем переместить все файлы на целевой компьютер.

Зачем?

  • на виртуальном хостинге вы не сможете получить доступ к командной строке
  • даже если вы это сделаете, PHP может быть ограничен с точки зрения команд, памяти или доступа к сети
  • инструменты CLI репозитория (Git, Svn), скорее всего, не будут установлены, что приведет к сбою, если ваш файл блокировки записал зависимость для извлечения определенного коммита вместо загрузки этого коммита в виде ZIP (вы использовали --prefer-source или Composer нет другого способа получить эту версию)
  • если ваша рабочая машина больше похожа на небольшой тестовый сервер (например, на микроэкземпляр Amazon EC2), вероятно, даже недостаточно памяти для выполнения composer install
  • в то время как composer старается ничего не нарушать, как вы относитесь к тому, что заканчиваете частично сломанным рабочим веб-сайтом, потому что некоторая случайная зависимость не может быть загружена во время фазы установки Composers?

Короче говоря: используйте Composer в среде, которой вы можете управлять. Ваша машина разработки действительно подходит, потому что у вас уже есть все, что необходимо для работы Composer.

Как правильно развернуть это, не устанавливая зависимости -dev?

Команда для использования

composer install --no-dev

Это будет работать в любой среде, будь то сам рабочий сервер, или машина развертывания, или машина разработки, которая должна выполнить последнюю проверку, чтобы определить, правильно ли используется какое-либо требование dev для реального программного обеспечения.

Команда не будет устанавливать или активно удалять требования dev, объявленные в файле composer.lock.

Если вы не возражаете против развертывания компонентов программного обеспечения для разработки на производственном сервере, запуск composer installбудет выполнять ту же работу, но просто увеличит количество перемещаемых байтов, а также создаст большее объявление автозагрузчика.

Sven
источник
14
Интересный рабочий процесс, но есть большой минус : репозитории никогда не должны содержать саму папку / содержимое вендора (официальные заявления на странице Composer), поэтому они никогда не будут напрямую отправлены в производство при развертывании на основе git (что является стандартным стандартом на самом деле, поправьте меня если я ошибаюсь). Так что в основном вышеприведенное решение работает только с «старой школой» FTP-развертывания! Пожалуйста, давайте обсудим это дальше ...
Sliq
17
Мой предложенный рабочий процесс не включает передачу кода через GIT на рабочий сервер. Фактически, я бы рекомендовал против, потому что это заставит вас устанавливать зависимости Composer на рабочий сервер, что может вызвать любое количество проблем. Если вы хотите, чтобы развертывание прошло гладко, вам нужно собрать весь код, необходимый для запуска приложения, прежде чем уничтожить текущую версию и заменить ее. Не нравится FTP? RSync через SSH, затем переключите версии, щелкнув символическую ссылку. Но вы также можете push, checkout и composer установить в prod, если хотите.
Свен
2
@Panique: Я только что видел эту часть вашего комментария, и я должен ответить: «подтолкнул к производству в развертывании на основе git (что является стандартным стандартом, поправьте меня, если я ошибаюсь)» - Нет, это это не общий стандарт. Это всего лишь один из способов сделать это.
Свен
1
Команда, в которой я работаю, с большим успехом включила это в свой рабочий процесс. У нас есть машина сборки (конечно, Дженкинс), которая: 1) извлекает из SC 2) запускает установку / обновление композитора 3) запускает модульные тесты 4) удаляет зависимости dev 5) генерирует файл phar (и app-1.34.pharт. Д.). Существует отдельный механизм, который уведомляет и решает, когда захватить этот файл, куда передать его и что с ним делать. Некоторые команды предпочитают распаковывать phar, когда он находится на сервере, а некоторые команды запускают его как есть. Это придает большую уверенность стабильности и воспроизводимости наших развертываний.
Джош Джонсон
3
Я согласен на 100% с этим ответом. Composer не должен быть установлен ни на сервере развертывания, ни на git. Предполагается, что серверы непрерывного развертывания / интеграции точно управляют извлечением исходного кода и зависимостей: git pull> composer install> deploy
Eric MORAND
4

Теперь require-devвключен по умолчанию, для локальной разработки вы можете обойтись composer installи composer updateбез --devопции.

Когда вы хотите развернуть в производство, вы должны убедиться, что composer.lockнет пакетов, которые пришли require-dev.

Вы можете сделать это с

composer update --no-dev

Как только вы проверили локально с --no-dev вы можете развернуть все для производства и установки на основе composer.lock. Здесь вам --no-devснова понадобится опция, в противном случае композитор скажет: «Файл блокировки не содержит информацию о require-dev» .

composer install --no-dev

Примечание: будьте осторожны со всем, что может привести к различиям между разработкой и производством! Обычно я стараюсь избегать require-dev везде, где это возможно, поскольку включение инструментов dev не требует больших затрат.

dave1010
источник
1
Это на самом деле неверно в деталях. Нет необходимости проверять composer.lockзависимости dev. Вы просто запустите composer install --no-dev, и вы получите только установленные регулярные зависимости - фактически, Composer также удалит все зависимости dev на этом шаге.
Свен
Если бы в моем локальном компьютере composer.lockбыли зависимости dev (и это могло повлиять на версии пакетов не dev), я бы хотел обновить его, чтобы отразить, как он будет работать. Это также заставляет вас запускаться composer install --no-devв производство, как composer installи ошибка. Технически я думаю, что ты прав; это не обязательно, но это дополнительный уровень безопасности, который мне нравится.
dave1010
Хорошо, демонстрационный сценарий: ваше приложение требует dev/toolи prod/lib:~1.0. Новейшая версия prod / lib - 1.3, но также требуется dev / tool prod/lib:1.1.*. Результат: вы установите версию 1.1.9 (новейшую ветку 1.1.x) и будете использовать ее во время разработки. Я бы сказал, что просто обновлять НЕ безопасно --no-dev, поэтому включите новейшую версию prod / lib 1.3 и предположите, что все работает без тестирования. А может быть, тогда тестирование невозможно из-за отсутствия dev / tool. Я бы предположил, что, поскольку dev / tool не нужен в производственной среде, его не следует развертывать, но тогда программное обеспечение должно использовать prod / lib 1.1.9.
Свен
Если вы используете, --no-devто вам нужно проверить его локально, как я уже упоминал в ответе. Я все еще рекомендовал бы вообще не использовать --no-dev.
dave1010
Итак, в основном вы предлагаете следующее: composer updateзатем сделайте некоторую разработку, затем сделайте composer update --no-dev, затем проведите тестирование релиза, затем перейдите к производству и выполните composer install --no-dev. Две проблемы: 1. Я не могу протестировать релиз без dev-зависимостей, и 2. Я не могу установить, например, с Git на производстве.
Свен
3

На производственных серверах я переименую vendorвvendor-<datetime> , и во время развертывания будет иметь два поставщик каталоги.

Файл cookie HTTP заставляет мою систему выбирать нового поставщика autoload.php , и после тестирования я делаю полностью атомарный / мгновенный переход между ними, чтобы отключить старый каталог поставщиков для всех будущих запросов, а затем удаляю предыдущий каталог несколькими днями позже.

Это позволяет избежать любой проблемы, вызванной кэшем файловой системы, который я использую в apache / php, а также позволяет любому активному PHP-коду продолжать использовать каталог предыдущего поставщика.


Несмотря на другие ответы, рекомендующие против, я лично запускаю composer install на сервере, так как это быстрее, чем rsync из моей области подготовки (виртуальная машина на моем ноутбуке).

Я использую --no-dev --no-scripts --optimize-autoloader. Вы должны прочитать документы для каждого из них, чтобы проверить, подходит ли это для вашей среды.

Абхи Беккерт
источник
2

Я думаю, лучше автоматизировать процесс:

Добавьте файл composer.lock в ваш репозиторий git, убедитесь, что вы используете composer.phar install --no-dev когда вы выпускаете, но на вашем компьютере разработчика вы можете использовать любую команду composer без проблем, это не пойдет на работу, производство будет основывать свои зависимости в файле блокировки.

На сервере вы извлекаете эту конкретную версию или метку и запускаете все тесты, прежде чем заменять приложение. Если тесты пройдены, вы продолжаете развертывание.

Если тест зависит от dev-зависимостей, так как у composer нет зависимости от области действия теста, не слишком элегантное решение может быть выполнением теста с dev-зависимостями ( composer.phar install ), удалить библиотеку вендора, запустить composer.phar install - -по-DEV Опять , это будет использовать кэшированные зависимости, поэтому быстрее. Но это хак, если вы знаете концепцию областей действия в других инструментах сборки

Автоматизируй это и забудь обо всем остальном, иди выпей пива :-)

PS: Как и в комментарии @Sven ниже, не очень хорошая идея не извлекать файл composer.lock, потому что это заставит установку composer работать как обновление composer.

Вы можете сделать это с помощью http://deployer.org/ это простой инструмент.

Джованни Силва
источник
2
Не совершать и проверять composer.lockзаставит composer installдействовать как composer update. Таким образом, версии, которые вы развертываете, не те, с которыми вы разработали. Это может вызвать проблемы (и особенно в свете единственной недавно решенной проблемы безопасности с «заменой» в Composer). Вы никогда не должны запускаться composer updateбез присмотра, не убедившись, что он ничего не сломал.
Свен
1
@ Даже если в этом же комментарии предлагается автоматически запустить модульные тесты перед развертыванием. Но вы правы, лучше в любом случае сохранить файл composer.lock.
Джованни Силва
Теперь единственное, что вам нужно объяснить: как вы запускаете тесты на сервере без таких dev-зависимостей, как PHPUnit?
Свен
Было бы очень хорошо, если бы зависимости, тесты и развертывание были объединены в одном инструменте, таком как Java Gradle или SBT или даже Maven (maven не так хорош). Один инструмент PHP, который позволяет компоновщику phpunit и развертыванию работать вместе. Или даже плагин Gradle или Scala SBT, чтобы сделать это, так как они являются независимыми инструментами сборки, плагин может даже работать с такими активами, как сведение к минимуму javascript и компиляция sass, сведение к минимуму css. Кто-то что-то знает?
Джованни Силва
1
Конечно, это делается на сервере, чтобы проверить реальную среду, но не напрямую на сайте vhost, вы можете поместить его в отдельную временную папку и переместить результат в vhost, если это удастся
Джованни Сильва,