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
-
Magento\Framework\Console\Cli::__construct() unconditionally executes:
$configuration = require BP . '/setup/config/application.config.php';
bootstrapping a Laminas ServiceManager for every CLI call.
-
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" />
-
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.").
-
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)
-
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.
-
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.
-
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/.
-
registration_globlist.php — setup/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)
- Register
setup:* commands via standard di.xml command_list, eliminating the Laminas ServiceManager bootstrap entirely.
- Delete the dead web installer code (
setup/view/, setup/pub/, setup/src/Magento/Setup/Mvc/).
- 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.
Problem Statement
The
setup/directory (568 tracked files) is a hard runtime dependency for everybin/magentoinvocation, even though the web Setup Wizard has been deprecated and disabled innginx.conf.sample. Production runtime artifacts cannot omit it without breaking operational CLI commands such ascache:flush,indexer:reindex, orcron:run.Reproducible failure
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
Magento\Framework\Console\Cli::__construct()unconditionally executes:bootstrapping a Laminas
ServiceManagerfor every CLI call.app/etc/di.xmlmaps runtime Framework interfaces toMagento\Setup\*:Magento\Backendmaintenance commands extendMagento\Setup\Console\Command\AbstractSetupCommand, which transitively depends onMagento\Setup\Mvc\Bootstrap\InitParamListener(annotated@deprecated— "Web Setup support has been removed, this class is no longer in use.").composer.jsonPSR-4 +app/etc/registration_globlist.phpboth referencesetup/.What
setup/actually contains (current 2.4-develop)setup/src/Magento/Setup/Module/Di/setup/src/Magento/Setup/Console/setup:*setup/src/Magento/Setup/Module/I18n/setup/src/Magento/Setup/Module/Dependency/setup/pub/setup/performance-toolkit/setup/view/setup/src/Magento/Setup/Mvc/@deprecated)Web installer deprecation is documented on
Magento\Setup\Mvc\View\Http\InjectTemplateListenerandMagento\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:deployrunning withoutsetup/. 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)
Guard
Cli.php— wrap therequireatCli.php:97in afile_exists()check; skip SetupServiceManagerbootstrap andSetupCommandLoaderregistration when absent. Non-setup commands dispatch normally.Framework-owned implementations of runtime setup interfaces — provide
Magento\Framework\Setup\Module\Setup/ModuleDataSetupand updateapp/etc/di.xmlpreferences. KeepMagento\Setup\Module\SetupandMagento\Setup\Module\DataSetupasclass_aliasBC shims (@apiis preserved). Loaded only whensetup/present; runtime artifact uses the Framework class directly.Decouple
AbstractSetupCommandfromMagento\Setup\Mvc— extract the--magento-init-paramsoption handling out of the deprecated Laminas listener so Backend maintenance commands no longer pullsetup/Mvc/.registration_globlist.php—setup/src/*/*/registration.phpglob 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)
setup:*commands via standarddi.xmlcommand_list, eliminating the LaminasServiceManagerbootstrap entirely.setup/view/,setup/pub/,setup/src/Magento/Setup/Mvc/).Module/Di,Module/I18n,Module/Dependency) into a separatemagento/setup-toolspackage so production projects do not pull DI-compiler classes via Composer.Impact
setup/index.phpis denied innginx.conf.sample, but Apache deployments rely on per-vhost rules that are easy to misconfigure. The safest file is the absent file.bin/magentoinvocation currently bootstraps LaminasServiceManagerpurely to register setup commands. Benchmarks (to be attached) forbin/magento list,cache:flush,cron:runwill quantify wall-time and memory savings.laminas/laminas-mvcand friends simplifies dependency resolution against modern tooling.Backward Compatibility
Magento\Setup\Module\Setup+DataSetupremain available asclass_aliasshims whensetup/is present.AbstractSetupCommandremains in place; only its dependency on the deprecatedMvc\Bootstrap\InitParamListeneris severed.Magento\Setup\*runtime classes can follow standard policy.