Skip to content

Allow setup:upgrade and setup:db-data:upgrade to run with a read-only app/etc (#26292) - #41153

Open
lbajsarowicz wants to merge 4 commits into
magento:2.4-developfrom
lbajsarowicz:fix/26292-read-only-app-etc-upgrade
Open

Allow setup:upgrade and setup:db-data:upgrade to run with a read-only app/etc (#26292)#41153
lbajsarowicz wants to merge 4 commits into
magento:2.4-developfrom
lbajsarowicz:fix/26292-read-only-app-etc-upgrade

Conversation

@lbajsarowicz

Copy link
Copy Markdown
Contributor

Description (*)

setup:upgrade --keep-generated and setup:db-data:upgrade cannot run when app/etc is read-only, which is the expected state for immutable deployments (prebuilt container images, Kubernetes, chmod 444 app/etc/*). Two independent causes, one commit each:

  1. Installer::updateModulesSequence() always rewrites app/etc/config.php.
    createModulesConfig() recomputes the modules array and calls Writer::saveConfig() unconditionally, even when the result is byte-for-byte what is already deployed. On a read-only config.php this fails with The "config.php" deployment config file isn't writable.
    Fix: only call saveConfig() when the computed module list differs (!==, so a changed module sequence still triggers a write) from the current modules section.

  2. FilePermissions::getMissingWritableDirectoriesForDbUpgrade() requires app/etc to be writable.
    Installer::installDataFixtures() runs this precondition, so setup:db-data:upgrade (and the data phase of setup:upgrade) aborts with Missing write permissions to the following paths: <root>/app/etc before touching the database. The DB upgrade itself writes only to the database and var/.
    Fix: drop DirectoryList::CONFIG from the list; var/ is still required. A patch that genuinely needs to write deployment configuration (e.g. Magento\Backend\Setup\Patch\Data\MigrateRedisBackendConfig) still gets a precise error from DeploymentConfig\Writer at the moment of the write instead of a blanket refusal up front.

No public signatures changed.

Related Pull Requests

Fixed Issues (if relevant)

  1. Fixes Read-only app/etc/ #26292

Manual testing scenarios (*)

  1. Install Magento 2.4-develop, run bin/magento setup:upgrade once so config.php is in sync.
  2. chmod 555 app/etc && chmod 444 app/etc/*
  3. bin/magento setup:upgrade --keep-generated
    • before: Upgrade failed: The "config.php" deployment config file isn't writable.
    • after: Upgrade completed successfully.
  4. bin/magento setup:db-data:upgrade
    • before: Missing write permissions to the following paths: /var/www/html/app/etc
    • after: completes, exit code 0.
  5. Restore permissions, enable/disable a module (bin/magento module:disable Magento_Wishlist), run bin/magento setup:upgrade --keep-generatedconfig.php is rewritten as before.

Questions or comments

Unit tests: setup/src/Magento/Setup/Test/Unit/Model/InstallerTest.php (write skipped when unchanged, write performed when module order changes) and lib/internal/Magento/Framework/Setup/Test/Unit/FilePermissionsTest.php (read-only app/etc not reported). Both new tests fail against 2.4-develop without the fix.

Contribution checklist (*)

  • Pull request has a meaningful description of its purpose
  • All commits are accompanied by meaningful commit messages
  • All new or changed code is covered with unit/integration tests (if applicable)
  • README.md files for modified modules are updated and included in the pull request if any README.md predefined templates (if applicable)
  • All automated tests passed successfully (all builds are green)

@lbajsarowicz

Copy link
Copy Markdown
Contributor Author

@magento run all tests

@m2-assistant

m2-assistant Bot commented Aug 26, 2026

Copy link
Copy Markdown

Hi @lbajsarowicz. Thank you for your contribution!
Here are some useful tips on how you can test your changes using Magento test environment.
❗ Automated tests can be triggered manually with an appropriate comment:

  • @magento run all tests - run or re-run all required tests against the PR changes
  • @magento run <test-build(s)> - run or re-run specific test build(s)
    For example: @magento run Unit Tests

<test-build(s)> is a comma-separated list of build names.

Allowed build names are:
  1. Database Compare
  2. Functional Tests CE
  3. Functional Tests EE
  4. Functional Tests B2B
  5. Integration Tests
  6. Magento Health Index
  7. Sample Data Tests CE
  8. Sample Data Tests EE
  9. Sample Data Tests B2B
  10. Static Tests
  11. Unit Tests
  12. WebAPI Tests
  13. Semantic Version Checker

You can find more information about the builds here
ℹ️ Run only required test builds during development. Run all test builds before sending your pull request for review.


For more details, review the Code Contributions documentation.
Join Magento Community Engineering Slack and ask your questions in #github channel.

@lbajsarowicz

Copy link
Copy Markdown
Contributor Author

@magento run all tests

1 similar comment
@lbajsarowicz

Copy link
Copy Markdown
Contributor Author

@magento run all tests

Installer::updateModulesSequence() unconditionally rewrote the "modules"
section of app/etc/config.php on every setup:upgrade run, even when the
resulting list was identical to what is already deployed. On read-only
deployments (immutable container images, chmod 444 app/etc/*) this made
setup:upgrade --keep-generated fail with:

    The "config.php" deployment config file isn't writable.

Only write the file when the computed module list actually differs.
FilePermissions::getMissingWritableDirectoriesForDbUpgrade() listed app/etc
as a directory that must be writable, so setup:db-data:upgrade (and the data
phase of setup:upgrade) refused to start on read-only deployments with:

    Missing write permissions to the following paths:
    <root>/app/etc

Data and schema upgrade write to the database and var/ only. Keep the var/
check and drop app/etc from the precondition. A patch that genuinely needs
to write deployment configuration still gets a precise error from
DeploymentConfig\Writer at the moment of the write.
Add @see reference to the deprecated getMissingWritableDirectoriesForInstallation()
and fix indentation of use/attribute lines inside the braced namespace of InstallerTest.
@lbajsarowicz

Copy link
Copy Markdown
Contributor Author

@magento run all tests

@lbajsarowicz
lbajsarowicz force-pushed the fix/26292-read-only-app-etc-upgrade branch from 53545f2 to 1107ba6 Compare August 27, 2026 21:06
@lbajsarowicz

Copy link
Copy Markdown
Contributor Author

@magento run Unit Tests, WebAPI Tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Read-only app/etc/

1 participant