Skip to content

57 · Web installer fails on Apache with mod_php: Composer needs HOME or COMPOSER_HOME

Project Drupal CMS (drupal_cms), Drupal CMS installer profile
Component Installer
Category Bug report
Priority Major
Status Reported upstream as #3591481

Problem/Motivation

After the site template is chosen, the Drupal CMS installer runs Composer as the web server user (Drupal\drupal_cms_installer\ComposerExecutor, first for composer config extra.drupal-scaffold.allowed-packages). Composer refuses to run without HOME or COMPOSER_HOME. Apache with mod_php sets neither for PHP, so the installation stops right at the first batch step with an AJAX error:

Symfony\Component\Process\Exception\ProcessFailedException: The command
"'/usr/local/bin/php' '/var/www/cms/vendor/composer/./composer/bin/composer'
'--no-interaction' 'config' 'extra.drupal-scaffold.allowed-packages' '--merge'
'--json' '["drupal/haven"]'" failed.
...
The HOME or COMPOSER_HOME environment variable must be set for composer to run correctly

This happens with every site template, including the ones shipped with Drupal CMS.

Setting the variable for Apache alone is not enough: Symfony Process only passes on variables that are both in the environment of the process and in $_SERVER. It takes export COMPOSER_HOME=… in /etc/apache2/envvars and PassEnv COMPOSER_HOME.

Core's Package Manager already handles this: its ProcessFactory sets COMPOSER_HOME for every Composer process it starts.

Steps to reproduce

  1. Serve a fresh Drupal CMS with Apache and mod_php, e.g. the image drupalci/php-8.5-ubuntu-apache.
  2. Open /core/install.php, choose any site template (e.g. Haven) and create the account.
  3. The batch stops with the exception above.

Proposed resolution

Set COMPOSER_HOME in ComposerExecutor::execute() when neither HOME nor COMPOSER_HOME is set, as Package Manager's ProcessFactory does, e.g. to a directory below the temporary directory.

Additional information

Found with Drupal CMS 2.2 while building a GitLab CI job that installs every site template through the web installer (October 2026). With PHP-FPM the installation works. Related: #3591473, where SiteTemplate::findAll() already sets COMPOSER_HOME when it is unset; ComposerExecutor does not. The CI job of the Drupal CMS German Installer sets the variable for Apache as a workaround. Not a translation problem.

Copy to drupal.org

Issue title:

Web installer fails on Apache with mod_php: Composer needs HOME or COMPOSER_HOME

Issue summary (paste it into the "Issue summary" field; project, component, category and priority are in the table above):

<h3 id="summary-problem-motivation">Problem/Motivation</h3>
<p>After the site template is chosen, the Drupal CMS installer runs Composer as the web server user (<code>Drupal\drupal_cms_installer\ComposerExecutor</code>, first for <code>composer config extra.drupal-scaffold.allowed-packages</code>). Composer refuses to run without <code>HOME</code> or <code>COMPOSER_HOME</code>. Apache with mod_php sets neither for PHP, so the installation stops right at the first batch step with an AJAX error:</p>
<code>Symfony\Component\Process\Exception\ProcessFailedException: The command
"'/usr/local/bin/php' '/var/www/cms/vendor/composer/./composer/bin/composer'
'--no-interaction' 'config' 'extra.drupal-scaffold.allowed-packages' '--merge'
'--json' '["drupal/haven"]'" failed.
...
The HOME or COMPOSER_HOME environment variable must be set for composer to run correctly</code>
<p>This happens with every site template, including the ones shipped with Drupal CMS.</p>
<p>Setting the variable for Apache alone is not enough: Symfony Process only passes on variables that are both in the environment of the process and in <code>$_SERVER</code>. It takes <code>export COMPOSER_HOME=…</code> in <code>/etc/apache2/envvars</code> <strong>and</strong> <code>PassEnv COMPOSER_HOME</code>.</p>
<p>Core's Package Manager already handles this: its <code>ProcessFactory</code> sets <code>COMPOSER_HOME</code> for every Composer process it starts.</p>
<h3 id="summary-steps-reproduce">Steps to reproduce</h3>
<ol>
<li>Serve a fresh Drupal CMS with Apache and mod_php, e.g. the image <code>drupalci/php-8.5-ubuntu-apache</code>.</li>
<li>Open <code>/core/install.php</code>, choose any site template (e.g. Haven) and create the account.</li>
<li>The batch stops with the exception above.</li>
</ol>
<h3 id="summary-proposed-resolution">Proposed resolution</h3>
<p>Set <code>COMPOSER_HOME</code> in <code>ComposerExecutor::execute()</code> when neither <code>HOME</code> nor <code>COMPOSER_HOME</code> is set, as Package Manager's <code>ProcessFactory</code> does, e.g. to a directory below the temporary directory.</p>
<h3>Additional information</h3>
<p>Found with Drupal CMS 2.2 while building a GitLab CI job that installs every site template through the web installer (October 2026). With PHP-FPM the installation works. Related: <a href="https://git.drupalcode.org/project/drupal_cms/-/work_items/3591473">#3591473</a>, where <code>SiteTemplate::findAll()</code> already sets <code>COMPOSER_HOME</code> when it is unset; <code>ComposerExecutor</code> does not. The CI job of the Drupal CMS German Installer sets the variable for Apache as a workaround. Not a translation problem.</p>