Привет. Я занимаюсь back-end / full-stack разработкой на Magento 2 уже 3.5 года. Все эти годы у меня никак не хватает сил и времени перетащить один свой старый (но всё еще довольно популярный) проект с убогого Web-CMS uWeb на что-то более-менее толковое, поддерживаемое и расширяемое. Идей было много - писать с нуля на Symfony, изучать Drupal и делать на нем, привлекать React JS... Но всё это требует значительных временных затрат и от этих идей приходилось отказываться.

И вот недавно мне в голову пришла другая (совсем уж безумная?) идея: а что если использовать Magento 2 как каркас для моего кастомного проекта, пусть он даже и не E-commerce? Тут конечно на ум приходят вполне логичные возражения - вроде сомнительной эффективности E-commerce CMS для не-магазинов, стрельбы из пушки по воробьям (проект не особо большой), низкой производительности/высоких требований к железу и т. д. Но и теоретические плюсы я для себя в такой разработке вижу:

  • не надо тратить время на изучения нового стека технологий или фреймворка;

  • модульность, грамотно построенная эко-система, наличие наработанных best practices;

  • большое коммьюнити и наличие ответов на практически любые вопросы в интернете.

Ну и на самом деле мне в большей степени даже стало просто интересно, на что способна Magento, и можно ли установить какой-то минимальный набор её пакетов, чтобы использовать её больше как фреймворк, а не как CMS (но и в этом плане тоже - например, модуль админки).

Помню, на одной из конференций по Magento был доклад, в котором разработчик рассказывал о своём опыте максимального облегчения Magento 2 путем отключения всего, что можно отключить. Я же пошел другим путём: моя идея - попытаться не устанавливать то, в чем нет необходимости для запуска сайта. Критерием работоспособности я взял успешную загрузку frontend и backend областей сайта.

Далее расскажу о своём опыте ручной установки пакетов Magento 2 и попытках запуска минимальной необходимой функциональности.

Исходные данные

Имеем Ubuntu 20.04, nginx 1.18.0, PHP-FPM 7.4.22, MariaDB 10.3.30, Composer 2.1.5

Предварительно по стандартной процедуре у меня была установлена версия Magento CE 2.4.2-p1, чтобы видеть, какие настройки используются в composer.json. Разворачивается она очень легко:

composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition <install-directory-name> 

Далее, чтоб было интереснее, я отключил все лишние модули PHP, оставив только указанные в System Requirements :

  • ext-bcmath

  • ext-ctype

  • ext-curl

  • ext-dom

  • ext-gd

  • ext-hash

  • ext-iconv

  • ext-intl

  • ext-mbstring

  • ext-openssl

  • ext-pdo_mysql

  • ext-simplexml

  • ext-soap

  • ext-xsl

  • ext-zip

  • ext-sockets

Можно запасаться попкорном...

Установка пакетов

Итак, создаём проект /var/www/magento-framework-check, запускаем внутри composer init и, вполне логично, получаю первую отсутствующую зависимость - phar, а также, похоже, ошибку связанную с отсутствием расширения dom:

PHP Warning: PHP Startup: Unable to load dynamic library 'xsl.so' (tried: /usr/lib/php/20190902/xsl.so (/usr/lib/php/20190902/xsl.so: undefined symbol: dom_node_class_entry), /usr/lib/php/20190902/xsl.so.so (/usr/lib/php/20190902/xsl.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0 PHP Fatal error: Uncaught Error: Class 'Phar' not found in /usr/local/bin/composer:23 Stack trace: #0 {main} thrown in /usr/local/bin/composer on line 23

Запускаем sudo phpenmod phar dom, перезапускаем сервис PHP-FPM и повторяем команду. Теперь не хватает модуля JSON:

exception

PHP Fatal error: Uncaught Error: Call to undefined function Composer\Json\json_decode() in phar:///usr/local/bin/composer/src/Composer/Json/JsonFile.php:182 Stack trace: #0 phar:///usr/local/bin/composer/src/Composer/Factory.php(313): Composer\Json\JsonFile->validateSchema() #1 phar:///usr/local/bin/composer/src/Composer/Factory.php(616): Composer\Factory->createComposer() #2 phar:///usr/local/bin/composer/src/Composer/Console/Application.php(418): Composer\Factory::create() #3 phar:///usr/local/bin/composer/src/Composer/Console/Application.php(540): Composer\Console\Application->getComposer() #4 phar:///usr/local/bin/composer/src/Composer/Console/Application.php(191): Composer\Console\Application->getPluginCommands() #5 phar:///usr/local/bin/composer/vendor/symfony/console/Application.php(117): Composer\Console\Application->doRun() #6 phar:///usr/local/bin/composer/src/Composer/Console/Application.php(125): Symfony\Component\Console\Application->run() #7 phar:///usr/local/bin/composer/bin/composer(67): Composer\Console\Appli in phar:///usr/local/bin/composer/src/Composer/Json/JsonFile.php on line 182

Fatal error: Uncaught Error: Call to undefined function Composer\Json\json_decode() in phar:///usr/local/bin/composer/src/Composer/Json/JsonFile.php:182 Stack trace: #0 phar:///usr/local/bin/composer/src/Composer/Factory.php(313): Composer\Json\JsonFile->validateSchema() #1 phar:///usr/local/bin/composer/src/Composer/Factory.php(616): Composer\Factory->createComposer() #2 phar:///usr/local/bin/composer/src/Composer/Console/Application.php(418): Composer\Factory::create() #3 phar:///usr/local/bin/composer/src/Composer/Console/Application.php(540): Composer\Console\Application->getComposer() #4 phar:///usr/local/bin/composer/src/Composer/Console/Application.php(191): Composer\Console\Application->getPluginCommands() #5 phar:///usr/local/bin/composer/vendor/symfony/console/Application.php(117): Composer\Console\Application->doRun() #6 phar:///usr/local/bin/composer/src/Composer/Console/Application.php(125): Symfony\Component\Console\Application->run() #7 phar:///usr/local/bin/composer/bin/composer(67): Composer\Console\Appli in phar:///usr/local/bin/composer/src/Composer/Json/JsonFile.php on line 182

Не зря в 8-й вверси его теперь поставляют из коробки. Включаем и наконец генерим JSON:

{
    "name": "taras/magento-framework-check",
    "type": "project",
    "minimum-stability": "stable",
    "require": {}
}

Чтобы не запариваться с неймспейсами, конфигурацией автозагрузчика и т. д., просто копируем остальные поля из JSON'а установленной Magento 2.4.2. Получаем:

{
    "name": "taras/magento-framework-check",
    "type": "project",
    "minimum-stability": "stable",
    "require": {},
    "config": {
        "preferred-install": "dist",
        "sort-packages": true
    },
    "version": "2.4.2-p1",
    "autoload": {
        "exclude-from-classmap": [
            "**/dev/**",
            "**/update/**",
            "**/Test/**"
        ],
        "files": [
            "app/etc/NonComposerComponentRegistration.php"
        ],
        "psr-0": {
            "": [
                "app/code/",
                "generated/code/"
            ]
        },
        "psr-4": {
            "Magento\\": "app/code/Magento/",
            "Magento\\Framework\\": "lib/internal/Magento/Framework/",
            "Magento\\Setup\\": "setup/src/Magento/Setup/",
            "Zend\\Mvc\\Controller\\": "setup/src/Zend/Mvc/Controller/"
        }
    },
    "conflict": {
        "gene/bluefoot": "*"
    },
    "prefer-stable": true,
    "repositories": [
        {
            "type": "composer",
            "url": "https://repo.magento.com/"
        }
    ],
    "extra": {
        "magento-force": "override"
    }
}

Обратите внимание: я исключил разделы require-dev и autoload-dev.

Также нужно создать файла авторизации c кредами для репозитория Magento - auth.json:

{
    "http-basic": {
        "repo.magento.com": {
            "username": "<public>",
            "password": "<private>"
        }
    }
}

Чтобы проверить, что всё работает, запустим composer install. Получаем структуру файлов:

Теперь установим первый пакет. Как известно, основная структура проекта Magento 2 создается пакетом magento/magento2-base. С него и начнем:

composer require magento/magento2-base

$ composer require magento/magento2-base

Using version ^2.4 for magento/magento2-base ./composer.json has been updated Running composer update magento/magento2-base Loading composer repositories with package information Updating dependencies Lock file operations: 65 installs, 0 updates, 0 removals

  • Locking composer/ca-bundle (1.2.10)

  • Locking composer/composer (1.10.22)

  • Locking composer/semver (1.7.2)

  • Locking composer/spdx-licenses (1.5.5)

  • Locking composer/xdebug-handler (1.4.6)

  • Locking container-interop/container-interop (1.2.0)

  • Locking justinrainbow/json-schema (5.2.11)

  • Locking laminas/laminas-code (3.4.1)

  • Locking laminas/laminas-config (2.6.0)

  • Locking laminas/laminas-console (2.8.0)

  • Locking laminas/laminas-crypt (2.6.0)

  • Locking laminas/laminas-di (2.6.1)

  • Locking laminas/laminas-diactoros (1.8.7p2)

  • Locking laminas/laminas-escaper (2.8.0)

  • Locking laminas/laminas-eventmanager (3.3.1)

  • Locking laminas/laminas-filter (2.11.1)

  • Locking laminas/laminas-form (2.15.1)

  • Locking laminas/laminas-http (2.14.3)

  • Locking laminas/laminas-hydrator (2.4.2)

  • Locking laminas/laminas-i18n (2.11.1)

  • Locking laminas/laminas-inputfilter (2.10.1)

  • Locking laminas/laminas-json (2.6.1)

  • Locking laminas/laminas-loader (2.7.0)

  • Locking laminas/laminas-log (2.12.0)

  • Locking laminas/laminas-math (2.7.1)

  • Locking laminas/laminas-modulemanager (2.9.0)

  • Locking laminas/laminas-mvc (2.7.15)

  • Locking laminas/laminas-psr7bridge (0.2.2)

  • Locking laminas/laminas-serializer (2.10.0)

  • Locking laminas/laminas-server (2.9.2)

  • Locking laminas/laminas-servicemanager (2.7.11)

  • Locking laminas/laminas-soap (2.9.0)

  • Locking laminas/laminas-stdlib (3.5.0)

  • Locking laminas/laminas-text (2.7.1)

  • Locking laminas/laminas-uri (2.8.1)

  • Locking laminas/laminas-validator (2.14.5)

  • Locking laminas/laminas-view (2.11.5)

  • Locking laminas/laminas-zendframework-bridge (1.3.0)

  • Locking magento/composer (1.6.0)

  • Locking magento/magento-composer-installer (0.2.1)

  • Locking magento/magento2-base (2.4.2-p1)

  • Locking magento/zendframework1 (1.14.5)

  • Locking monolog/monolog (1.26.1)

  • Locking pelago/emogrifier (v3.1.0)

  • Locking phpseclib/phpseclib (2.0.32)

  • Locking psr/container (1.1.1)

  • Locking psr/http-message (1.0.1)

  • Locking psr/log (1.1.4)

  • Locking seld/jsonlint (1.8.3)

  • Locking seld/phar-utils (1.1.1)

  • Locking symfony/console (v4.4.29)

  • Locking symfony/css-selector (v5.3.4)

  • Locking symfony/event-dispatcher (v4.4.27)

  • Locking symfony/event-dispatcher-contracts (v1.1.9)

  • Locking symfony/filesystem (v5.3.4)

  • Locking symfony/finder (v5.3.4)

  • Locking symfony/polyfill-ctype (v1.23.0)

  • Locking symfony/polyfill-mbstring (v1.23.1)

  • Locking symfony/polyfill-php73 (v1.23.0)

  • Locking symfony/polyfill-php80 (v1.23.1)

  • Locking symfony/process (v5.3.4)

  • Locking symfony/service-contracts (v2.4.0)

  • Locking tedivm/jshrink (v1.3.3)

  • Locking tubalmartin/cssmin (v4.1.1)

  • Locking webimpress/safe-writer (2.2.0) Writing lock file Installing dependencies from lock file (including require-dev) Package operations: 65 installs, 0 updates, 0 removals

  • Installing composer/ca-bundle (1.2.10): Extracting archive

  • Installing composer/semver (1.7.2): Extracting archive

  • Installing composer/spdx-licenses (1.5.5): Extracting archive

  • Installing psr/log (1.1.4): Extracting archive

  • Installing composer/xdebug-handler (1.4.6): Extracting archive

  • Installing psr/container (1.1.1): Extracting archive

  • Installing justinrainbow/json-schema (5.2.11): Extracting archive

  • Installing symfony/polyfill-php80 (v1.23.1): Extracting archive

  • Installing symfony/service-contracts (v2.4.0): Extracting archive

  • Installing symfony/polyfill-php73 (v1.23.0): Extracting archive

  • Installing symfony/polyfill-mbstring (v1.23.1): Extracting archive

  • Installing symfony/console (v4.4.29): Extracting archive

  • Installing symfony/process (v5.3.4): Extracting archive

  • Installing symfony/finder (v5.3.4): Extracting archive

  • Installing symfony/polyfill-ctype (v1.23.0): Extracting archive

  • Installing symfony/filesystem (v5.3.4): Extracting archive

  • Installing seld/phar-utils (1.1.1): Extracting archive

  • Installing seld/jsonlint (1.8.3): Extracting archive

  • Installing composer/composer (1.10.22): Extracting archive

  • Installing magento/magento-composer-installer (0.2.1): Extracting archive

  • Installing container-interop/container-interop (1.2.0): Extracting archive

  • Installing laminas/laminas-zendframework-bridge (1.3.0): Extracting archive

  • Installing laminas/laminas-escaper (2.8.0): Extracting archive

  • Installing laminas/laminas-stdlib (3.5.0): Extracting archive

  • Installing laminas/laminas-hydrator (2.4.2): Extracting archive

  • Installing laminas/laminas-validator (2.14.5): Extracting archive

  • Installing laminas/laminas-servicemanager (2.7.11): Extracting archive

  • Installing laminas/laminas-filter (2.11.1): Extracting archive

  • Installing laminas/laminas-inputfilter (2.10.1): Extracting archive

  • Installing laminas/laminas-loader (2.7.0): Extracting archive

  • Installing laminas/laminas-math (2.7.1): Extracting archive

  • Installing psr/http-message (1.0.1): Extracting archive

  • Installing laminas/laminas-uri (2.8.1): Extracting archive

  • Installing laminas/laminas-http (2.14.3): Extracting archive

  • Installing laminas/laminas-diactoros (1.8.7p2): Extracting archive

  • Installing laminas/laminas-psr7bridge (0.2.2): Extracting archive

  • Installing tubalmartin/cssmin (v4.1.1): Extracting archive

  • Installing tedivm/jshrink (v1.3.3): Extracting archive

  • Installing symfony/event-dispatcher-contracts (v1.1.9): Extracting archive

  • Installing symfony/event-dispatcher (v4.4.27): Extracting archive

  • Installing phpseclib/phpseclib (2.0.32): Extracting archive

  • Installing symfony/css-selector (v5.3.4): Extracting archive

  • Installing pelago/emogrifier (v3.1.0): Extracting archive

  • Installing monolog/monolog (1.26.1): Extracting archive

  • Installing magento/zendframework1 (1.14.5): Extracting archive

  • Installing magento/composer (1.6.0): Extracting archive

  • Installing laminas/laminas-json (2.6.1): Extracting archive

  • Installing laminas/laminas-eventmanager (3.3.1): Extracting archive

  • Installing laminas/laminas-view (2.11.5): Extracting archive

  • Installing laminas/laminas-text (2.7.1): Extracting archive

  • Installing laminas/laminas-code (3.4.1): Extracting archive

  • Installing laminas/laminas-server (2.9.2): Extracting archive

  • Installing laminas/laminas-soap (2.9.0): Extracting archive

  • Installing laminas/laminas-serializer (2.10.0): Extracting archive

  • Installing laminas/laminas-form (2.15.1): Extracting archive

  • Installing laminas/laminas-console (2.8.0): Extracting archive

  • Installing laminas/laminas-mvc (2.7.15): Extracting archive

  • Installing webimpress/safe-writer (2.2.0): Extracting archive

  • Installing laminas/laminas-config (2.6.0): Extracting archive

  • Installing laminas/laminas-modulemanager (2.9.0): Extracting archive

  • Installing laminas/laminas-log (2.12.0): Extracting archive

  • Installing laminas/laminas-i18n (2.11.1): Extracting archive

  • Installing laminas/laminas-di (2.6.1): Extracting archive

  • Installing laminas/laminas-crypt (2.6.0): Extracting archive

  • Installing magento/magento2-base (2.4.2-p1): Extracting archive 47 package suggestions were added by new dependencies, use composer suggest to see details. Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead. Package laminas/laminas-console is abandoned, you should avoid using it. Use laminas/laminas-cli instead. Generating autoload files 37 packages you are using are looking for funding. Use the composer fund command to find out more!

Прекрасно, похоже, всё установилось, структура файлов создалась:

Пробуем запустить bin/magento:

taras@taras-home:/var/www/magento-framework-check$ bin/magento 
PHP Fatal error:  Uncaught Error: Class 'Magento\Framework\Component\ComponentRegistrar' not found in /var/www/magento-framework-check/setup/src/Magento/Setup/registration.php:9
Stack trace:
#0 /var/www/magento-framework-check/app/etc/NonComposerComponentRegistration.php(29): require_once()
#1 [internal function]: Magento\NonComposerComponentRegistration\{closure}()
#2 /var/www/magento-framework-check/app/etc/NonComposerComponentRegistration.php(31): array_map()
#3 /var/www/magento-framework-check/app/etc/NonComposerComponentRegistration.php(34): Magento\NonComposerComponentRegistration\{closure}()
#4 /var/www/magento-framework-check/vendor/composer/autoload_real.php(75): require('/var/www/magent...')
#5 /var/www/magento-framework-check/vendor/composer/autoload_real.php(65): composerRequiref27b5d24f83d64c29deb274744cf45e2()
#6 /var/www/magento-framework-check/vendor/autoload.php(7): ComposerAutoloaderInitf27b5d24f83d64c29deb274744cf45e2::getLoader()
#7 /var/www/magento-framework-check/app/autoload.php(51): include('/var/www/ma in /var/www/magento-framework-check/setup/src/Magento/Setup/registration.php on line 9

Хмм. Оказывается, компонент magento2-base не установил magento-framework, но при этом явно от него зависит. Довольно странно. Чтож, придется поставить его вручную:

taras@taras-home:/var/www/magento-framework-check$ composer require magento/framework
Using version ^103.0 for magento/framework
./composer.json has been updated
Running composer update magento/framework
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - magento/framework[103.0.0, ..., 103.0.2-p1] require symfony/process ~4.4.0 -> found symfony/process[v4.4.0, ..., v4.4.27] but the package is fixed to v5.3.4 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.
    - Root composer.json requires magento/framework ^103.0 -> satisfiable by magento/framework[103.0.0, ..., 103.0.2-p1].

Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.

Installation failed, reverting ./composer.json and ./composer.lock to their original content.

Похоже, у нас небольшие проблемы - установленная для предыдущего модуля версия symfony/process не подходит фреймворку. Ладно, форсируем обновление зависимостей:

taras@taras-home:/var/www/magento-framework-check$ composer require magento/framework --with-all-dependencies
Using version ^103.0 for magento/framework
./composer.json has been updated
Running composer update magento/framework --with-all-dependencies
Loading composer repositories with package information
Updating dependencies
Lock file operations: 16 installs, 1 update, 0 removals
  - Locking colinmollenhour/credis (v1.12.1)
  - Locking colinmollenhour/php-redis-session-abstract (v1.4.4)
  - Locking guzzlehttp/guzzle (6.5.5)
  - Locking guzzlehttp/promises (1.4.1)
  - Locking guzzlehttp/psr7 (1.8.2)
  - Locking laminas/laminas-mail (2.14.1)
  - Locking laminas/laminas-mime (2.8.0)
  - Locking magento/framework (103.0.2-p1)
  - Locking paragonie/random_compat (v9.99.99)
  - Locking ralouphie/getallheaders (3.0.3)
  - Locking ramsey/uuid (3.8.0)
  - Locking symfony/polyfill-intl-idn (v1.23.0)
  - Locking symfony/polyfill-intl-normalizer (v1.23.0)
  - Locking symfony/polyfill-php72 (v1.23.0)
  - Downgrading symfony/process (v5.3.4 => v4.4.27)
  - Locking true/punycode (v2.1.1)
  - Locking wikimedia/less.php (1.8.2)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 16 installs, 1 update, 0 removals
  - Installing colinmollenhour/credis (v1.12.1): Extracting archive
  - Installing guzzlehttp/promises (1.4.1): Extracting archive
  - Installing ralouphie/getallheaders (3.0.3): Extracting archive
  - Installing guzzlehttp/psr7 (1.8.2): Extracting archive
  - Installing wikimedia/less.php (1.8.2): Extracting archive
  - Downgrading symfony/process (v5.3.4 => v4.4.27): Extracting archive
  - Installing paragonie/random_compat (v9.99.99): Extracting archive
  - Installing ramsey/uuid (3.8.0): Extracting archive
  - Installing laminas/laminas-mime (2.8.0): Extracting archive
  - Installing true/punycode (v2.1.1): Extracting archive
  - Installing laminas/laminas-mail (2.14.1): Extracting archive
  - Installing symfony/polyfill-php72 (v1.23.0): Extracting archive
  - Installing symfony/polyfill-intl-normalizer (v1.23.0): Extracting archive
  - Installing symfony/polyfill-intl-idn (v1.23.0): Extracting archive
  - Installing guzzlehttp/guzzle (6.5.5): Extracting archive
  - Installing colinmollenhour/php-redis-session-abstract (v1.4.4): Extracting archive
  - Installing magento/framework (103.0.2-p1): Extracting archive
9 package suggestions were added by new dependencies, use `composer suggest` to see details.
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.
Package laminas/laminas-console is abandoned, you should avoid using it. Use laminas/laminas-cli instead.
Generating autoload files
42 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

Всё в порядке, версия обновилась, все компоненты довольны. Пробуем запуск:

taras@taras-home:/var/www/magento-framework-check$ bin/magento
Constant name is expected.

А вот это уже интересно. В логах ничего. Начинаем дебажить - выясняем, что у нас имеются необъявленные зависимости от Mageno_Store в app/etc/di.xml. Например:

<type name="Magento\Framework\Url">
  <arguments>
    <argument name="session" xsi:type="object">Magento\Framework\Session\Generic\Proxy</argument>
    <argument name="scopeType" xsi:type="const">Magento\Store\Model\ScopeInterface::SCOPE_STORE</argument>
  </arguments>
</type>

Что эти строки там делают и почему тогда модуль не указан в composer.json - непонятно. Вот вам и модульность.

Что ж, будем ставить модуль store вручную. Не уверен, что он мне пригодился бы, но надо признать, что в Magento на скоупы завязано очень многое, и без этого модуля её сложно представить.

composer require magento/module-store
taras@taras-home:/var/www/magento-framework-check$ composer require magento/module-store
Using version ^101.1 for magento/module-store
./composer.json has been updated
Running composer update magento/module-store
Loading composer repositories with package information
Updating dependencies
Lock file operations: 60 installs, 0 updates, 0 removals
  - Locking laminas/laminas-captcha (2.10.0)
  - Locking laminas/laminas-db (2.12.0)
  - Locking laminas/laminas-session (2.11.0)
  - Locking magento/framework-bulk (101.0.0)
  - Locking magento/framework-message-queue (100.4.2)
  - Locking magento/module-asynchronous-operations (100.4.2)
  - Locking magento/module-authorization (100.4.2)
  - Locking magento/module-backend (102.0.2)
  - Locking magento/module-backup (100.4.2)
  - Locking magento/module-bundle (101.0.2)
  - Locking magento/module-captcha (100.4.2)
  - Locking magento/module-catalog (104.0.2-p1)
  - Locking magento/module-catalog-import-export (101.1.2)
  - Locking magento/module-catalog-inventory (100.4.2)
  - Locking magento/module-catalog-rule (101.2.2)
  - Locking magento/module-catalog-url-rewrite (100.4.2)
  - Locking magento/module-checkout (100.4.2)
  - Locking magento/module-cms (104.0.2)
  - Locking magento/module-cms-url-rewrite (100.4.1)
  - Locking magento/module-config (101.2.2)
  - Locking magento/module-contact (100.4.2)
  - Locking magento/module-cron (100.4.2)
  - Locking magento/module-customer (103.0.2-p1)
  - Locking magento/module-deploy (100.4.2)
  - Locking magento/module-developer (100.4.2)
  - Locking magento/module-directory (100.4.2)
  - Locking magento/module-downloadable (100.4.2)
  - Locking magento/module-eav (102.1.2)
  - Locking magento/module-email (101.1.2)
  - Locking magento/module-gift-message (100.4.1)
  - Locking magento/module-import-export (101.0.2)
  - Locking magento/module-indexer (100.4.2)
  - Locking magento/module-integration (100.4.2)
  - Locking magento/module-media-storage (100.4.1)
  - Locking magento/module-msrp (100.4.1)
  - Locking magento/module-newsletter (100.4.2)
  - Locking magento/module-page-cache (100.4.2)
  - Locking magento/module-payment (100.4.2-p1)
  - Locking magento/module-product-alert (100.4.1)
  - Locking magento/module-quote (101.2.2)
  - Locking magento/module-reports (100.4.2)
  - Locking magento/module-require-js (100.4.0)
  - Locking magento/module-review (100.4.2)
  - Locking magento/module-rss (100.4.1)
  - Locking magento/module-rule (100.4.1)
  - Locking magento/module-sales (103.0.2)
  - Locking magento/module-sales-rule (101.2.2)
  - Locking magento/module-sales-sequence (100.4.1)
  - Locking magento/module-security (100.4.2-p1)
  - Locking magento/module-shipping (100.4.2)
  - Locking magento/module-store (101.1.2)
  - Locking magento/module-tax (100.4.2)
  - Locking magento/module-theme (101.1.2)
  - Locking magento/module-translation (100.4.2)
  - Locking magento/module-ui (101.2.2)
  - Locking magento/module-url-rewrite (102.0.1)
  - Locking magento/module-user (101.2.2)
  - Locking magento/module-variable (100.4.0)
  - Locking magento/module-widget (101.2.2)
  - Locking magento/module-wishlist (101.2.2)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 60 installs, 0 updates, 0 removals
  - Installing laminas/laminas-captcha (2.10.0): Extracting archive
  - Installing laminas/laminas-db (2.12.0): Extracting archive
  - Installing laminas/laminas-session (2.11.0): Extracting archive
  - Installing magento/framework-message-queue (100.4.2): Extracting archive
  - Installing magento/module-ui (101.2.2): Extracting archive
  - Installing magento/module-store (101.1.2): Extracting archive
  - Installing magento/module-user (101.2.2): Extracting archive
  - Installing magento/module-theme (101.1.2): Extracting archive
  - Installing magento/module-config (101.2.2): Extracting archive
  - Installing magento/module-wishlist (101.2.2): Extracting archive
  - Installing magento/module-widget (101.2.2): Extracting archive
  - Installing magento/module-tax (100.4.2): Extracting archive
  - Installing magento/module-sales (103.0.2): Extracting archive
  - Installing magento/module-shipping (100.4.2): Extracting archive
  - Installing magento/module-sales-sequence (100.4.1): Extracting archive
  - Installing magento/module-quote (101.2.2): Extracting archive
  - Installing magento/module-backend (102.0.2): Extracting archive
  - Installing magento/module-directory (100.4.2): Extracting archive
  - Installing magento/module-security (100.4.2-p1): Extracting archive
  - Installing magento/module-media-storage (100.4.1): Extracting archive
  - Installing magento/module-catalog (104.0.2-p1): Extracting archive
  - Installing magento/module-eav (102.1.2): Extracting archive
  - Installing magento/module-rule (100.4.1): Extracting archive
  - Installing magento/module-sales-rule (101.2.2): Extracting archive
  - Installing magento/module-require-js (100.4.0): Extracting archive
  - Installing magento/module-variable (100.4.0): Extracting archive
  - Installing magento/module-email (101.1.2): Extracting archive
  - Installing magento/module-cms (104.0.2): Extracting archive
  - Installing magento/module-page-cache (100.4.2): Extracting archive
  - Installing magento/module-newsletter (100.4.2): Extracting archive
  - Installing magento/module-customer (103.0.2-p1): Extracting archive
  - Installing magento/module-authorization (100.4.2): Extracting archive
  - Installing magento/module-integration (100.4.2): Extracting archive
  - Installing magento/module-checkout (100.4.2): Extracting archive
  - Installing magento/module-review (100.4.2): Extracting archive
  - Installing magento/module-gift-message (100.4.1): Extracting archive
  - Installing magento/module-catalog-inventory (100.4.2): Extracting archive
  - Installing magento/module-downloadable (100.4.2): Extracting archive
  - Installing magento/module-reports (100.4.2): Extracting archive
  - Installing magento/module-payment (100.4.2-p1): Extracting archive
  - Installing magento/module-catalog-rule (101.2.2): Extracting archive
  - Installing magento/module-captcha (100.4.2): Extracting archive
  - Installing magento/module-msrp (100.4.1): Extracting archive
  - Installing magento/module-contact (100.4.2): Extracting archive
  - Installing magento/module-bundle (101.0.2): Extracting archive
  - Installing magento/module-rss (100.4.1): Extracting archive
  - Installing magento/module-url-rewrite (102.0.1): Extracting archive
  - Installing magento/module-cms-url-rewrite (100.4.1): Extracting archive
  - Installing magento/module-import-export (101.0.2): Extracting archive
  - Installing magento/module-catalog-url-rewrite (100.4.2): Extracting archive
  - Installing magento/module-catalog-import-export (101.1.2): Extracting archive
  - Installing magento/module-product-alert (100.4.1): Extracting archive
  - Installing magento/module-indexer (100.4.2): Extracting archive
  - Installing magento/framework-bulk (101.0.0): Extracting archive
  - Installing magento/module-asynchronous-operations (100.4.2): Extracting archive
  - Installing magento/module-deploy (100.4.2): Extracting archive
  - Installing magento/module-cron (100.4.2): Extracting archive
  - Installing magento/module-developer (100.4.2): Extracting archive
  - Installing magento/module-translation (100.4.2): Extracting archive
  - Installing magento/module-backup (100.4.2): Extracting archive
34 package suggestions were added by new dependencies, use `composer suggest` to see details.
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.
Package laminas/laminas-console is abandoned, you should avoid using it. Use laminas/laminas-cli instead.
Generating autoload files
45 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

И вот здесь мои глаза начинают округляться. 60 пакетов! 60 пакетов, из которых почти все - модули мадженты, надо поставить, чтобы установить модуль отвечающий за скоупинг - вебсайты и сторы. Впрочем, кто сказал, что он отвечает только за это? Посмотрим readme:

The Store module provides one of the basic and major features of a content management system for e-commerce websites by creating and managing a store for the customers to conduct online-shopping. Stores can be combined in groups,and are linked to a specific website. All store related configurations (currency, locale, scope etc.), management andstorage maintenance are covered under this module.

Это многое объясняет. Похоже, область ответственности этого модуля катастрофически широкая. Но всё же не ясно, почему он не может никак работать например без функциональности Wishlist. В общем, дела плохи - зависимости не в том направлении, дядюшка Боб плачет кровавыми слезами...
Ладно, спишем на legacy, стерпим и продолжим - хотя бы ради интереса.

И в третий раз закинул старик невод...

taras@taras-home:/var/www/magento-framework-check$ bin/magento
PHP Fatal error:  Uncaught Error: Class 'Cm_Cache_Backend_File' not found in /var/www/magento-framework-check/vendor/magento/zendframework1/library/Zend/Cache.php:153
Stack trace:
#0 /var/www/magento-framework-check/vendor/magento/zendframework1/library/Zend/Cache.php(94): Zend_Cache::_makeBackend()
#1 /var/www/magento-framework-check/vendor/magento/framework/App/Cache/Frontend/Factory.php(156): Zend_Cache::factory()
#2 /var/www/magento-framework-check/vendor/magento/framework/Cache/Frontend/Adapter/Zend.php(38): Magento\Framework\App\Cache\Frontend\Factory->Magento\Framework\App\Cache\Frontend\{closure}()
#3 /var/www/magento-framework-check/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php(121): Magento\Framework\Cache\Frontend\Adapter\Zend->__construct()
#4 /var/www/magento-framework-check/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php(66): Magento\Framework\ObjectManager\Factory\AbstractFactory->createObject()
#5 /var/www/magento-framework-check/vendor/magento/framework/ObjectManager/O in /var/www/magento-framework-check/vendor/magento/zendframework1/library/Zend/Cache.php on line 153

Увы, не фартануло - мы явно не в сказке. Идем в полноценную Мадженту, ищем где объявлен этот класс - ставим модуль:

taras@taras-home:/var/www/magento-framework-check$ composer require colinmollenhour/cache-backend-file
Using version ^1.4 for colinmollenhour/cache-backend-file
./composer.json has been updated
Running composer update colinmollenhour/cache-backend-file
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
  - Locking colinmollenhour/cache-backend-file (v1.4.5)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing colinmollenhour/cache-backend-file (v1.4.5): Extracting archive
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.
Package laminas/laminas-console is abandoned, you should avoid using it. Use laminas/laminas-cli instead.
Generating autoload files
45 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

Получаем:

taras@taras-home:/var/www/magento-framework-check$ bin/magento
PHP Fatal error:  Uncaught Error: Class 'PDO' not found in /var/www/magento-framework-check/setup/src/Magento/Setup/Model/ConfigOptionsList.php:180
Stack trace:
#0 /var/www/magento-framework-check/setup/src/Magento/Setup/Model/ConfigModel.php(71): Magento\Setup\Model\ConfigOptionsList->getOptions()
#1 /var/www/magento-framework-check/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php(61): Magento\Setup\Model\ConfigModel->getAvailableOptions()
#2 /var/www/magento-framework-check/vendor/symfony/console/Command/Command.php(77): Magento\Setup\Console\Command\ConfigSetCommand->configure()
#3 /var/www/magento-framework-check/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php(51): Symfony\Component\Console\Command\Command->__construct()
#4 /var/www/magento-framework-check/vendor/laminas/laminas-di/src/Di.php(511): Magento\Setup\Console\Command\ConfigSetCommand->__construct()
#5 /var/www/magento-framework-check/vendor/laminas/laminas-di/src/Di.php(318): Laminas\Di\Di->createInstanceViaConstructor()
#6 /var/www/mage in /var/www/magento-framework-check/setup/src/Magento/Setup/Model/ConfigOptionsList.php on line 180

Включаем pdo, снова ошибка:

taras@taras-home:/var/www/magento-framework-check$ bin/magento
PHP Fatal error:  Uncaught Error: Undefined class constant 'PDO::MYSQL_ATTR_SSL_KEY' in /var/www/magento-framework-check/setup/src/Magento/Setup/Model/ConfigOptionsList.php:180
Stack trace:
#0 /var/www/magento-framework-check/setup/src/Magento/Setup/Model/ConfigModel.php(71): Magento\Setup\Model\ConfigOptionsList->getOptions()
#1 /var/www/magento-framework-check/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php(61): Magento\Setup\Model\ConfigModel->getAvailableOptions()
#2 /var/www/magento-framework-check/vendor/symfony/console/Command/Command.php(77): Magento\Setup\Console\Command\ConfigSetCommand->configure()
#3 /var/www/magento-framework-check/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php(51): Symfony\Component\Console\Command\Command->__construct()
#4 /var/www/magento-framework-check/vendor/laminas/laminas-di/src/Di.php(511): Magento\Setup\Console\Command\ConfigSetCommand->__construct()
#5 /var/www/magento-framework-check/vendor/laminas/laminas-di/src/Di.php(318): Laminas\Di\Di->createInstanceViaC in /var/www/magento-framework-check/setup/src/Magento/Setup/Model/ConfigOptionsList.php on line 180

Включаем mysqlnd и получаем наконец вывод без ошибок:

taras@taras-home:/var/www/magento-framework-check$ bin/magento -v
Magento CLI

Usage:
  command [options] [arguments]

Options:
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  help                                     Display help for a command
  list                                     List commands
 admin
  admin:user:create                        Creates an administrator
 app
  app:config:import                        Import data from shared configuration files to appropriate data storage
 i18n
  i18n:collect-phrases                     Discovers phrases in the codebase
  i18n:pack                                Saves language package
 info
  info:adminuri                            Displays the Magento Admin URI
  info:backups:list                        Prints list of available backup files
  info:currency:list                       Displays the list of available currencies
  info:dependencies:show-framework         Shows number of dependencies on Magento framework
  info:dependencies:show-modules           Shows number of dependencies between modules
  info:dependencies:show-modules-circular  Shows number of circular dependencies between modules
  info:language:list                       Displays the list of available language locales
  info:timezone:list                       Displays the list of available timezones
 maintenance
  maintenance:allow-ips                    Sets maintenance mode exempt IPs
  maintenance:disable                      Disables maintenance mode
  maintenance:enable                       Enables maintenance mode
  maintenance:status                       Displays maintenance mode status
 module
  module:config:status                     Checks the modules configuration in the 'app/etc/config.php' file and reports if they are up to date or not
  module:disable                           Disables specified modules
  module:enable                            Enables specified modules
  module:status                            Displays status of modules
  module:uninstall                         Uninstalls modules installed by composer
 setup
  setup:backup                             Takes backup of Magento Application code base, media and database
  setup:config:set                         Creates or modifies the deployment configuration
  setup:db-data:upgrade                    Installs and upgrades data in the DB
  setup:db-schema:upgrade                  Installs and upgrades the DB schema
  setup:db:status                          Checks if DB schema or data requires upgrade
  setup:di:compile                         Generates DI configuration and all missing classes that can be auto-generated
  setup:install                            Installs the Magento application
  setup:performance:generate-fixtures      Generates fixtures
  setup:rollback                           Rolls back Magento Application codebase, media and database
  setup:static-content:deploy              Deploys static view files
  setup:store-config:set                   Installs the store configuration. Deprecated since 2.2.0. Use config:set instead
  setup:uninstall                          Uninstalls the Magento application
  setup:upgrade                            Upgrades the Magento application, DB data, and schema

Обратите внимание: версия Magento CLI не указана.

Установка Magento 2

Для начала создадим для Magento вирутальный хост в nginx. Сразу настраиваем IPv6, HTTP/2, HTTPS:

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name magento-framework-check.loc;
  ssl_certificate     /ssl/magento-framework-check.loc.pem;
  ssl_certificate_key /ssl/magento-framework-check.loc-key.pem;
  ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers         HIGH:!aNULL:!MD5;
  set $MAGE_ROOT /var/www/magento-framework-check;
  include /var/www/magento-framework-check/nginx.conf.sample;
}

Чекаем, что работает:

Создаем БД:

MariaDB [(none)]> create database magento_framework_check;
Query OK, 1 row affected (0.000 sec)

Приступаем к установке:

taras@taras-home:/var/www/magento-framework-check$ bin/magento setup:install \
> --base-url=https://magento-framework-check.loc \
> --db-host=localhost \
> --db-name=magento_framework_check \
> --db-user=root \
> --db-password=***** \
> --backend-frontname=admin \
> --admin-firstname=admin \
> --admin-lastname=admin \
> --admin-email=admin@admin.com \
> --admin-user=tkovrijenko \
> --admin-password=****** \
> --language=en_US \
> --currency=USD \
> --timezone=Europe/Kiev \
> --use-rewrites=1
Starting Magento installation:
File permissions check...
[Progress: 1 / 234]
Required extensions check...
[Progress: 2 / 234]
Enabling Maintenance Mode...
[Progress: 3 / 234]
Installing deployment configuration...
PHP Fatal error:  Uncaught Error: Call to undefined function Magento\Framework\App\DeploymentConfig\token_get_all() in /var/www/magento-framework-check/vendor/magento/framework/App/DeploymentConfig/CommentParser.php:75
Stack trace:
#0 /var/www/magento-framework-check/vendor/magento/framework/App/DeploymentConfig/Writer.php(131): Magento\Framework\App\DeploymentConfig\CommentParser->execute()
#1 /var/www/magento-framework-check/setup/src/Magento/Setup/Model/ConfigModel.php(118): Magento\Framework\App\DeploymentConfig\Writer->saveConfig()
#2 /var/www/magento-framework-check/setup/src/Magento/Setup/Model/Installer.php(580): Magento\Setup\Model\ConfigModel->process()
#3 [internal function]: Magento\Setup\Model\Installer->installDeploymentConfig()
#4 /var/www/magento-framework-check/setup/src/Magento/Setup/Model/Installer.php(389): call_user_func_array()
#5 /var/www/magento-framework-check/setup/src/Magento/Setup/Console/Command/InstallCommand.php(231): Magento\Setup\Model\Installer->install()
#6 /var/www/magento-framework-check/ve in /var/www/magento-framework-check/vendor/magento/framework/App/DeploymentConfig/CommentParser.php on line 75

Похоже, еще одна необъявленная зависимость - на этот раз от модуля PHP tokenizer. Включаем...

Starting Magento Installation
Starting Magento installation:
File permissions check...
[Progress: 1 / 234]
Required extensions check...
[Progress: 2 / 234]
Enabling Maintenance Mode...
[Progress: 3 / 234]
Installing deployment configuration...
[Progress: 4 / 234]
Installing database schema:
Schema creation/updates:
Module 'Magento_Store':
[Progress: 5 / 234]
Module 'Magento_Directory':
[Progress: 6 / 234]
Module 'Magento_Config':
[Progress: 7 / 234]
Module 'Magento_Backup':
[Progress: 8 / 234]
Module 'Magento_Theme':
[Progress: 9 / 234]
Module 'Magento_Eav':
[Progress: 10 / 234]
Module 'Magento_Customer':
[Progress: 11 / 234]
Module 'Magento_CatalogImportExport':
[Progress: 12 / 234]
Module 'Magento_Indexer':
[Progress: 13 / 234]
Module 'Magento_Variable':
[Progress: 14 / 234]
Module 'Magento_Cms':
[Progress: 15 / 234]
Module 'Magento_Catalog':
[Progress: 16 / 234]
Module 'Magento_Payment':
[Progress: 17 / 234]
Module 'Magento_CmsUrlRewrite':
[Progress: 18 / 234]
Module 'Magento_Backend':
[Progress: 19 / 234]
Module 'Magento_Contact':
[Progress: 20 / 234]
Module 'Magento_Cron':
[Progress: 21 / 234]
Module 'Magento_Bundle':
[Progress: 22 / 234]
Module 'Magento_Deploy':
[Progress: 23 / 234]
Module 'Magento_Developer':
[Progress: 24 / 234]
Module 'Magento_Authorization':
[Progress: 25 / 234]
Module 'Magento_Downloadable':
[Progress: 26 / 234]
Module 'Magento_Quote':
[Progress: 27 / 234]
Module 'Magento_Email':
[Progress: 28 / 234]
Module 'Magento_Rule':
[Progress: 29 / 234]
Module 'Magento_ImportExport':
[Progress: 30 / 234]
Module 'Magento_CatalogRule':
[Progress: 31 / 234]
Module 'Magento_Security':
[Progress: 32 / 234]
Module 'Magento_MediaStorage':
[Progress: 33 / 234]
Module 'Magento_Msrp':
[Progress: 34 / 234]
Module 'Magento_Widget':
[Progress: 35 / 234]
Module 'Magento_PageCache':
[Progress: 36 / 234]
Module 'Magento_SalesSequence':
[Progress: 37 / 234]
Module 'Magento_ProductAlert':
[Progress: 38 / 234]
Module 'Magento_Sales':
[Progress: 39 / 234]
Module 'Magento_Reports':
[Progress: 40 / 234]
Module 'Magento_RequireJs':
[Progress: 41 / 234]
Module 'Magento_Review':
[Progress: 42 / 234]
Module 'Magento_Rss':
[Progress: 43 / 234]
Module 'Magento_GiftMessage':
[Progress: 44 / 234]
Module 'Magento_CatalogInventory':
[Progress: 45 / 234]
Module 'Magento_SalesRule':
[Progress: 46 / 234]
Module 'Magento_Checkout':
[Progress: 47 / 234]
Module 'Magento_User':
[Progress: 48 / 234]
Module 'Magento_Ui':
[Progress: 49 / 234]
Module 'Magento_AsynchronousOperations':
[Progress: 50 / 234]
Module 'Magento_Tax':
[Progress: 51 / 234]
Module 'Magento_CatalogUrlRewrite':
[Progress: 52 / 234]
Module 'Magento_Translation':
[Progress: 53 / 234]
Module 'Magento_Shipping':
[Progress: 54 / 234]
Module 'Magento_UrlRewrite':
[Progress: 55 / 234]
Module 'Magento_Integration':
[Progress: 56 / 234]
Module 'Magento_Captcha':
[Progress: 57 / 234]
Module 'Magento_Newsletter':
[Progress: 58 / 234]
Module 'Magento_Wishlist':
[Progress: 59 / 234]
Schema post-updates:
Module 'Magento_Store':
[Progress: 60 / 234]
Module 'Magento_Directory':
[Progress: 61 / 234]
Module 'Magento_Config':
[Progress: 62 / 234]
Module 'Magento_Backup':
[Progress: 63 / 234]
Module 'Magento_Theme':
[Progress: 64 / 234]
Module 'Magento_Eav':
[Progress: 65 / 234]
Module 'Magento_Customer':
[Progress: 66 / 234]
Module 'Magento_CatalogImportExport':
[Progress: 67 / 234]
Module 'Magento_Indexer':
Running schema recurring...
[Progress: 68 / 234]
Module 'Magento_Variable':
[Progress: 69 / 234]
Module 'Magento_Cms':
[Progress: 70 / 234]
Module 'Magento_Catalog':
Running schema recurring...
[Progress: 71 / 234]
Module 'Magento_Payment':
[Progress: 72 / 234]
Module 'Magento_CmsUrlRewrite':
[Progress: 73 / 234]
Module 'Magento_Backend':
[Progress: 74 / 234]
Module 'Magento_Contact':
[Progress: 75 / 234]
Module 'Magento_Cron':
Running schema recurring...
[Progress: 76 / 234]
Module 'Magento_Bundle':
Running schema recurring...
[Progress: 77 / 234]
Module 'Magento_Deploy':
[Progress: 78 / 234]
Module 'Magento_Developer':
[Progress: 79 / 234]
Module 'Magento_Authorization':
[Progress: 80 / 234]
Module 'Magento_Downloadable':
[Progress: 81 / 234]
Module 'Magento_Quote':
[Progress: 82 / 234]
Module 'Magento_Email':
[Progress: 83 / 234]
Module 'Magento_Rule':
[Progress: 84 / 234]
Module 'Magento_ImportExport':
[Progress: 85 / 234]
Module 'Magento_CatalogRule':
[Progress: 86 / 234]
Module 'Magento_Security':
[Progress: 87 / 234]
Module 'Magento_MediaStorage':
[Progress: 88 / 234]
Module 'Magento_Msrp':
[Progress: 89 / 234]
Module 'Magento_Widget':
[Progress: 90 / 234]
Module 'Magento_PageCache':
[Progress: 91 / 234]
Module 'Magento_SalesSequence':
Running schema recurring...
[Progress: 92 / 234]
Module 'Magento_ProductAlert':
Running schema recurring...
[Progress: 93 / 234]
Module 'Magento_Sales':
[Progress: 94 / 234]
Module 'Magento_Reports':
Running schema recurring...
[Progress: 95 / 234]
Module 'Magento_RequireJs':
[Progress: 96 / 234]
Module 'Magento_Review':
[Progress: 97 / 234]
Module 'Magento_Rss':
[Progress: 98 / 234]
Module 'Magento_GiftMessage':
[Progress: 99 / 234]
Module 'Magento_CatalogInventory':
Running schema recurring...
[Progress: 100 / 234]
Module 'Magento_SalesRule':
[Progress: 101 / 234]
Module 'Magento_Checkout':
[Progress: 102 / 234]
Module 'Magento_User':
[Progress: 103 / 234]
Module 'Magento_Ui':
[Progress: 104 / 234]
Module 'Magento_AsynchronousOperations':
[Progress: 105 / 234]
Module 'Magento_Tax':
[Progress: 106 / 234]
Module 'Magento_CatalogUrlRewrite':
Running schema recurring...
[Progress: 107 / 234]
Module 'Magento_Translation':
[Progress: 108 / 234]
Module 'Magento_Shipping':
[Progress: 109 / 234]
Module 'Magento_UrlRewrite':
[Progress: 110 / 234]
Module 'Magento_Integration':
Running schema recurring...
[Progress: 111 / 234]
Module 'Magento_Captcha':
[Progress: 112 / 234]
Module 'Magento_Newsletter':
[Progress: 113 / 234]
Module 'Magento_Wishlist':
Running schema recurring...
[Progress: 114 / 234]
[Progress: 115 / 234]
Installing search configuration...

In ClassReader.php line 45:
                                                                                                                                                                                 
  Impossible to process constructor argument Parameter #1 [ <required> Magento\Search\Model\SearchEngine\Validator $searchValidator ] of Magento\Setup\Model\SearchConfig class  
                                                                                                                                                                                 

In ClassReader.php line 34:
                                                                    
  Class Magento\Search\Model\SearchEngine\Validator does not exist  
                                                                    

На этот раз продвинулись чуть дальше. Но с чего вдруг нам понадобился модуль поиска? А Magento конфигурирует его в \Magento\Setup\Model\SearchConfig даже не проверив, установлен ли он. Ставим:

taras@taras-home:/var/www/magento-framework-check$ composer require magento/module-search
Using version ^101.1 for magento/module-search
./composer.json has been updated
Running composer update magento/module-search
Loading composer repositories with package information
Updating dependencies
Lock file operations: 2 installs, 0 updates, 0 removals
  - Locking magento/module-catalog-search (102.0.2)
  - Locking magento/module-search (101.1.2)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 2 installs, 0 updates, 0 removals
  - Installing magento/module-search (101.1.2): Extracting archive
  - Installing magento/module-catalog-search (102.0.2): Extracting archive
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.
Package laminas/laminas-console is abandoned, you should avoid using it. Use laminas/laminas-cli instead.
Generating autoload files
45 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

К счастью еще 100 модулей с ним не подтянулось :)

Продолжаем:

Starting Magento Installation
Starting Magento installation:
File permissions check...
[Progress: 1 / 242]
Required extensions check...
[Progress: 2 / 242]
Enabling Maintenance Mode...
[Progress: 3 / 242]
Installing deployment configuration...
[Progress: 4 / 242]
Installing database schema:
Schema creation/updates:
Module 'Magento_Store':
[Progress: 5 / 242]
Module 'Magento_Directory':
[Progress: 6 / 242]
Module 'Magento_Config':
[Progress: 7 / 242]
Module 'Magento_Backup':
[Progress: 8 / 242]
Module 'Magento_Theme':
[Progress: 9 / 242]
Module 'Magento_Eav':
[Progress: 10 / 242]
Module 'Magento_Customer':
[Progress: 11 / 242]
Module 'Magento_CatalogImportExport':
[Progress: 12 / 242]
Module 'Magento_Indexer':
[Progress: 13 / 242]
Module 'Magento_Variable':
[Progress: 14 / 242]
Module 'Magento_Cms':
[Progress: 15 / 242]
Module 'Magento_Catalog':
[Progress: 16 / 242]
Module 'Magento_Payment':
[Progress: 17 / 242]
Module 'Magento_Quote':
[Progress: 18 / 242]
Module 'Magento_CmsUrlRewrite':
[Progress: 19 / 242]
Module 'Magento_Backend':
[Progress: 20 / 242]
Module 'Magento_Contact':
[Progress: 21 / 242]
Module 'Magento_Cron':
[Progress: 22 / 242]
Module 'Magento_Bundle':
[Progress: 23 / 242]
Module 'Magento_Deploy':
[Progress: 24 / 242]
Module 'Magento_Developer':
[Progress: 25 / 242]
Module 'Magento_Authorization':
[Progress: 26 / 242]
Module 'Magento_Downloadable':
[Progress: 27 / 242]
Module 'Magento_Rule':
[Progress: 28 / 242]
Module 'Magento_Email':
[Progress: 29 / 242]
Module 'Magento_SalesSequence':
[Progress: 30 / 242]
Module 'Magento_ImportExport':
[Progress: 31 / 242]
Module 'Magento_CatalogRule':
[Progress: 32 / 242]
Module 'Magento_Security':
[Progress: 33 / 242]
Module 'Magento_MediaStorage':
[Progress: 34 / 242]
Module 'Magento_Msrp':
[Progress: 35 / 242]
Module 'Magento_Widget':
[Progress: 36 / 242]
Module 'Magento_PageCache':
[Progress: 37 / 242]
Module 'Magento_Sales':
[Progress: 38 / 242]
Module 'Magento_ProductAlert':
[Progress: 39 / 242]
Module 'Magento_CatalogInventory':
[Progress: 40 / 242]
Module 'Magento_Reports':
[Progress: 41 / 242]
Module 'Magento_RequireJs':
[Progress: 42 / 242]
Module 'Magento_Review':
[Progress: 43 / 242]
Module 'Magento_Rss':
[Progress: 44 / 242]
Module 'Magento_Search':
[Progress: 45 / 242]
Module 'Magento_GiftMessage':
[Progress: 46 / 242]
Module 'Magento_SalesRule':
[Progress: 47 / 242]
Module 'Magento_Checkout':
[Progress: 48 / 242]
Module 'Magento_CatalogSearch':
[Progress: 49 / 242]
Module 'Magento_User':
[Progress: 50 / 242]
Module 'Magento_Ui':
[Progress: 51 / 242]
Module 'Magento_AsynchronousOperations':
[Progress: 52 / 242]
Module 'Magento_Tax':
[Progress: 53 / 242]
Module 'Magento_Captcha':
[Progress: 54 / 242]
Module 'Magento_Translation':
[Progress: 55 / 242]
Module 'Magento_Shipping':
[Progress: 56 / 242]
Module 'Magento_UrlRewrite':
[Progress: 57 / 242]
Module 'Magento_Integration':
[Progress: 58 / 242]
Module 'Magento_CatalogUrlRewrite':
[Progress: 59 / 242]
Module 'Magento_Newsletter':
[Progress: 60 / 242]
Module 'Magento_Wishlist':
[Progress: 61 / 242]
Schema post-updates:
Module 'Magento_Store':
[Progress: 62 / 242]
Module 'Magento_Directory':
[Progress: 63 / 242]
Module 'Magento_Config':
[Progress: 64 / 242]
Module 'Magento_Backup':
[Progress: 65 / 242]
Module 'Magento_Theme':
[Progress: 66 / 242]
Module 'Magento_Eav':
[Progress: 67 / 242]
Module 'Magento_Customer':
[Progress: 68 / 242]
Module 'Magento_CatalogImportExport':
[Progress: 69 / 242]
Module 'Magento_Indexer':
Running schema recurring...
[Progress: 70 / 242]
Module 'Magento_Variable':
[Progress: 71 / 242]
Module 'Magento_Cms':
[Progress: 72 / 242]
Module 'Magento_Catalog':
Running schema recurring...
[Progress: 73 / 242]
Module 'Magento_Payment':
[Progress: 74 / 242]
Module 'Magento_Quote':
[Progress: 75 / 242]
Module 'Magento_CmsUrlRewrite':
[Progress: 76 / 242]
Module 'Magento_Backend':
[Progress: 77 / 242]
Module 'Magento_Contact':
[Progress: 78 / 242]
Module 'Magento_Cron':
Running schema recurring...
[Progress: 79 / 242]
Module 'Magento_Bundle':
Running schema recurring...
[Progress: 80 / 242]
Module 'Magento_Deploy':
[Progress: 81 / 242]
Module 'Magento_Developer':
[Progress: 82 / 242]
Module 'Magento_Authorization':
[Progress: 83 / 242]
Module 'Magento_Downloadable':
[Progress: 84 / 242]
Module 'Magento_Rule':
[Progress: 85 / 242]
Module 'Magento_Email':
[Progress: 86 / 242]
Module 'Magento_SalesSequence':
Running schema recurring...
[Progress: 87 / 242]
Module 'Magento_ImportExport':
[Progress: 88 / 242]
Module 'Magento_CatalogRule':
[Progress: 89 / 242]
Module 'Magento_Security':
[Progress: 90 / 242]
Module 'Magento_MediaStorage':
[Progress: 91 / 242]
Module 'Magento_Msrp':
[Progress: 92 / 242]
Module 'Magento_Widget':
[Progress: 93 / 242]
Module 'Magento_PageCache':
[Progress: 94 / 242]
Module 'Magento_Sales':
[Progress: 95 / 242]
Module 'Magento_ProductAlert':
Running schema recurring...
[Progress: 96 / 242]
Module 'Magento_CatalogInventory':
Running schema recurring...
[Progress: 97 / 242]
Module 'Magento_Reports':
Running schema recurring...
[Progress: 98 / 242]
Module 'Magento_RequireJs':
[Progress: 99 / 242]
Module 'Magento_Review':
[Progress: 100 / 242]
Module 'Magento_Rss':
[Progress: 101 / 242]
Module 'Magento_Search':
[Progress: 102 / 242]
Module 'Magento_GiftMessage':
[Progress: 103 / 242]
Module 'Magento_SalesRule':
[Progress: 104 / 242]
Module 'Magento_Checkout':
[Progress: 105 / 242]
Module 'Magento_CatalogSearch':
[Progress: 106 / 242]
Module 'Magento_User':
[Progress: 107 / 242]
Module 'Magento_Ui':
[Progress: 108 / 242]
Module 'Magento_AsynchronousOperations':
[Progress: 109 / 242]
Module 'Magento_Tax':
[Progress: 110 / 242]
Module 'Magento_Captcha':
[Progress: 111 / 242]
Module 'Magento_Translation':
[Progress: 112 / 242]
Module 'Magento_Shipping':
[Progress: 113 / 242]
Module 'Magento_UrlRewrite':
[Progress: 114 / 242]
Module 'Magento_Integration':
Running schema recurring...
[Progress: 115 / 242]
Module 'Magento_CatalogUrlRewrite':
Running schema recurring...
[Progress: 116 / 242]
Module 'Magento_Newsletter':
[Progress: 117 / 242]
Module 'Magento_Wishlist':
Running schema recurring...
[Progress: 118 / 242]
[Progress: 119 / 242]
Installing search configuration...
[Progress: 120 / 242]
Installing user configuration...
[Progress: 121 / 242]
Enabling caches:
Current status:
config: 1
layout: 1
block_html: 1
collections: 1
reflection: 1
db_ddl: 1
compiled_config: 1
eav: 1
customer_notification: 1
full_page: 1
translate: 1
config_integration: 1
config_integration_api: 1
[Progress: 122 / 242]
Installing data...
Data install/update:
Disabling caches:
Current status:
layout: 0
block_html: 0
full_page: 0
Module 'Magento_Store':
[Progress: 123 / 242]
Module 'Magento_Directory':
[Progress: 124 / 242]
Module 'Magento_Config':
[Progress: 125 / 242]
Module 'Magento_Backup':
[Progress: 126 / 242]
Module 'Magento_Theme':
[Progress: 127 / 242]
Module 'Magento_Eav':
[Progress: 128 / 242]
Module 'Magento_Customer':
[Progress: 129 / 242]
Module 'Magento_CatalogImportExport':
[Progress: 130 / 242]
Module 'Magento_Indexer':
[Progress: 131 / 242]
Module 'Magento_Variable':
[Progress: 132 / 242]
Module 'Magento_Cms':
[Progress: 133 / 242]
Module 'Magento_Catalog':
[Progress: 134 / 242]
Module 'Magento_Payment':
[Progress: 135 / 242]
Module 'Magento_Quote':
[Progress: 136 / 242]
Module 'Magento_CmsUrlRewrite':
[Progress: 137 / 242]
Module 'Magento_Backend':
[Progress: 138 / 242]
Module 'Magento_Contact':
[Progress: 139 / 242]
Module 'Magento_Cron':
[Progress: 140 / 242]
Module 'Magento_Bundle':
[Progress: 141 / 242]
Module 'Magento_Deploy':
[Progress: 142 / 242]
Module 'Magento_Developer':
[Progress: 143 / 242]
Module 'Magento_Authorization':
[Progress: 144 / 242]
Module 'Magento_Downloadable':
[Progress: 145 / 242]
Module 'Magento_Rule':
[Progress: 146 / 242]
Module 'Magento_Email':
[Progress: 147 / 242]
Module 'Magento_SalesSequence':
[Progress: 148 / 242]
Module 'Magento_ImportExport':
[Progress: 149 / 242]
Module 'Magento_CatalogRule':
[Progress: 150 / 242]
Module 'Magento_Security':
[Progress: 151 / 242]
Module 'Magento_MediaStorage':
[Progress: 152 / 242]
Module 'Magento_Msrp':
[Progress: 153 / 242]
Module 'Magento_Widget':
[Progress: 154 / 242]
Module 'Magento_PageCache':
[Progress: 155 / 242]
Module 'Magento_Sales':
[Progress: 156 / 242]
Module 'Magento_ProductAlert':
[Progress: 157 / 242]
Module 'Magento_CatalogInventory':
[Progress: 158 / 242]
Module 'Magento_Reports':
[Progress: 159 / 242]
Module 'Magento_RequireJs':
[Progress: 160 / 242]
Module 'Magento_Review':
[Progress: 161 / 242]
Module 'Magento_Rss':
[Progress: 162 / 242]
Module 'Magento_Search':
[Progress: 163 / 242]
Module 'Magento_GiftMessage':
[Progress: 164 / 242]
Module 'Magento_SalesRule':
[Progress: 165 / 242]
Module 'Magento_Checkout':
[Progress: 166 / 242]
Module 'Magento_CatalogSearch':
[Progress: 167 / 242]
Module 'Magento_User':
[Progress: 168 / 242]
Module 'Magento_Ui':
[Progress: 169 / 242]
Module 'Magento_AsynchronousOperations':
[Progress: 170 / 242]
Module 'Magento_Tax':
[Progress: 171 / 242]
Module 'Magento_Captcha':
[Progress: 172 / 242]
Module 'Magento_Translation':
[Progress: 173 / 242]
Module 'Magento_Shipping':
[Progress: 174 / 242]
Module 'Magento_UrlRewrite':
[Progress: 175 / 242]
Module 'Magento_Integration':
[Progress: 176 / 242]
Module 'Magento_CatalogUrlRewrite':
[Progress: 177 / 242]
Module 'Magento_Newsletter':
[Progress: 178 / 242]
Module 'Magento_Wishlist':
[Progress: 179 / 242]
Data post-updates:
Module 'Magento_Store':
[Progress: 180 / 242]
Module 'Magento_Directory':
[Progress: 181 / 242]
Module 'Magento_Config':
[Progress: 182 / 242]
Module 'Magento_Backup':
[Progress: 183 / 242]
Module 'Magento_Theme':
Running data recurring...
[Progress: 184 / 242]
Module 'Magento_Eav':
[Progress: 185 / 242]
Module 'Magento_Customer':
Running data recurring...
[Progress: 186 / 242]
Module 'Magento_CatalogImportExport':
[Progress: 187 / 242]
Module 'Magento_Indexer':
[Progress: 188 / 242]
Module 'Magento_Variable':
[Progress: 189 / 242]
Module 'Magento_Cms':
[Progress: 190 / 242]
Module 'Magento_Catalog':
[Progress: 191 / 242]
Module 'Magento_Payment':
[Progress: 192 / 242]
Module 'Magento_Quote':
[Progress: 193 / 242]
Module 'Magento_CmsUrlRewrite':
[Progress: 194 / 242]
Module 'Magento_Backend':
[Progress: 195 / 242]
Module 'Magento_Contact':
[Progress: 196 / 242]
Module 'Magento_Cron':
[Progress: 197 / 242]
Module 'Magento_Bundle':
[Progress: 198 / 242]
Module 'Magento_Deploy':
[Progress: 199 / 242]
Module 'Magento_Developer':
[Progress: 200 / 242]
Module 'Magento_Authorization':
[Progress: 201 / 242]
Module 'Magento_Downloadable':
[Progress: 202 / 242]
Module 'Magento_Rule':
[Progress: 203 / 242]
Module 'Magento_Email':
[Progress: 204 / 242]
Module 'Magento_SalesSequence':
Running data recurring...
[Progress: 205 / 242]
Module 'Magento_ImportExport':
[Progress: 206 / 242]
Module 'Magento_CatalogRule':
[Progress: 207 / 242]
Module 'Magento_Security':
[Progress: 208 / 242]
Module 'Magento_MediaStorage':
[Progress: 209 / 242]
Module 'Magento_Msrp':
[Progress: 210 / 242]
Module 'Magento_Widget':
[Progress: 211 / 242]
Module 'Magento_PageCache':
[Progress: 212 / 242]
Module 'Magento_Sales':
[Progress: 213 / 242]
Module 'Magento_ProductAlert':
[Progress: 214 / 242]
Module 'Magento_CatalogInventory':
[Progress: 215 / 242]
Module 'Magento_Reports':
[Progress: 216 / 242]
Module 'Magento_RequireJs':
[Progress: 217 / 242]
Module 'Magento_Review':
[Progress: 218 / 242]
Module 'Magento_Rss':
[Progress: 219 / 242]
Module 'Magento_Search':
[Progress: 220 / 242]
Module 'Magento_GiftMessage':
[Progress: 221 / 242]
Module 'Magento_SalesRule':
[Progress: 222 / 242]
Module 'Magento_Checkout':
[Progress: 223 / 242]
Module 'Magento_CatalogSearch':
[Progress: 224 / 242]
Module 'Magento_User':
[Progress: 225 / 242]
Module 'Magento_Ui':
[Progress: 226 / 242]
Module 'Magento_AsynchronousOperations':
[Progress: 227 / 242]
Module 'Magento_Tax':
[Progress: 228 / 242]
Module 'Magento_Captcha':
[Progress: 229 / 242]
Module 'Magento_Translation':
[Progress: 230 / 242]
Module 'Magento_Shipping':
[Progress: 231 / 242]
Module 'Magento_UrlRewrite':
[Progress: 232 / 242]
Module 'Magento_Integration':
[Progress: 233 / 242]
Module 'Magento_CatalogUrlRewrite':
[Progress: 234 / 242]
Module 'Magento_Newsletter':
[Progress: 235 / 242]
Module 'Magento_Wishlist':
[Progress: 236 / 242]
Enabling caches:
Current status:
layout: 1
block_html: 1
full_page: 1
[Progress: 237 / 242]
Installing admin user...
[Progress: 238 / 242]
Caches clearing:
Cache cleared successfully
[Progress: 239 / 242]
Disabling Maintenance Mode:
[Progress: 240 / 242]
Post installation file permissions check...
For security, remove write permissions from these directories: '/var/www/magento-framework-check/app/etc'
[Progress: 241 / 242]
Write installation date...
[Progress: 242 / 242]
[SUCCESS]: Magento installation complete.
[SUCCESS]: Magento Admin URI: /admin
Nothing to import.
taras@taras-home:/var/www/magento-framework-check$ 

Можно выдохнуть. Вроде установилось. Запускаем bin/magento deploy:mode:set developer и пробуем зайти на сайт:

1 exception(s):
Exception #0 (LogicException): Unable to load theme by specified key: 'Magento/luma'

Exception #0 (LogicException): Unable to load theme by specified key: 'Magento/luma'
<pre>#1 Magento\Theme\Model\View\Design->setDesignTheme() called at [vendor/magento/module-theme/Model/View/Design.php:212]
#2 Magento\Theme\Model\View\Design->setDefaultDesignTheme() called at [vendor/magento/framework/App/Area.php:261]
#3 Magento\Framework\App\Area->_initDesign() called at [vendor/magento/framework/App/Area.php:219]
#4 Magento\Framework\App\Area->_loadPart() called at [vendor/magento/framework/App/Area.php:143]
#5 Magento\Framework\App\Area->load() called at [vendor/magento/framework/View/DesignLoader.php:54]
#6 Magento\Framework\View\DesignLoader->load() called at [vendor/magento/module-theme/Plugin/LoadDesignPlugin.php:53]
#7 Magento\Theme\Plugin\LoadDesignPlugin->beforeExecute() called at [vendor/magento/framework/Interception/Interceptor.php:121]
#8 Magento\Cms\Controller\Index\Index\Interceptor->Magento\Framework\Interception\{closure}() called at [vendor/magento/framework/App/Action/Plugin/ActionFlagNoDispatchPlugin.php:51]
#9 Magento\Framework\App\Action\Plugin\ActionFlagNoDispatchPlugin->aroundExecute() called at [vendor/magento/framework/Interception/Interceptor.php:135]
#10 Magento\Cms\Controller\Index\Index\Interceptor->Magento\Framework\Interception\{closure}() called at [vendor/magento/framework/Interception/Interceptor.php:153]
#11 Magento\Cms\Controller\Index\Index\Interceptor->___callPlugins() called at [generated/code/Magento/Cms/Controller/Index/Index/Interceptor.php:23]
#12 Magento\Cms\Controller\Index\Index\Interceptor->execute() called at [vendor/magento/framework/App/Action/Action.php:111]
#13 Magento\Framework\App\Action\Action->dispatch() called at [vendor/magento/framework/Interception/Interceptor.php:58]
#14 Magento\Cms\Controller\Index\Index\Interceptor->___callParent() called at [vendor/magento/framework/Interception/Interceptor.php:138]
#15 Magento\Cms\Controller\Index\Index\Interceptor->Magento\Framework\Interception\{closure}() called at [vendor/magento/framework/Interception/Interceptor.php:153]
#16 Magento\Cms\Controller\Index\Index\Interceptor->___callPlugins() called at [generated/code/Magento/Cms/Controller/Index/Index/Interceptor.php:32]
#17 Magento\Cms\Controller\Index\Index\Interceptor->dispatch() called at [vendor/magento/framework/App/FrontController.php:186]
#18 Magento\Framework\App\FrontController->processRequest() called at [vendor/magento/framework/App/FrontController.php:118]
#19 Magento\Framework\App\FrontController->dispatch() called at [vendor/magento/framework/Interception/Interceptor.php:58]
#20 Magento\Framework\App\FrontController\Interceptor->___callParent() called at [vendor/magento/framework/Interception/Interceptor.php:138]
#21 Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}() called at [vendor/magento/module-store/App/FrontController/Plugin/RequestPreprocessor.php:99]
#22 Magento\Store\App\FrontController\Plugin\RequestPreprocessor->aroundDispatch() called at [vendor/magento/framework/Interception/Interceptor.php:135]
#23 Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}() called at [vendor/magento/module-page-cache/Model/App/FrontController/BuiltinPlugin.php:75]
#24 Magento\PageCache\Model\App\FrontController\BuiltinPlugin->aroundDispatch() called at [vendor/magento/framework/Interception/Interceptor.php:135]
#25 Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}() called at [vendor/magento/framework/Interception/Interceptor.php:153]
#26 Magento\Framework\App\FrontController\Interceptor->___callPlugins() called at [generated/code/Magento/Framework/App/FrontController/Interceptor.php:23]
#27 Magento\Framework\App\FrontController\Interceptor->dispatch() called at [vendor/magento/framework/App/Http.php:116]
#28 Magento\Framework\App\Http->launch() called at [vendor/magento/framework/App/Bootstrap.php:263]
#29 Magento\Framework\App\Bootstrap->run() called at [pub/index.php:29]
</pre>

Чем глубже в лес, тем больше дров. Почему Luma? Я бы понял, если бы оно искало тему Magento/blank, но... Действительно, в vendor/magento/module-theme/etc/di.xml:63 явно говорится устанавливать Luma:

<type name="Magento\Theme\Model\View\Design">
  <arguments>
    <argument name="themes" xsi:type="array">
      <item name="frontend" xsi:type="string">Magento/luma</item>
      <item name="adminhtml" xsi:type="string">Magento/backend</item>
    </argument>
  </arguments>
</type>

Ну, где Luma, там и Blank:

taras@taras-home:/var/www/magento-framework-check$ composer require magento/theme-frontend-luma
Using version ^100.4 for magento/theme-frontend-luma
./composer.json has been updated
Running composer update magento/theme-frontend-luma
Loading composer repositories with package information
Updating dependencies
Lock file operations: 2 installs, 0 updates, 0 removals
  - Locking magento/theme-frontend-blank (100.4.2)
  - Locking magento/theme-frontend-luma (100.4.2)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 2 installs, 0 updates, 0 removals
  - Installing magento/theme-frontend-blank (100.4.2): Extracting archive
  - Installing magento/theme-frontend-luma (100.4.2): Extracting archive
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.
Package laminas/laminas-console is abandoned, you should avoid using it. Use laminas/laminas-cli instead.
Generating autoload files
45 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

И конечно не забываем теперь про bin/magento setup:upgrade. Проверяем:

Так-с, страница загрузилась, но есть какие-то траблы с загрузкой статических файлов. Смотрим лог и видим пачку вот таких ошибок:

[2021-08-06 14:34:06] main.ERROR: Notice: Trying to access array offset on value of type bool in /var/www/magento-framework-check/vendor/magento/framework/Filesystem/Driver/File/Mime.php on line 116 [] []
[2021-08-06 14:34:06] main.CRITICAL: Notice: Trying to access array offset on value of type bool in /var/www/magento-framework-check/vendor/magento/framework/Filesystem/Driver/File/Mime.php on line 116 [] []

Идем в код:

Здесь Маджента пытается работать без функции из ext-fileinfo, и это у неё явно не получается. Включаем расширение и смотрим снова:

Чисто. Наконец-то. А попробуем зайти на страницу регистрации:

2 exceptions
2 exception(s):
Exception #0 (Magento\Framework\Exception\LocalizedException): Invalid block type: Magento\Cookie\Block\RequireCookie
Exception #1 (ReflectionException): Class Magento\Cookie\Block\RequireCookie does not exist

Exception #0 (Magento\Framework\Exception\LocalizedException): Invalid block type: Magento\Cookie\Block\RequireCookie
<pre>#1 Magento\Framework\View\Layout\Generator\Block->createBlock() called at [vendor/magento/framework/View/Layout/Generator/Block.php:229]
#2 Magento\Framework\View\Layout\Generator\Block->generateBlock() called at [vendor/magento/framework/View/Layout/Generator/Block.php:134]
#3 Magento\Framework\View\Layout\Generator\Block->process() called at [vendor/magento/framework/View/Layout/GeneratorPool.php:93]
#4 Magento\Framework\View\Layout\GeneratorPool->process() called at [vendor/magento/framework/View/Layout.php:365]
#5 Magento\Framework\View\Layout->generateElements() called at [vendor/magento/framework/Interception/Interceptor.php:58]
#6 Magento\Framework\View\Layout\Interceptor->___callParent() called at [vendor/magento/framework/Interception/Interceptor.php:138]
#7 Magento\Framework\View\Layout\Interceptor->Magento\Framework\Interception{closure}() called at [vendor/magento/framework/Interception/Interceptor.php:153]
#8 Magento\Framework\View\Layout\Interceptor->___callPlugins() called at [generated/code/Magento/Framework/View/Layout/Interceptor.php:68]
#9 Magento\Framework\View\Layout\Interceptor->generateElements() called at [vendor/magento/framework/View/Layout/Builder.php:129]
#10 Magento\Framework\View\Layout\Builder->generateLayoutBlocks() called at [vendor/magento/framework/View/Page/Builder.php:65]
#11 Magento\Framework\View\Page\Builder->generateLayoutBlocks() called at [vendor/magento/framework/View/Layout/Builder.php:65]
#12 Magento\Framework\View\Layout\Builder->build() called at [vendor/magento/framework/View/Page/Config.php:224]
#13 Magento\Framework\View\Page\Config->build() called at [vendor/magento/framework/View/Page/Config.php:237]
#14 Magento\Framework\View\Page\Config->publicBuild() called at [vendor/magento/framework/View/Result/Page.php:242]
#15 Magento\Framework\View\Result\Page->render() called at [vendor/magento/framework/View/Result/Layout.php:171]
#16 Magento\Framework\View\Result\Layout->renderResult() called at [vendor/magento/framework/Interception/Interceptor.php:58]
#17 Magento\Framework\View\Result\Page\Interceptor->___callParent() called at [vendor/magento/framework/Interception/Interceptor.php:138]
#18 Magento\Framework\View\Result\Page\Interceptor->Magento\Framework\Interception{closure}() called at [vendor/magento/framework/Interception/Interceptor.php:153]
#19 Magento\Framework\View\Result\Page\Interceptor->___callPlugins() called at [generated/code/Magento/Framework/View/Result/Page/Interceptor.php:95]
#20 Magento\Framework\View\Result\Page\Interceptor->renderResult() called at [vendor/magento/framework/App/Http.php:120]
#21 Magento\Framework\App\Http->launch() called at [vendor/magento/framework/App/Bootstrap.php:263]
#22 Magento\Framework\App\Bootstrap->run() called at [pub/index.php:29]
</pre>
Exception #1 (ReflectionException): Class Magento\Cookie\Block\RequireCookie does not exist
<pre>#1 Magento\Framework\Code\Reader\ClassReader->getConstructor() called at [vendor/magento/framework/ObjectManager/Definition/Runtime.php:54]
#2 Magento\Framework\ObjectManager\Definition\Runtime->getParameters() called at [vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:48]
#3 Magento\Framework\ObjectManager\Factory\Dynamic\Developer->create() called at [vendor/magento/framework/ObjectManager/ObjectManager.php:56]
#4 Magento\Framework\ObjectManager\ObjectManager->create() called at [vendor/magento/framework/View/Element/BlockFactory.php:46]
#5 Magento\Framework\View\Element\BlockFactory->createBlock() called at [vendor/magento/framework/View/Layout/Generator/Block.php:272]
#6 Magento\Framework\View\Layout\Generator\Block->getBlockInstance() called at [vendor/magento/framework/View/Layout/Generator/Block.php:252]
#7 Magento\Framework\View\Layout\Generator\Block->createBlock() called at [vendor/magento/framework/View/Layout/Generator/Block.php:229]
#8 Magento\Framework\View\Layout\Generator\Block->generateBlock() called at [vendor/magento/framework/View/Layout/Generator/Block.php:134]
#9 Magento\Framework\View\Layout\Generator\Block->process() called at [vendor/magento/framework/View/Layout/GeneratorPool.php:93]
#10 Magento\Framework\View\Layout\GeneratorPool->process() called at [vendor/magento/framework/View/Layout.php:365]
#11 Magento\Framework\View\Layout->generateElements() called at [vendor/magento/framework/Interception/Interceptor.php:58]
#12 Magento\Framework\View\Layout\Interceptor->___callParent() called at [vendor/magento/framework/Interception/Interceptor.php:138]
#13 Magento\Framework\View\Layout\Interceptor->Magento\Framework\Interception{closure}() called at [vendor/magento/framework/Interception/Interceptor.php:153]
#14 Magento\Framework\View\Layout\Interceptor->___callPlugins() called at [generated/code/Magento/Framework/View/Layout/Interceptor.php:68]
#15 Magento\Framework\View\Layout\Interceptor->generateElements() called at [vendor/magento/framework/View/Layout/Builder.php:129]
#16 Magento\Framework\View\Layout\Builder->generateLayoutBlocks() called at [vendor/magento/framework/View/Page/Builder.php:65]
#17 Magento\Framework\View\Page\Builder->generateLayoutBlocks() called at [vendor/magento/framework/View/Layout/Builder.php:65]
#18 Magento\Framework\View\Layout\Builder->build() called at [vendor/magento/framework/View/Page/Config.php:224]
#19 Magento\Framework\View\Page\Config->build() called at [vendor/magento/framework/View/Page/Config.php:237]
#20 Magento\Framework\View\Page\Config->publicBuild() called at [vendor/magento/framework/View/Result/Page.php:242]
#21 Magento\Framework\View\Result\Page->render() called at [vendor/magento/framework/View/Result/Layout.php:171]
#22 Magento\Framework\View\Result\Layout->renderResult() called at [vendor/magento/framework/Interception/Interceptor.php:58]
#23 Magento\Framework\View\Result\Page\Interceptor->___callParent() called at [vendor/magento/framework/Interception/Interceptor.php:138]
#24 Magento\Framework\View\Result\Page\Interceptor->Magento\Framework\Interception{closure}() called at [vendor/magento/framework/Interception/Interceptor.php:153]
#25 Magento\Framework\View\Result\Page\Interceptor->___callPlugins() called at [generated/code/Magento/Framework/View/Result/Page/Interceptor.php:95]
#26 Magento\Framework\View\Result\Page\Interceptor->renderResult() called at [vendor/magento/framework/App/Http.php:120]
#27 Magento\Framework\App\Http->launch() called at [vendor/magento/framework/App/Bootstrap.php:263]
#28 Magento\Framework\App\Bootstrap->run() called at [pub/index.php:29]
</pre>

Нужен module-cookie...

taras@taras-home:/var/www/magento-framework-check$ composer require magento/module-cookie
Using version ^100.4 for magento/module-cookie
./composer.json has been updated
Running composer update magento/module-cookie
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
  - Locking magento/module-cookie (100.4.2)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing magento/module-cookie (100.4.2): Extracting archive
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.
Package laminas/laminas-console is abandoned, you should avoid using it. Use laminas/laminas-cli instead.
Generating autoload files
45 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

Теперь работает.

Так, всё, переключимся на админку. Видим, что конечно же нужна тема:

1 exception(s):
Exception #0 (LogicException): Unable to load theme by specified key: 'Magento/backend'

Ставим:

taras@taras-home:/var/www/magento-framework-check$ composer require magento/theme-adminhtml-backend
Using version ^100.4 for magento/theme-adminhtml-backend
./composer.json has been updated
Running composer update magento/theme-adminhtml-backend
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
  - Locking magento/theme-adminhtml-backend (100.4.2)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing magento/theme-adminhtml-backend (100.4.2): Extracting archive
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.
Package laminas/laminas-console is abandoned, you should avoid using it. Use laminas/laminas-cli instead.
Generating autoload files
45 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

И теперь можно войти в админку:

И она даже вроде бы нигде не падает.

Но на этом я конечно же не остановлюсь. Есть такой трюк - если хочешь проверить, не налажал ли где-то в коде - запусти bin/magento setup:di:compile.

taras@taras-home:/var/www/magento-framework-check$ bin/magento s:d:c
Compilation was started.
Application code generator... 3/9 [=========>------------------]  33% 1 sec 146.0 MiBPHP Fatal error:  Uncaught Error: Interface 'GraphQL\Error\ClientAware' not found in /var/www/magento-framework-check/vendor/magento/framework/GraphQl/Exception/GraphQlAuthenticationException.php:17
Stack trace:
#0 /var/www/magento-framework-check/vendor/composer/ClassLoader.php(480): include()
#1 /var/www/magento-framework-check/vendor/composer/ClassLoader.php(346): Composer\Autoload\includeFile()
#2 [internal function]: Composer\Autoload\ClassLoader->loadClass()
#3 [internal function]: spl_autoload_call()
#4 /var/www/magento-framework-check/setup/src/Magento/Setup/Module/Di/Code/Reader/ClassesScanner.php(134): class_exists()
#5 /var/www/magento-framework-check/setup/src/Magento/Setup/Module/Di/Code/Reader/ClassesScanner.php(117): Magento\Setup\Module\Di\Code\Reader\ClassesScanner->includeClass()
#6 /var/www/magento-framework-check/setup/src/Magento/Setup/Module/Di/Code/Reader/ClassesScanner.php(87): Magento\Setup\Module\Di\Code\Reader\ClassesScanner->extract()
#7 /var/www/magento-framework-check/setup/src/Magento/Setup/Modul in /var/www/magento-framework-check/vendor/magento/framework/GraphQl/Exception/GraphQlAuthenticationException.php on line 17

И действительно...
Разбираемся, устанавливаем пакет:

taras@taras-home:/var/www/magento-framework-check$ composer require webonyx/graphql-php
Using version ^14.9 for webonyx/graphql-php
./composer.json has been updated
Running composer update webonyx/graphql-php
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
  - Locking webonyx/graphql-php (v14.9.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Downloading webonyx/graphql-php (v14.9.0)
  - Installing webonyx/graphql-php (v14.9.0): Extracting archive
1 package suggestions were added by new dependencies, use `composer suggest` to see details.
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.
Package laminas/laminas-console is abandoned, you should avoid using it. Use laminas/laminas-cli instead.
Generating autoload files
46 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

И снова:

taras@taras-home:/var/www/magento-framework-check$ bin/magento s:d:c
Compilation was started.
Application code generator... 3/9 [=========>------------------]  33% 1 sec 150.0 MiBPHP Fatal error:  Uncaught Error: Class 'Cm_Cache_Backend_Redis' not found in /var/www/magento-framework-check/vendor/magento/framework/Cache/Backend/Redis.php:12
Stack trace:
#0 /var/www/magento-framework-check/vendor/composer/ClassLoader.php(480): include()
#1 /var/www/magento-framework-check/vendor/composer/ClassLoader.php(346): Composer\Autoload\includeFile()
#2 [internal function]: Composer\Autoload\ClassLoader->loadClass()
#3 [internal function]: spl_autoload_call()
#4 /var/www/magento-framework-check/setup/src/Magento/Setup/Module/Di/Code/Reader/ClassesScanner.php(134): class_exists()
#5 /var/www/magento-framework-check/setup/src/Magento/Setup/Module/Di/Code/Reader/ClassesScanner.php(117): Magento\Setup\Module\Di\Code\Reader\ClassesScanner->includeClass()
#6 /var/www/magento-framework-check/setup/src/Magento/Setup/Module/Di/Code/Reader/ClassesScanner.php(87): Magento\Setup\Module\Di\Code\Reader\ClassesScanner->extract()
#7 /var/www/magento-framework-check/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ApplicationC in /var/www/magento-framework-check/vendor/magento/framework/Cache/Backend/Redis.php on line 12

Ставим и сразу проверяем:

taras@taras-home:/var/www/magento-framework-check$ composer require colinmollenhour/cache-backend-redis
Using version ^1.14 for colinmollenhour/cache-backend-redis
./composer.json has been updated
Running composer update colinmollenhour/cache-backend-redis
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
  - Locking colinmollenhour/cache-backend-redis (1.14.2)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing colinmollenhour/cache-backend-redis (1.14.2): Extracting archive
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.
Package laminas/laminas-console is abandoned, you should avoid using it. Use laminas/laminas-cli instead.
Generating autoload files
46 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
taras@taras-home:/var/www/magento-framework-check$ bin/magento s:d:c
Compilation was started.
Application code generator... 3/9 [=========>------------------]  33% 1 sec 148.0 MiB
In ErrorHandler.php line 61:
                                                                                                                                                                                                                    
  Warning: Use of undefined constant MCRYPT_BLOWFISH - assumed 'MCRYPT_BLOWFISH' (this will throw an Error in a future version of PHP) in /var/www/magento-framework-check/setup/src/Magento/Setup/Module/Di/Code/  
  Scanner/PhpScanner.php on line 65                                                                                                                                                                                 
                                                                                                                                                                                                                    

setup:di:compile

Интересно, что делает тут константа из расширения mcrypt, если от него вроде бы давно отказались? Ну, что делать, включаем и идем дальше

taras@taras-home:/var/www/magento-framework-check$ bin/magento s:d:c
Compilation was started.
Area configuration aggregation... 5/9 [===============>------------]  55% 5 secs 194.0 MiB
In ClassReader.php line 45:
                                                                                                                                                                                                                    
  Impossible to process constructor argument Parameter #0 [ <required> Magento\AdminNotification\Model\System\MessageFactory $messageFactory ] of Magento\AsynchronousOperations\Model\ResourceModel\System\Messag  
  e\Collection\Synchronized\Plugin class                                                                                                                                                                            
                                                                                                                                                                                                                    

In ClassReader.php line 34:
                                                                              
  Class Magento\AdminNotification\Model\System\MessageFactory does not exist  
                                                                              

setup:di:compile

Очередная необъявленная зависимость, и опять, похоже, не в том направлении. Если модуль предоставляет функционал асинхронных операций, почему он зависит от каких-то деталей реализации Magento\AdminNotification? Ставим...

taras@taras-home:/var/www/magento-framework-check$ composer require magento/module-admin-notification
Using version ^100.4 for magento/module-admin-notification
./composer.json has been updated
Running composer update magento/module-admin-notification
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
  - Locking magento/module-admin-notification (100.4.1)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing magento/module-admin-notification (100.4.1): Extracting archive
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.

taras@taras-home:/var/www/magento-framework-check$ bin/magento s:d:c
Compilation was started.
Interception cache generation... 6/9 [==================>---------]  66% 5 secs 258.0 MiBErrors during configuration scanning:
        Magento\WebapiAsync\Model\Config\Proxy
                Invalid proxy class for Magento\WebapiAsync\Model\Config</error>
        Magento\ConfigurableProduct\Helper\Product\Options\Factory
                Invalid Factory for nonexistent class Magento\ConfigurableProduct\Helper\Product\Options in file /var/www/magento-framework-check/setup/src/Magento/Setup/Model/FixtureGenerator/ConfigurableProductTemplateGenerator.php
Total Errors Count: 2

In Log.php line 92:
                            
  Error during compilation  
                            

setup:di:compile

И снова у нас в установщике зависимость от модуля Magento_ConfigurableProduct, который нам не нужен (возможно, этих зависимостей можно избежать, но я не знаю, как?)

Ставим и его

taras@taras-home:/var/www/magento-framework-check$ composer require magento/module-configurable-product
Using version ^100.4 for magento/module-configurable-product
./composer.json has been updated
Running composer update magento/module-configurable-product
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
  - Locking magento/module-configurable-product (100.4.2)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing magento/module-configurable-product (100.4.2): Extracting archive
4 package suggestions were added by new dependencies, use `composer suggest` to see details.
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.
Package laminas/laminas-console is abandoned, you should avoid using it. Use laminas/laminas-cli instead.
Generating autoload files
46 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
taras@taras-home:/var/www/magento-framework-check$ bin/magento s:d:c
Compilation was started.
Interception cache generation... 6/9 [==================>---------]  66% 5 secs 260.0 MiBErrors during configuration scanning:
        Magento\WebapiAsync\Model\Config\Proxy
                Invalid proxy class for Magento\WebapiAsync\Model\Config</error>
Total Errors Count: 1

In Log.php line 92:
                            
  Error during compilation  
                            

setup:di:compile

А вот это так же из app/etc/di.xml:231:

<preference for="Magento\AsynchronousOperations\Model\ConfigInterface" type="Magento\WebapiAsync\Model\Config\Proxy" />

Ставим

taras@taras-home:/var/www/magento-framework-check$ composer require magento/module-webapi-async
Using version ^100.4 for magento/module-webapi-async
./composer.json has been updated
Running composer update magento/module-webapi-async
Loading composer repositories with package information
Updating dependencies
Lock file operations: 2 installs, 0 updates, 0 removals
  - Locking magento/module-webapi (100.4.1)
  - Locking magento/module-webapi-async (100.4.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 2 installs, 0 updates, 0 removals
  - Installing magento/module-webapi (100.4.1): Extracting archive
  - Installing magento/module-webapi-async (100.4.0): Extracting archive
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.
Package laminas/laminas-console is abandoned, you should avoid using it. Use laminas/laminas-cli instead.
Generating autoload files
46 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
taras@taras-home:/var/www/magento-framework-check$ bin/magento s:d:c
Compilation was started.
Plugin list generation... 9/9 [============================] 100% 6 secs 262.0 MiB
Generated code and dependency injection configuration successfully.

Так-так. Мне не снится? Похоже, это всё. Действительно, а то я уже хотел объявить, что всё совсем плохо и остановить дальнейшее копание.

В общем, морда работает, админка работает. Пора делать выводы.

Итог

Начнем снизу. Какие расширения PHP нам понадобилось включить сверх заявленного в системных требованиях Magento 2? Для Composer - 3: phar, dom, json.Это логично, ведь если Magento требует Composer, все его зависимости должны быть установлены - окей. Но есть еще и расширения, которые требует сама Magento, но которые были почему-то забыты в требованиях. Их 5:

pdo (впрочем, логично, что pdo_mysql без него не работает)
mysqlnd
tokenizer
mcrypt
fileinfo (скорее тут имеем баг, который лечится установкой расширения)

Теперь посмотрим, что у нас по пакетам composer. Вот модули, которые пришлось по ставить вручную (magento2-base был отправной точкой), чтобы заставить Magento 2 работать:

"require": {
  "colinmollenhour/cache-backend-file": "^1.4",
  "colinmollenhour/cache-backend-redis": "^1.14",
  "magento/framework": "^103.0",
  "magento/magento2-base": "^2.4",
  "magento/module-admin-notification": "^100.4",
  "magento/module-configurable-product": "^100.4",
  "magento/module-cookie": "^100.4",
  "magento/module-search": "^101.1",
  "magento/module-store": "^101.1",
  "magento/module-webapi-async": "^100.4",
  "magento/theme-adminhtml-backend": "^100.4",
  "magento/theme-frontend-luma": "^100.4",
  "webonyx/graphql-php": "^14.9"
}

Многие из них - явно забытые зависимости. О причинах этого мне судить сложно. Если модуль действительно не работает без другого модуля, какой смысл не указывать его в composer.json и module.xml? Если у кого-то есть догадки - пишите.

Вот список 72 модулей Magento, которые установились по итогу:

список
composer
framework
framework-bulk
framework-message-queue
magento-composer-installer
magento2-base
module-admin-notification
module-asynchronous-operations
module-authorization
module-backend
module-backup
module-bundle
module-captcha
module-catalog
module-catalog-import-export
module-catalog-inventory
module-catalog-rule
module-catalog-search
module-catalog-url-rewrite
module-checkout
module-cms
module-cms-url-rewrite
module-config
module-configurable-product
module-contact
module-cookie
module-cron
module-customer
module-deploy
module-developer
module-directory
module-downloadable
module-eav
module-email
module-gift-message
module-import-export
module-indexer
module-integration
module-media-storage
module-msrp
module-newsletter
module-page-cache
module-payment
module-product-alert
module-quote
module-reports
module-require-js
module-review
module-rss
module-rule
module-sales
module-sales-rule
module-sales-sequence
module-search
module-security
module-shipping
module-store
module-tax
module-theme
module-translation
module-ui
module-url-rewrite
module-user
module-variable
module-webapi
module-webapi-async
module-widget
module-wishlist
theme-adminhtml-backend
theme-frontend-blank
theme-frontend-luma
zendframework1

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

пример
$ bin/magento module:disable Magento_Wishlist
Unable to change status of modules because of the following constraints:
Cannot disable Magento_Wishlist because modules depend on it:
Magento_Store: Magento_Store->Magento_Customer->Magento_Wishlist
Magento_Directory: Magento_Directory->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_Theme: Magento_Theme->Magento_Customer->Magento_Wishlist
Magento_Config: Magento_Config->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_Backup: Magento_Backup->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_Variable: Magento_Variable->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_Eav: Magento_Eav->Magento_Catalog->Magento_Wishlist
Magento_Customer: Magento_Customer->Magento_Wishlist
Magento_CatalogImportExport: Magento_CatalogImportExport->Magento_Customer->Magento_Wishlist
Magento_AdminNotification: Magento_AdminNotification->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_Indexer: Magento_Indexer->Magento_Backend->Magento_Customer->Magento_Wishlist
Magento_Cms: Magento_Cms->Magento_Catalog->Magento_Wishlist
Magento_Catalog: Magento_Catalog->Magento_Wishlist
Magento_Payment: Magento_Payment->Magento_Sales->Magento_Wishlist
Magento_Quote: Magento_Quote->Magento_Customer->Magento_Wishlist
Magento_CmsUrlRewrite: Magento_CmsUrlRewrite->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_Backend: Magento_Backend->Magento_Customer->Magento_Wishlist
Magento_Msrp: Magento_Msrp->Magento_Catalog->Magento_Wishlist
Magento_Contact: Magento_Contact->Magento_Customer->Magento_Wishlist
Magento_Cookie: Magento_Cookie->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_Cron: Magento_Cron->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_Bundle: Magento_Bundle->Magento_Customer->Magento_Wishlist
Magento_Deploy: Magento_Deploy->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_Developer: Magento_Developer->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_Authorization: Magento_Authorization->Magento_Backend->Magento_Customer->Magento_Wishlist
Magento_Downloadable: Magento_Downloadable->Magento_Customer->Magento_Wishlist
Magento_Rule: Magento_Rule->Magento_Catalog->Magento_Wishlist
Magento_Email: Magento_Email->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_ImportExport: Magento_ImportExport->Magento_Catalog->Magento_Wishlist
Magento_CatalogRule: Magento_CatalogRule->Magento_Customer->Magento_Wishlist
Magento_Security: Magento_Security->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_MediaStorage: Magento_MediaStorage->Magento_Catalog->Magento_Wishlist
Magento_Sales: Magento_Sales->Magento_Wishlist
Magento_Widget: Magento_Widget->Magento_Catalog->Magento_Wishlist
Magento_PageCache: Magento_PageCache->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_CatalogInventory: Magento_CatalogInventory->Magento_Customer->Magento_Wishlist
Magento_ProductAlert: Magento_ProductAlert->Magento_Customer->Magento_Wishlist
Magento_Checkout: Magento_Checkout->Magento_Customer->Magento_Wishlist
Magento_Reports: Magento_Reports->Magento_Wishlist
Magento_Review: Magento_Review->Magento_Customer->Magento_Wishlist
Magento_Rss: Magento_Rss->Magento_Customer->Magento_Wishlist
Magento_Search: Magento_Search->Magento_Reports->Magento_Wishlist
Magento_GiftMessage: Magento_GiftMessage->Magento_Customer->Magento_Wishlist
Magento_SalesRule: Magento_SalesRule->Magento_Customer->Magento_Wishlist
Magento_Captcha: Magento_Captcha->Magento_Customer->Magento_Wishlist
Magento_CatalogSearch: Magento_CatalogSearch->Magento_Customer->Magento_Wishlist
Magento_User: Magento_User->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_Ui: Magento_Ui->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_ConfigurableProduct: Magento_ConfigurableProduct->Magento_Customer->Magento_Wishlist
Magento_Tax: Magento_Tax->Magento_Customer->Magento_Wishlist
Magento_AsynchronousOperations: Magento_AsynchronousOperations->Magento_Backend->Magento_Customer->Magento_Wishlist
Magento_Translation: Magento_Translation->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_Shipping: Magento_Shipping->Magento_Customer->Magento_Wishlist
Magento_UrlRewrite: Magento_UrlRewrite->Magento_Catalog->Magento_Wishlist
Magento_Integration: Magento_Integration->Magento_Customer->Magento_Wishlist
Magento_CatalogUrlRewrite: Magento_CatalogUrlRewrite->Magento_Catalog->Magento_Wishlist
Magento_Webapi: Magento_Webapi->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_WebapiAsync: Magento_WebapiAsync->Magento_Webapi->Magento_Store->Magento_Customer->Magento_Wishlist
Magento_Newsletter: Magento_Newsletter->Magento_Customer->Magento_Wishlist

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

И меня терзают смутные сомнения насчет возможности это исправить. Думаю, это уже не исправят (по принципу "работает - не трогай").

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

Комментарии (12)


  1. tommyangelo27
    06.08.2021 19:45
    +4

    В первой Мадженте ещё можно было что-то подобное провернуть (хотя тоже, вроде бы, Magento_Catalog нельзя было отключить). Ну а в двойке просто нереально…

    Ну и в целом у системы чем дальше, тем больше проблем. Фичи новые пилят, а число багов с каждым релизом только растёт. После релиза было вроде около 400 открытых issue, сейчас уже 1100.


    1. Audiophile Автор
      06.08.2021 21:35
      +2

      Даже не знаю. В первой мадженте по-моему вообще всё плохо с архитектурой. Эти статические методы везде, object manager (точнее, там аналог его - уже забыл это как страшный сон), никакого Composer.
      Во второй есть хорошие подвижки последнее время - переходят на команды с репозиториев, внедряют CQRS, service contracts во всю. Но вот старый код так и лежит. И ничего уже с ним не сделаешь - хоть Magento 3 пиши.
      Но с другой стороны, привлекают, похоже, много не вполне компетентных разрабов. И качество кода страдает.


      1. tommyangelo27
        07.08.2021 10:00

        Да да, естественно Magento 1 безнадёжно устарела. Я просто помню собственные попытки в далёком 2013 году сделать то же, что и вы (платформу для разработки не e-commerce проектов). Только композера не было, и я просто отключал модули, пытаясь добиться работоспособности фронта и админки.

        Будет ли новая версия Adobe Commerce — скорее да, но будет ли это эволюция Magento, или они купят другую платформу (возможно даже не на php)?


    1. snuk182
      06.08.2021 22:42
      +1

      Мне первая маджента по SOAP возвращала ответ на запрос товаров по фильтру шесть секунд. С удовольсвием перешел на вторую, которая уже умеет REST + GraphQL за полсекунды вместо шести. Правда, она недокументирована, и половина фильтров не работают, ну то уже такое.


      1. tommyangelo27
        07.08.2021 09:54
        +1

        Magento 1 тоже умеет REST, если что (но, конечно, никакого GraphQL из коробки). Скорость ответа сильно зависит от размера каталога… Припоминаю проект с каталогом на 500 тыс товаров, где приходилось реиндекс запускать раз в неделю ночью по субботам, иначе всё рушилось.

        В двойке производительность очень сильно завязана на число вебсайтов/сторов. С одним-двумя работать будет в меру быстро, даже с большим каталогом. Если же разных скоупов 7-10 — начинаются критические просадки, которые уже практически не лечатся…


        1. snuk182
          08.08.2021 00:34

          И все равно все проблемы меркнут перед самой главной. Нет документации. Ну то есть 'function getRecentProducts gets recent products' - это не документация. Впрочем это похоже на системный факап продуктов Adobe - понять, как работает CQ/AEM можно было только с дебаггером.


          1. Djeux
            09.08.2021 10:40

            Ну или зачем писать документацию когда можно продавать курсы.


    1. zhartaunik
      07.08.2021 09:39

      Я лично не помню,чтобы количество багов падало меньше 900. Обычно до нового релиза фиксят багов 100-200 и после релиза оно вновь со временем возвращается на заветное число в 1100. Так и имеем 900-1100-900-1100


      1. tommyangelo27
        07.08.2021 09:48

        Я лично не помню, чтобы количество багов падало меньше 900.

        Было-было, я с самого первого релиза двойки за этим цирком наблюдаю (на мадженто работаю с 2013 года).


  1. flancer
    06.08.2021 21:34
    +3

    Коллега, преклоняюсь перед вашим героизмом - всё-таки дойти до конца квеста! Я лет 10 сидел на Magento 1-2 и в конце-концов оставил надежды, что в этого монстра удастся вдохнуть жизнь. Но сама платформа очень интересная, как и её история.


  1. 06romix
    07.08.2021 09:39

    Теж пробував використати Magento 2 для свого проекту але зрозумів що надто велика частина фреймворку залежна від реалізації інтерфейсів мадженто модулями.

    Жаль що такий потужний фреймворк має дуже обмежене застосування.


  1. oxidmod
    11.08.2021 15:40

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