Drupal 8 and Composer on Pantheon Without Continuous Integration

Learn how to manage Drupal 8 using Composer with Pantheon.

Contributors: Andrew Taylor, Dwayne McDaniel, David Needham

In this guide, we’re going to run through the bare necessities to use Composer for managing a Drupal 8 site on your local machine and pushing to Pantheon.

Using a Composer managed site removes the ability to apply Drupal core updates via the site dashboard. This is for advanced users who are comfortable taking complete responsibility for the management of site updates with Composer.

Creating the Pantheon Site

To begin, we’ll want to start a brand new Drupal 8 site on Pantheon from our empty upstream. This upstream is different from the Drupal 8 upstream in that it does not come with any Drupal files. As such, you must use Composer to download Drupal.

Before we begin choose a machine-friendly site name. It should be all lower case with dashes instead of spaces. I'll use d8-composer-no-ci but choose your own. Once you have a site name export it to a variable for re-use.

export PANTHEON_SITE_NAME="d8-composer-no-ci"

You should also be authenticated with Terminus. See the Authenticate into Terminus section of the machine tokens documentation for details.

Create a new Pantheon site with an empty upstream.

terminus site:create $PANTHEON_SITE_NAME 'My D8 Composer Site' empty

Note you can also add the --org argument to terminus site:create if you would like the site to be part of an organization. See terminus site:create -h for details and help.

Cloning example-drops-8-composer Locally

Instead of setting up composer.json manually, it is easier to start with the example-drops-8-composer repository.

  1. Clone the example-drops-8-composer repository locally:

    git clone git@github.com:pantheon-systems/example-drops-8-composer.git $PANTHEON_SITE_NAME
  2. cd into the cloned directory:


Updating the Git Remote URL

  1. Store the Git URL for the Pantheon site created earlier in a variable:

    export PANTHEON_SITE_GIT_URL="$(terminus connection:info $PANTHEON_SITE_NAME.dev --field=git_url)"
  2. Update the Git remote to use the Pantheon site Git URL returned rather than the example-drops-8-composer GitHub URL:

    git remote set-url origin $PANTHEON_SITE_GIT_URL

Removing Automation Pieces

example-drops-8-composer was designed to run automated tests on a continuous integration server. Unless you plan on running automated tests it is safe to completely remove the automated testing functionality.

  1. Delete the following directories:
  • scripts/github
  • scripts/gitlab
  • .circleci
  • tests

2. Modify composer.json:

  • Remove all dependencies in the require-dev section.
  • Update the scripts section to remove the lint, code-sniff, and unit-test lines.
  • Remove the find .circleci/scripts/pantheon/ -type f | xargs chmod 755, line from the post-update-cmd section of scripts.
  • Remove the find tests/scripts/ -type f | xargs chmod 755 line from the post-update-cmd section of scripts.
    • You may need to remove a trailing comma from the end of the last item in the post-update-cmd section, otherwise the JSON will be invalid.
  1. Remove the following section from pantheon.yml:

         - type: webphp
           description: Push changes back to GitHub if needed
           script: private/scripts/quicksilver/quicksilver-pushback/push-back-to-github.php

Managing Drupal with Composer

Downloading Drupal Dependencies with Composer

Normally the next step would go through the standard Drupal installation. But since we’re using Composer, none of the core files exist yet. Let’s use Composer to download Drupal core.

  1. Since we modified composer.json we will need to update Composer. This will also download the defined dependencies:

    composer update

    This may take a while as all of Drupal core and its dependencies will be downloaded. Subsequent updates should take less time.

    image of terminal running a composer install

  2. And now we need to install:

    composer install
  3. Let's take a look at the changes:

    git status

    It appears that our web directory isn't being committed. This is because the example-drops-8-composer .gitignore file assumes that you’re using a build step with continuous integration.

  4. To make it compatible with this manual method, you need to edit the .gitignore file and remove everything above the :: cut :: section:

    Important: Without this modification, critical components such as Drupal core and contrib modules will be ignored and not pushed to Pantheon.

  5. Now let’s run git status again to make sure everything is included:

    git status

    Image of git status showing the changed files in red

  6. Set the site to git mode:

    terminus connection:set $PANTHEON_SITE_NAME.dev git
  7. Add and commit the code files. A Git force push is necessary because we are writing over the empty repository on Pantheon with our new history that was started on the local machine. Subsequent pushes after this initial one should not use --force:

    git add .
    git commit -m 'Drupal 8 and dependencies'
    git push --force

    Note: the vendor directory is being committed to Pantheon. This is because Pantheon needs the full site artifact. If you prefer to ignore the vendor directory then take a look at our Build Tools guide for documentation on the more advanced automated workflow with a build step.

Installing Drupal

Now that the code for Drupal core exists on our Pantheon site, we need to actually install Drupal.

  1. Use Terminus Drush to install Drupal:

    terminus drush $PANTHEON_SITE_NAME.dev -- site-install -y
  2. Log in to your new Drupal 8 site to verify it is working. You can get a one-time login link using Drush:

    terminus drush $PANTHEON_SITE_NAME.dev -- uli

Adding a New Module with Composer

  1. Next, let’s add a new module to our site. For this example, we’ll add the address module. We advocate working in feature branches on Pantheon, so let's create a Git branch and spin up a Multidev environment:

    git checkout -b addr-module
    composer require "drupal/address ~1.0"
  2. Now that Composer is aware of our new module requirement we need to update our dependencies. Then, we can commit them and push to Pantheon:

    composer update
    git add .
    git commit -m "Adding the address module with Composer"
    git push -u origin addr-module
  3. Spin up a Multidev environment from the Git branch we just pushed up to Pantheon:

    terminus multidev:create $PANTHEON_SITE_NAME.dev addr-module
  4. Log in to your new environment and verify that the address module exists:

    terminus drush $PANTHEON_SITE_NAME.addr-module -- uli

    Image of installing address module

Update All Site Code

  1. From a local copy of your site's codebase, run:

    composer update
  2. After Composer updates successfully, push the code back to Pantheon via Git or SFTP.

Update only Drupal Core

  1. From a local copy of your site's codebase run:

    composer update drupal/core --with-dependencies

    --with-dependencies is necessary when explicitly updating only Drupal core in order to download all of Drupal core's dependencies, such as Symfony.

  2. After Composer updates successfully, push the code back to Pantheon via Git or SFTP.

    Note that composer update is based on the values specified in composer.json. So, for example, if composer.json specifies drupal/core at ^8 then Composer will update Drupal core to the latest version of 8 but not update to 9.x. You can read more about version constraints in Composer's version constraints documentation.

Congratulations! You now have a Drupal 8 site on Pantheon that is managed by Composer.

P.S. the Pantheon Power Users Community Slack instance #composer-workflow channel or Pantheon Office Hours are great places to ask questions and chat about Composer.