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 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!