Drupal 8: Composer based installation and Multiple Drushes

David G - DrupalRecently at work I started working with Drupal 8 RC1. In the past I’ve attempted to work on Drupal 8 but with early adoption I ran into issues such as trying to run an older version of Drush for my Drupal 7 sites, and a newer version of Drush for Drupal 8. I also ran into the issue of trying to find a simple means to include module(s) and updates from 3rd party code into my Drupal 8 sandbox. In beginning to work with RC1 I found this very interesting github project which creates a Drupal 8 project and manages it’s dependencies via Composer. This project is called: drupal-project and it is a composer template for starting a drupal 8 website project.

With my foray into using Composer based Drupal project building I took copious notes along the way. Herein you’ll find some of my observations.

First you need to assure you’ve installed Composer, the easiest solution is to install it globally on your system. If you’ve already installed Composer for a previous project I recommend occasionally running composer self-update to assure you’re running the latest version of composer. Working with new technologies it’s good to assure you’re running the latest stable version of dependencies.

After installing Composer you can easily create a new Drupal 8 project based around a Composer build process with the following command:

composer create-project drupal-composer/drupal-project:8.x-dev \
project-dir --stability dev --no-interaction

Then in order to address my first issue of Drupal projects regarding differing Drush versions — I found out that different versions of Drush can be installed locally via Composer. So from project-dir you can install Drush locally for the project following the Composer One Drush Per Project directions.

cd project-dir
composer require drush/drush:dev-master
composer update // for already created repository

Then your project will have a drush installation and wrapper file called drush.wrapper at <project-dir>/web/vendor/drush/drush/examples. It is recommended this wrapper file be moved to your drupal root directory for Drupal 8. When you want to use Drush to enable modules or run cache-clear or updb — you will do so using drush.wrapper and not any globally defined drush command on your system.

So now if you try to invoke drush.wrapper you will get the latest version:

dgurba at aw-dgurba in .../id-site-2015/www on master▲
$ ./drush.wrapper --version
 Drush Version   :  8.0-dev

Note: please read the file drush.wrapper as it contains many useful comments about how to use the wrapper file if you’re using Composer and other such tools. I ended up modifying the file so that the local vendor/drush folder was looked for installed drush extensions and so that my site alias file(s) were found in the local composer project space. My changes look like this:

# Tell this local copy of Drush where to find includes and alias files.
cd "`dirname $0`" vendor/bin/drush.launcher --include=$inc --alias-path=./drush "$@"

So, we have a Drupal 8 project whose dependencies are being powered by Composer, and have a local copy of Drush installed. What can do we with it? How do we use it?

This is covered in the drupal-project wiki briefly but adding a module to the drupal site can be done by issueing the following command:

cd project-dir
composer require drupal/devel:8.*
composer update

This simply adds a line to the composer.json file if you look at the file after runing composer require.

This is how I installed the Drush tool virtualhost for this project. By adding the following to my composer.json file. This is also why I wanted to setup my drush include path to find installed extensions:

"require": {
    "davereid/drush-virtualhost": "dev-master",

So say you want to install a new drupal site using the drush wrapper, you might try:

dgurba at aw-dgurba in .../id-site-2015/www on master▲ $
./drush.wrapper --root=/var/www/2015/instructional_development/id-site-2015/www/web/ \
site-install standard --db-url=mysql://dev_user:******@localhost/id-site-2015 \
--account-mail=test@test.com --account-name=_admin \
--account-pass=****** --site-email=test@test.com \
--site-name="ID 2015" --sites-subdir=id_site_2015

And note if you leave off the –root option above you’ll get this gloriously obtuse error message:

dgurba at aw-dgurba in .../id-site-2015/www on master▲ $
./drush.wrapper site-install standard
--account-mail=webdev@id.ucsb.edu --account-name=_admin --account-pass=***** 
--site-mail=webdev@id.ucsb.edu --site-name="ID 2015" --sites-subdir=id_site_2015

Command site-install needs a higher bootstrap level to run - you
will need to invoke drush from a more functional Drupal
environment to run this command. [error] The drush command
'site-install standard' could not be executed. [error]

So when using site-install initially, be sure to include the –root option. But, man oh  man, it would suck to have to pass –root for calls using enable, disable, pm-uninstall … so we can fix that by making our project site’s alias file. Then we can simply call:

dgurba at aw-dgurba in .../id-site-2015/www on master▲
$ ./drush.wrapper @inst.local status
 Drupal version                  :  8.0.0-rc1
 Site URI                        :  id-site-2015.example

This was the point to modifying drush.wrapper in the first few steps of this blog post, so that it may find our alias files as needed.

So then as stated way above … new dependencies can easily be included by using Composer, and then enabled using Drush. For a simple module that workflow would be:

dgurba at aw-dgurba in .../id-site-2015/www on master▲
composer require drupal/migrate_plus: 8.1.*@dev;
composer require drupal/migrate_upgrade: 8.1.*@dev;
# ...

dgurba at aw-dgurba in .../id-site-2015/www on master▲
$ ./drush.wrapper @inst.local en migrate_plus migrate_upgrade;
The following extensions will be enabled: migrate_plus migrate_upgrade
Do you really want to continue? (y/n): y
# ...

Lastly, this whole drupal-project composer template sets up Drupal with certain pre-configured directories as outlined in the documentation. I opted to use my own multi-site subdirectory in sites for Drupal for my example drupal website. When I call composer require drupal/SOMEMODULE in my case it’s really downloading to my subsite folder. I do this by modifying the default composer.json file to change the predefined installer paths to my own:

    "extra": {
        "installer-paths": {
            "web/core": ["type:drupal-core"],
            "web/sites/id_site_2015/modules/contrib/{$name}": ["type:drupal-module"],
            "web/sites/id_site_2015/themes/contrib/{$name}": ["type:drupal-theme"],
            "web/profiles/contrib/{$name}": ["type:drupal-profile"],
            "drush/contrib/{$name}": ["type:drupal-drush"]

So I hope you can see how you can use Composer, a local version of Drush and a VCS tool to manage and build your website in a sane fashion. I’m not a fan of how .json files have no comment syntax support. But, I’m hoping this type of build process makes managing Drupal 8 based projects easier. The alternative to this is to use Drush Make, which I’ve written about before. Happy Developing!

Looking for quality web hosting? Look no further than Arvixe Web Hosting!

Tags: , , , , | Posted under Drupal, Drush | RSS 2.0

Author Spotlight

David Gurba

I am a web programmer currently employed at UCSB. I have been developing web applications professionally for 8+ years now. For the last 5 years I’ve been actively developing websites primarily in PHP using Drupal. I have experience using LAMP and developing data driven websites for clients in aviation, higher education and e-commerce. If you’d like to contact me I can be reached at david.gurba@arvixe.com

Leave a Reply

Your email address will not be published. Required fields are marked *