How to Deploy Drupal to Pivotal CF Within Seconds

August 5, 2014 Adam Zwickey

featured-CF-DrupalContent Management Systems (CMS) make it easy to manage content-rich websites with little to no web development knowledge. Using a CMS, content publishers can maintain a dynamic website that always has fresh content, apply design consistency using templates, and manage content creation using policy-based workflows for content publishing. Many organizations large and small turn to CMS systems such as WordPress, Joomla, or Drupal to manage content for things like a company’s intranet pages, product pages on a retail website, personal blog sites and news sites.

In this post I am going to demonstrate how to deploy the popular CMS, Drupal, to Pivotal CF or another distribution of Cloud Foundry within a matter of seconds. The result will be a full technology stack running a Drupal microsite that automatically offers scalability, high availability, and monitoring. Though this blog post is specific to deploying Drupal to Pivotal CF, the general principles should apply to any CMS.

View the video below to see how fast the process is:PCF-Drupal-Video-Screenshot

Architecture

In order to run a Drupal application, you will need three main components:

  1. A php runtime paired with a web server
  2. A relational database
  3. A storage system for generated or uploaded assets

Pivotal CF provides all three, making it incredibly simple to prepare for your installation. Using the php buildpack, the php execution environment for Drupal will be created automatically when we push the application. Additionally, Pivotal CF comes with a MySQL service broker out of the box. Lastly, we will need a storage system for Drupal assets, such as uploaded images and CSS files. By default, Drupal will store these on the local filesystem. While this will work within Pivotal CF, an application instance’s local file system is ephemeral, so the assets will be lost across application restarts. Also, uploaded assets will only be stored on the individual application instance to which they are uploaded, making horizontal scalability impossible. However, Drupal supports uploading assets to a S3-compatible blob store. By using the Riak-CS service broker, we can replace local filesystem storage with a distributed, cloud-based blob store.

It is very common for Drupal deployments to include a Varnish Cache HTTP reverse proxy to speed up content serving. Within the php buildpack, a Varnish Cache can be enabled to create an extremely performant Drupal application stack. We can also apply the same technique to content served from Riak-CS. Our final architecture within Pivotal CF looks like this:

Screen Shot 2014-08-03 at 8.50.46 PM

Though this architecture may seem simple, consider a few powerful implications of running your CMS on Pivotal CF.

  1. Speed and Ease of Deployment. Previously, each time a new business unit or group needed to create a new Drupal microsite an operations or infrastructure engineer would have to provision new VMs, install and configure a web server (for example, Apache or Nginx), install php, deploy a database, and finally install and configure Drupal. Within some enterprises this may take multiple months. Running on Pivotal CF this process takes seconds with the simple use of “cf push”.
  2. Scalability. What happens as your microsite gains in popularity and needs to scale up? Unfortunately you need to follow many of the steps listed all over again. This is time consuming and certainly not something that can be done dynamically in response to sudden traffic spikes. Running on Pivotal CF gives you dynamic scalability, either vertical or horizontal, with the simple command “cf scale”. Paired with Pivotal CF Autoscale service, your Drupal instance can even scale itself up or down to accommodate the ebbs and flows of your site traffic.
  3. High Availability. How do you monitor the VMs that you have provisioned? How do you ensure your web server and drupal instances are running and healthy? How do you recover from failures? Pivotal CF ensures applications are always running in the face of system failures, with four levels of H/A built into the platform.
  4. Routing and Load Balancing. Lastly, a site operator must worry about load balancing, traffic routing, maintaining public IP pools, and managing site DNS entries. Running on Pivotal CF gives you built in load balancing and DNS registration with every “cf push” command.

How to Get Started

  1. Clone the Cloudfoundry Drupal git repo. The Drupal settings.php has been modified to read service configuration from the PaaS environment.
# Pull credentials out of VCAP_SERVICES env
$services = getenv("VCAP_SERVICES");
$services_json = json_decode($services,true);
if (isset($services_json))	{

	#MySQL
	$mysql_config = $services_json["p-mysql"][0]["credentials"];
	$databases['default']['default'] = array(
	  'driver' => 'mysql',
	  'database' => $mysql_config["name"],
	  'username' => $mysql_config["username"],
	  'password' => $mysql_config["password"],
	  'host' => $mysql_config["hostname"],
	  'port' =>  $mysql_config["port"],
	  'prefix' => 'main_',
	  'collation' => 'utf8_general_ci',
	);

	#S3 API
	$s3_config = $services_json["p-riakcs"][0]["credentials"];
	if (isset($s3_config))	{
		$conf['awssdk2_access_key'] = $s3_config["access_key_id"];
		$conf['awssdk2_secret_key'] = $s3_config["secret_access_key"];

		$s3_url = parse_url($s3_config["uri"]);
		$conf['s3fs_bucket'] = ltrim($s3_url['path'],"/");
		#force http because of self-signed certs for now
		$full_host = "http://" . substr($s3_url['host'], 9); #strip off 'p-riakcs.' from URL
		$conf['s3fs_hostname'] = $full_host;
		$conf['s3fs_use_customhost'] = TRUE;
		$conf['s3fs_ignore_cache'] = TRUE;
	}
}
  1. If not installed, install the php buildpack into your Pivotal CF environment
  2. Using the Cloud Foundry CLI, provision a MySQL database and a Riak-CS service
    $ cf create-service p-mysql 100mb-dev drupal-db
    $ cf create-service p-riakcs developer drupal-s3
  3. Push the application to Cloud Foundry using cf push
  4. You application is now deployed to the url http://drupal.<PIVOTAL_CF_DOMAIN>. You can initialize your drupal instance by navigating to http://drupal.<PIVOTAL_CF_DOMAIN>/install.php and answering a few basic questions.

Screen Shot 2014-08-03 at 8.50.57 PM

Your drupal application is now running in within Pivotal CF. However, some additional configuration is required to scale past a single application instance. We need to ensure that the S3 content serving functions properly.

  1. In the previous section a Riak-CS blobstore service named drupal-s3 was created for the application. During this process a unique S3 bucket was initialized for the application along with a unique set of credentials. Retrieve the S3 bucket name created for the Drupal application with the CLI command cf env. The bucket name is the last part of the uri credential for the p-riakcs service.
$ cf env drupal
  System-Provided:
  {
    "VCAP_SERVICES": {
      "p-riakcs":[
        {
          "name":"drupal-s3",
          "label":"p-riakcs",
          "tags":[
            "riak-cs",
            "s3"
          ],
          "plan":"developer",
          "credentials":{
            "uri":"https://XHCE0E1RAVBI99_FJL_5:7AdvdTSBiYwmySKOkoKCyGFkAVHxuaeBg0xTig%3D%3D@p-riakcs.cloudfoundry.dyndns.org/service-instance-423086ed-9167-4026-add2-d734bfb0b2e5",
            "access_key_id":"XHCE0E1RAVBI99_FJL_5",
            "secret_access_key":"7AdvdTSBiYwmySKOkoKCyGFkAVHxuaeBg0xTig=="
          }
        }
      ],
      "p-mysql":[
        {
          "name":"drupal-db",
          "label":"p-mysql",
          "tags":[
            "mysql",
            "relational"
          ],
          "plan":"100mb-dev",
          "credentials":{
            "hostname":"10.0.0.103",
            "port":3306,
            "name":"cf_27742bc8_369a_4050_ad53_e85038aa5a35",
            "username":"FEotz981XvDEQXLI",
            "password":"lAXIntesmrowz1hb",
            "uri":"mysql://FEotz981XvDEQXLI:lAXIntesmrowz1hb@10.0.0.103:3306/cf_27742bc8_369a_4050_ad53_e85038aa5a35?reconnect=true",
            "jdbcUrl":"jdbc:mysql://FEotz981XvDEQXLI:lAXIntesmrowz1hb@10.0.0.103:3306/cf_27742bc8_369a_4050_ad53_e85038aa5a35"
          }
        }
      ]
    }
  1. Input this value into S3_BUCKET env variable in the deployment manifest, manifest.yml. Additionally, update the CF_FQND variable to reflect your Cloud Foundry domain.

env:
S3_BUCKET: YOUR S3 BUCKET HERE
CF_FQDN: YOUR CF DOMAIN HERE

Execute a second application push so that your updated deployment manifest variables take effect.

$ cf push

  1. Drupal must address Riak-CS with the format of http://$BUCKET_NAME.$CF_DOMAIN. In order to support this format we must add a Cloudfoundry route to the s3 proxy application that represents our bucket name retrieved in step 1.

$ cf map-route s3 <PIVOTAL_CF_DOMAIN> -n service-instance-423086ed-9167-4026-add2-d734bfb0b2e5

Screen Shot 2014-08-03 at 8.51.07 PM

  1. We have the S3 File System module loaded, but we must navigate to Configuration < Media < File System to select S3 as the default storage location.
  2. Lastly, navigate to Structure < Content Types. Configure the image field in the “Article” content type created by the default Drupal install to upload to S3. You can do this by selecting “manage fields” and editing the “Image” field.

You now have a scalable, highly available Drupal application ready for content authoring.

About the Author

Biography

Previous
Field Report: Hack Midwest Highlights How Developers Are Innovating on the Internet of Things and Big Data in Real-time
Field Report: Hack Midwest Highlights How Developers Are Innovating on the Internet of Things and Big Data in Real-time

In a 24 hour period, over July 19th and 20th, Pivotal community engineer Scott Kahler participated in the H...

Next
6 decision-making techniques all Product Managers should know
6 decision-making techniques all Product Managers should know

As a Product Manager you constantly make decisions. Many of the decisions you make are made in collaboratio...

×

Subscribe to our Newsletter

!
Thank you!
Error - something went wrong!