Руководство по обновлению Magento 2.3.x

Введение

Когда вы управляете магазином электронной коммерции, важно оставаться в безопасности и быть в курсе событий. Вы всегда должны следить за последней версией Magento 2 и своевременно обновлять ее. Целью данной статьи является обзор возможных вариантов обновлений и ошибок, с которыми вы можете столкнуться.

Пример, описанный в данной статье подойдет для обновления версий Magento 2.3.x

Сейчас наиболее современными версиями Magento являются релизы Magento 2.3.x (Источник 1). Каждый такой выпуск сопровождается полным описанием дополнений, доработок и выгодных для вас улучшений. Пример, приложенный в данной статье, описывает обновление до последней доступной на момент написания статьи версии Magento 2.3.5-p1 (Источник 2).

Важно: всегда делайте резервную копию ваших файлов и базы данных, прежде чем пытаться выполнить обновление. Также рекомендуется делать обновление на отдельной копии магазина, а затем уже заливать обновленную и протестированную версию на рабочий сервер. С такой сложной платформой, как Magento 2, вы не можете предвидеть, что обновление пройдет успешно. Многое может пойти не так. У вас всегда должна быть возможность восстановить систему.

Обновление Magento 2

Существует 3 варианта обновления системы Magento 2:

  1. С использованием Composer и терминала
  2. С помощью мастера веб-установки
  3. С помощью загрузки версии вручную (не рекомендуется)

Поскольку наиболее предпочтителен вариант обновления через Composer, второй и третий варианты рассмотрим обзорно.

 

Обновление через Composer

Composer - менеджер зависимостей для PHP. Он может помочь обновить магазин с минимальными хлопотами. Инструкция по его установке представлена в источнике 3.

Рассмотрим применение Composer на примере. Текущая версия магазина: 2.3.2. Желаемая версия магазина: 2.3.5-p1.

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

Весь процесс обновления можно рассмотреть в нескольких шагах:

1. Переключитесь в режим технического обслуживания, это можно сделать командой:

php bin/magento maintenance:enable

2. Запросите информацию о последних доступных версиях Magento:

composer show magento/product-community-edition 2.3.* --all | grep -m 1 versions

3. Заставьте Composer использовать последнюю версию (замените 2.3.5-p1 на самую новую):

composer require magento/product-community-edition=2.3.5-p1 --no-update

Если вы используете Magento 2 commerce, команда будет немного другой:

composer require magento/product-enterprise-edition=2.3.5-p1 --no-update

4. Обновите Composer, заставив его загрузить новую версию и обновить все файлы:

composer update

Применение первых четырех шагов выглядит следующим образом:

После завершения 4го шага можем убедиться, что обновилось много файлов системы:

В файле composer.json теперь отмечена новая версия:

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

6. После успешного обновления и коммита нужно запустить две команды, обновление базы данных и компиляция:

php bin/magento setup:upgrade

php bin/magento setup:di:compile

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

7. В случае успешного завершения команд, отключите режим обслуживания и запустите реиндекс:

php bin/magento maintenance:disable

php bin/magento indexer:reindex

После успешного завершения 7-го пункта, можно загружать магазин и тестировать его на возможные проблемы. Их обзор так же можно посмотреть в вышеупомянутом пункте статьи.

Номер текущей версии можно посмотреть на главной странице админки сайта:

 

Обновление с помощью мастера веб-настройки

В Magento 2 есть пункт меню в разделе System => Tools, называемый «Web Setup Wizard». Вы можете использовать его для установки расширений, купленных через Magento Marketplace, или для обновления Magento до новых версий.

Здесь нужно выбрать соответствующий пункт обновления и далее действовать по инструкции.

В начале обновления Magento попросит предоставить учетные данные. Их можно получить по ссылке https://marketplace.magento.com/customer/accessKeys/ (Источник 1). Следует помнить: имя пользователя - открытый ключ, а пароль - закрытый.

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

 

Обновление с помощью загрузки версии вручную

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

Для этого необходимо загрузить последнюю версию Magento 2 с официального сайта Magento, и разархивировать ее в основной папке magento. Это перезапишет основные файлы системы.

Затем запустите:

php bin/magento setup:upgrade

php bin/magento setup:di:compile

php bin/magento maintenance:disable

php bin/magento indexer:reindex

Обновление сделано.

Возможные проблемы

 

1. Обновление входных параметров в методах дочерних классов

Зачастую с обновлением версии Magento 2 необходимо обновлять сторонние модули.

Например, на шаге исполнения команды php bin/magento setup:upgrade может возникнуть такая проблема:

Текст ошибки: Warning: Declaration of Amasty\BannersLite\Model\BannerImageUpload::moveFileFromTmp($imageName) should be compatible with Magento\Catalog\Model\ImageUploader::moveFileFromTmp($imageName, $returnRelativePath = false) in /var/www/app/code/Amasty/BannersLite/Model/BannerImageUpload.php on line 76

Данная проблема возникает в стороннем модуле Amasty_BannersLite. Метод moveFileFromTmp класса Amasty\BannersLite\Model\BannerImageUpload принимает один аргумент, тогда когда его родительский метод теперь принимает два аргумента. Наличие одинаковых точных значений аргумента по умолчанию также важно.

Метод moveFileFromTmp класса Amasty\BannersLite\Model\BannerImageUpload:

<?php
namespace Amasty\BannersLite\Model;
class BannerImageUpload extends \Magento\Catalog\Model\ImageUploader
{
    public function moveFileFromTmp($imageName)
    { ... }
}

Метод moveFileFromTmp класса Magento\Catalog\Model\ImageUploader:

<?php
namespace Magento\Catalog\Model;
use Magento\Framework\File\Uploader;
class ImageUploader
{
    public function moveFileFromTmp($imageName, $returnRelativePath = false)
    { ... }
}

Поскольку это сторонний модуль, есть 3 варианта решения ситуации:

  1. Обновить модуль, если вышло обновление для 2.3.5
  2. Отключить модуль, если он не используется и исправить ошибку вручную, чтобы при компиляции не появлялась ошибка вновь
  3. Написать разработчикам модуля с вопросом о совмещении версии с 2.3.5

Во время нашего обновления был выбран вариант 2. Модуль отключили, а его код поправили:

<?php
namespace Amasty\BannersLite\Model;
class BannerImageUpload extends \Magento\Catalog\Model\ImageUploader
{
    public function moveFileFromTmp($imageName, $returnRelativePath = false)
    { ... }
}

 

2. Can’t create directory

Данная ошибка может также возникнуть на шаге исполнения php bin/magento setup:upgrade.

Текст ошибки: Fatal error: Uncaught exception 'MagentoFrameworkExceptionLocalizedException' with message 'Can't create directory /var/www/html/site/var/generation/Magento/Framework/App/ResourceConnection/.' in /var/www/html/site/vendor/magento/framework/Code/Generator.php:103 Stack trace: #0 /var/www/html/site/vendor/magento/framework/Code/Generator/Autoloader.php(35): MagentoFrameworkCodeGenerator->generateClass('MagentoFramewo...') #1 [internal function]: MagentoFrameworkCodeGeneratorAutoloader->load('MagentoFramewo...') #2 [internal function]: spl_autoload_call('MagentoFramewo...') #3 /var/www/html/site/vendor/magento/framework/Code/Reader/ClassReader.php(19): ReflectionClass->__construct('MagentoFramewo...') #4 /var/www/html/site/vendor/magento/framework/ObjectManager/Definition/Runtime.php(44): MagentoFrameworkCodeReaderClassReader->getConstructor('MagentoFramewo...') #5 /var/www/html/site/vendor/magento/framework/ObjectMana in /var/www/html/site/vendor/magento/framework/Code/Generator.php on line 103`

В этом случае нужно убедиться, что у текущего пользователя есть права на запись в папках pub/static и var. Права на запись можно задать командой:

chmod 755 var pub/static

 

3. Обновление конструктора у дочерних классов

Не реже чем сторонние требуют обновления и свои модули.

Например, шаге компиляции (комада bin/magento setup:di:compile), мы столкнулись с такой ошибкой:

Текст ошибки: Astrio\CustomerPhone\Rewrite\Magento\Customer\Controller\Account\CreatePost Incompatible argument type: Required type: \Magento\Customer\Api\CustomerRepositoryInterface. Actual type: \Magento\Framework\Data\Form\FormKey\Validator; File: /var/www/app/code/Astrio/CustomerPhone/Rewrite/Magento/Customer/Controller/Account/CreatePost.php

Причина проблемы в том, что в одном из написанных к тому времени модулей есть класс CreatePost, наследуемый \Magento\Customer\Controller\Account\CreatePost. Он имеет конструктор. С обновлением magento обновился класс \Magento\Customer\Controller\Account\CreatePost и его конструктор. Соответственно система требует обновить конструктор и нашего класса.

Таким образом, решением данной проблемы стало добавление в конструктор класса еще одного параметра:

 

4. Устаревшие сторонние модули

После успешного обновления базы и компиляции, нужно быть готовым, что в любом месте сайта могут произойти сбои. Например, одной из проблем может стать устаревший сторонний модуль. Например, после обновления Magento на одной из страниц админки произошла такая ошибка:

Текст ошибки: main.ERROR: The URL «http://togas.local/default/dfe-yandex-kassa» is invalid, because the system expects an URL which starts with «https://». [] []

Решением данной проблемы стало выключение модуля dfe-yandex-kassa и обращение к его разработчикам для его обновления до последней версии.

 

5. Доработка темы

Не редкими являются проблемы с темой. Если вы используете стандартную тему Magento, то необходимо заранее удостовериться, что ее версия будет работать в обновленной Magento. Или что разработчики выпустили такой модуль и его можно обновить. В случае, если тему разрабатывали и правили вы сами, то будьте готовы к доработкам. Например в нашем случае при загрузке главной страницы сайта возникла такая ошибка:

Текст ошибки: Uncaught Error: Call to undefined method Astrio\Theme\Rewrite\Magento\Catalog\Plugin\Block\Topmenu::afterGetCacheKeyInfo() in /var/www/vendor/magento/framework/Interception/Interceptor.php:146

Дело в том, что в одном из наших модулей мы ранее переопределили класс Magento\Catalog\Plugin\Block\Topmenu.

C обновлением Magento добавился метод Magento\Catalog\Plugin\Block\Topmenu::afterGetCacheKeyInfo(), а класс Astrio\Theme\Rewrite\Magento\Catalog\Plugin\Block\Topmenu остался прежним.

Простым решением данной проблемы стало добавление нового метода в класс нашего модуля:

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Vendor_OrderDeliveryDate',
    __DIR__
);
<?php
namespace Astrio\Theme\Rewrite\Magento\Catalog\Plugin\Block;
use Magento\Catalog\Model\Category;
use Magento\Framework\Data\Collection;
use Magento\Framework\Data\Tree\Node;
class Topmenu
{
    public function afterGetCacheKeyInfo(\Magento\Theme\Block\Html\Topmenu $subject, array $result)
    {
        ...
    }
}

 

6. Системные проблемы Nginx

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

Веб-сервер, используемый для сайта - Nginx. Его системные логи показали такую ошибку:

Текст ошибки: upstream sent too big header while reading response header from upstream

В нашем случае решением проблемы стала правка конфигурационного файла nginx.conf. В раздел http мы вставили такие строки:

fastcgi_buffer_size 64k;

fastcgi_buffers 16 64k;

proxy_buffer_size 128k;

proxy_buffers 4 256k;

proxy_busy_buffers_size 256k;

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

 

7. Cannot allocate memory error

Если вы столкнулись с этой ошибкой во время обновления, это означает, что недостаточно памяти, выделенной для процессов PHP. Вы не можете безопасно запускать Magento 2 на сервере с менее чем 2 ГБ доступной оперативной памяти. Ваша система должна соответствовать минимальным требованиям к оборудованию. Увеличьте пределы памяти как минимум до 2Гб.

 

8. There are no commands defined in the "setup" namespace

Есть несколько способов исправить ошибку:

  1. Дайте права на запись папкам var и pub: chmod 755 var pub
  2. Проверьте ваши пользовательские модули, убедитесь, что в каждом модуле файл module.xml существует и содержит валидный xml.
  3. Проверьте ваш файл composer.json. Иногда ошибка может привести к тому, что команда обновления Magento2 выдает исключение «no commands defined».

 

Заключение

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

Стоит еще раз отметить основные проблемы, с которыми можно столкнуться:

  1. Отсутствие необходимых разрешений на редактирование папок.
  2. Недостаток оперативной памяти, выделенной для процессов php.
  3. Устаревшие сторонние модули.
  4. Обновление переопределенных в собственном модуле функций.
  5. Обновление переопределенных в собственном модуле классов.

Тем неменее, сейчас достаточно справочного материала для своевременного решения данных проблем и успешного завершения обновления.

Источники

  1. 2.3.x Release Information
  2. Magento Commerce 2.3.5 Release Notes
  3. Install Magento using Composer
  4. Get your authentication keys