Migrate an existing Drupal site into a Composer-managed build

For the sites created on Drupal 8.8.0 or later, even if it was installed manually, Composer was pre-installed, and the files already contain the necessary Composer configuration, which means managing the site using composer would be convenient without taking any extra steps on converting it. 

The goal is to have your project the currently recommended directory structure:

  • Composer configuration (composer.json, composer.lock, etc.), drush, and the vendor's directory will be placed outside of your webroot.
  • Base-level directories (modules, profiles, sites, themes) and core directories will be placed inside the parent directory(webroot) called web/.

Before diving into the procedure, we should take note first of the correct file structure for it will be essential if the site is ready to be converted to a Composer-managed build. To follow proper file structure guidelines, It is recommended you start with a website generally structured the way you want the website built. Best practices are as follows:

  • Contributed modules should be placed in webroot/modules/contrib.
  • Custom modules should be placed in webroot/modules/custom.
  • All third-party external libraries should be placed in webroot/libraries
  • Place all contributed and custom installation profiles in /profile.
  • Same as the usual, themes shall be placed in webroot/themes/contrib for contributed themes while webroot/themes/custom for your own themes.

Note: If your files are not yet in their recommended directories, consider moving all of them to the specified location.

Now that we have known the correct file structure, let’s proceed with migrating your site into a Composer-managed build. Here are the steps.

Install new Drupal site 

Create a new Drupal project from the drupal/recommended-project template by running this command:

composer create-project drupal/recommended-project new_project --stability dev --no-interaction

Note: For this example, we’ll be using new_project as a project name. You can always change that as you please

This will create the directory new_project/ holding the vendors and web (= webroot) directories and your composer.json, files, etc.


Copy files to the new Composer project

Copy your old project’s modules, theme, and libraries to the new project’s directory. Make sure you put the files in the right directories in your new project (following the correct file structuring abovementioned), as your old folder structure might differ.

The right paths can be also found in your composer.json's "installer-paths" section.


Transfer settings.php to the new project

Copy the database connection information from your old settings.php to the new project. Simply compare the two settings.php files to see what needs to be copied.Most importantly are the $databases['default']['default'], the $settings['hash salt'] and the $settings['trusted host patterns'] arrays, and probably other some custom settings made.

Another important thing is the $config_directories['sync']. It should be pointing to the correct and existing directory that is probably outside your webroot, where composer.json is found or this might also be pointing to some files in your sites/default/files/ directory. Path defined should be existing and is writeable by your web server user. Lastly, copy as well the development settings files settings.local.php and development.services.yml to the new project.


Add contributed modules to the new Composer config

The require section should include a list of all modules required to run your website in production. Add all your project's contributed modules to the new composer.json file in your new webroot. You can either add the modules manually to your composer.json or use the composer require command on each module to add the latest versions of all modules to your site.

There are two ways to manually add all the modules to your composer.json file, You could also manually collect a list of all contributed (not custom) modules by getting a directory listing of your old site's modules/contrib/ or modules/ directory (depending on your setup).

Or generate a list of all enabled contributed modules by running the following Drush command:
drush pml --status=Enabled --no-core

This should display all the enabled contributed modules.
In the composer.json you will just prepend drupal/ to each of the modules' directory names. For example, modules/contrib/devel/ becomes drupal/devel.
Using the manual approach you'll have to care for the proper (latest) versions of the modules yourself.

Aside from adding modules manually, you could also run composer require drupal/<module name> for each of the required modules.  Adding all your modules at once can also be done by running composer require drupal/module-name-1 drupal/module-name-2 drupal/module-name-i. Use composer require --dev drupal/<module name> to add a module to the "require-dev" section of the composer.json file.

It is also important to place development packages in the "require-dev" section like drupal/devel or drupal/kint.


Finalize Composer installation

Run composer install command from your project directory. This will download all modules that you added to composer.json. If happen, Sometimes problems with Composer templates can be solved by removing the composer lock file and the vendor directory and then try again.

This should create a composer.lock file, recreate webroot/autoload.php if the file does not exist, and install all the packages required in the composer.json file into the proper directory.


Update database and clear cache

Run the drush updb command to apply all available database updates.
Then clear your Drupal caches by running the drush cr command.

Or you could run the update.php by visiting the site ([domain]/update.php).


Update web server configuration

If your old project uses a different directory layout, you will have to update your web server configuration to point to the new web/ directory. In our example, var/www/sites/new_project/web/.

If php-fpm setup is being used, it is necessary to update its settings to point it to the new webroot. For example, /etc/php/7.2/fpm/pool.d/yoursite.conf.

Don't forget to clear all cache after updating configs.

Now that all procedures abovementioned were followed, You have to check your site's reports to make sure you're not seeing a bunch of warnings or error messages.

Enjoy your new Composer-managed build site!

Profile picture for user Jamaica Angely Mañus
Jamaica Angely Mañus Software Developer

I was born and raised in one of the highly urbanized cities of the Philippines. Never traveled outside the country yet but it has always been my biggest dream. I learned things in life at a very young age as the only person in the household who brings in the lion's share of income. Growing up with such responsibility drives me to become a better version of myself each time. Failure and determination were my key ingredients to keep going forward. Being part of Acret-PH is something I will always be grateful for. In fact, I'm rooting for a wonderful journey ahead while making progress each time.