Skip to content

Remove setup/ directory dependency from production artifacts #40695

@lbajsarowicz

Description

@lbajsarowicz

Problem Statement

The setup/ directory (568 tracked files) is a hard runtime dependency for every bin/magento invocation, even though the web Setup Wizard has been deprecated and disabled in nginx.conf.sample. Production runtime artifacts cannot omit it without breaking operational CLI commands such as cache:flush, indexer:reindex, or cron:run.

Reproducible failure

rm -rf setup
php bin/magento cache:flush
# PHP Fatal: require(): Failed opening required '.../setup/config/application.config.php'
# at lib/internal/Magento/Framework/Console/Cli.php:97

Operational commands have no logical reason to depend on the Setup Wizard application, yet a missing setup/ aborts CLI dispatch before any command runs.

Current coupling

  1. Magento\Framework\Console\Cli::__construct() unconditionally executes:

    $configuration = require BP . '/setup/config/application.config.php';

    bootstrapping a Laminas ServiceManager for every CLI call.

  2. app/etc/di.xml maps runtime Framework interfaces to Magento\Setup\*:

    <preference for="Magento\Framework\Setup\SchemaSetupInterface" type="Magento\Setup\Module\Setup" />
    <preference for="Magento\Framework\Setup\ModuleDataSetupInterface" type="Magento\Setup\Module\DataSetup" />
  3. Magento\Backend maintenance commands extend Magento\Setup\Console\Command\AbstractSetupCommand, which transitively depends on Magento\Setup\Mvc\Bootstrap\InitParamListener (annotated @deprecated"Web Setup support has been removed, this class is no longer in use.").

  4. composer.json PSR-4 + app/etc/registration_globlist.php both reference setup/.

What setup/ actually contains (current 2.4-develop)

Path Files Role
setup/src/Magento/Setup/Module/Di/ 56 DI compiler (build-time)
setup/src/Magento/Setup/Console/ 38 CLI commands incl. setup:*
setup/src/Magento/Setup/Module/I18n/ 35 i18n collection (build-time)
setup/src/Magento/Setup/Module/Dependency/ 27 Dependency analysis (dev)
setup/pub/ 19 Static assets for Web Wizard
setup/performance-toolkit/ 18 Dev fixtures
setup/view/ 5 Laminas templates (dead)
setup/src/Magento/Setup/Mvc/ 2 Laminas MVC listeners (@deprecated)
... ~370 Setup application + config + tests

Web installer deprecation is documented on Magento\Setup\Mvc\View\Http\InjectTemplateListener and Magento\Setup\Mvc\Bootstrap\InitParamListener.

Scope

Goal: allow a runtime/web-node artifact to be built without setup/ while preserving operational CLI commands (cache:*, indexer:*, cron:*, config:*, module:*, maintenance:*).

Non-goal: setup:install, setup:upgrade, setup:di:compile, setup:static-content:deploy running without setup/. Those remain build-time / release-time concerns and continue to require the package.

This separates build/release artifacts (full tree including setup/) from runtime/web-node artifacts (slimmer, no Setup Wizard surface).

Proposed Short-term Changes (BC-preserving)

  1. Guard Cli.php — wrap the require at Cli.php:97 in a file_exists() check; skip Setup ServiceManager bootstrap and SetupCommandLoader registration when absent. Non-setup commands dispatch normally.

  2. Framework-owned implementations of runtime setup interfaces — provide Magento\Framework\Setup\Module\Setup / ModuleDataSetup and update app/etc/di.xml preferences. Keep Magento\Setup\Module\Setup and Magento\Setup\Module\DataSetup as class_alias BC shims (@api is preserved). Loaded only when setup/ present; runtime artifact uses the Framework class directly.

  3. Decouple AbstractSetupCommand from Magento\Setup\Mvc — extract the --magento-init-params option handling out of the deprecated Laminas listener so Backend maintenance commands no longer pull setup/Mvc/.

  4. registration_globlist.phpsetup/src/*/*/registration.php glob is harmless when path is absent (returns empty). No change required.

After these changes, deploying a web node without setup/ is a packaging-layer choice, not a code change.

Proposed Long-term Changes (next major)

  1. Register setup:* commands via standard di.xml command_list, eliminating the Laminas ServiceManager bootstrap entirely.
  2. Delete the dead web installer code (setup/view/, setup/pub/, setup/src/Magento/Setup/Mvc/).
  3. Extract build-time tooling (Module/Di, Module/I18n, Module/Dependency) into a separate magento/setup-tools package so production projects do not pull DI-compiler classes via Composer.

Impact

  • Attack-surface reduction: web nodes stop carrying a deprecated Laminas MVC entry point. setup/index.php is denied in nginx.conf.sample, but Apache deployments rely on per-vhost rules that are easy to misconfigure. The safest file is the absent file.
  • Performance: every bin/magento invocation currently bootstraps Laminas ServiceManager purely to register setup commands. Benchmarks (to be attached) for bin/magento list, cache:flush, cron:run will quantify wall-time and memory savings.
  • Composer graph: removing the runtime requirement on laminas/laminas-mvc and friends simplifies dependency resolution against modern tooling.
  • Architecture: removes the last Laminas MVC dependency from the runtime CLI path — the "final decoupling" already done elsewhere in the stack.

Backward Compatibility

  • Magento\Setup\Module\Setup + DataSetup remain available as class_alias shims when setup/ is present.
  • AbstractSetupCommand remains in place; only its dependency on the deprecated Mvc\Bootstrap\InitParamListener is severed.
  • No public method signature changes.
  • Deprecation window for Magento\Setup\* runtime classes can follow standard policy.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions