(This post was originally published at
Early in my Habitat journey I packed a
super-simple Python application that I had developed. It served no
purpose other than to be packaged. Once I started to get my head
around the fundamentals of packaging with Habitat, my mind turned to
more useful things.
These are interesting in their own right and you’ll be hearing more
about them after ChefConf. For now,
I want to talk about Drupal.
Drupal is “just” some PHP. How hard can it be? 1 Well, I saw enough
raised eyebrows from my friends at Chef, to understand this might not
be as easy as it seems.
Packaging Any PHP
Let’s forget Drupal for now. The first step is working out how to
package any piece of PHP for Habitat. Well, we really only need
- NGINX (or Apache HTTPD, if you so wish)
- The sources of our PHP application
No rocket science here. We just need to glue it all together. Most of
the hard work is already done for us, since Habitat already has
core/php packages available.
All I really wanted to do was unpack my PHP in a location where NGINX
could access it and then point NGINX to my PHP-FPM socket/ip. This is
all easy enough when you know how.
I didn’t know how. Thankfully, the Habitat public
depot has a plan available for WordPress 2
which gave me some insight. The “trick” here is to launch PHP-FPM and
then use an init hook to also launch NGINX with a config you give it.
OK, so now Drupal.
Drupal: First Attempt
The first attempt a Drupal was easy enough:
This plan was built exactly as I described above: I download the
source tarball, unpack it in a specific location and configure NGINX
to use that location as a site root. When it is run, the user is
presented with a shiny new Drupal install page:
So, there you have it, a successful Drupal package for Habitat!
Or is it?
Drupal: A Better Attempt?
The problem with my first attempt is that it is not very Habitat-y. Or
Drupal-y for that matter. The cool kids use the Drupal shell
(drush) to deploy/configure Drupal and here
comes my first problem: there’s no Habitat package for
Not to worry:
drush could not be any simpler to install; it is used
as a dependency in composer. Thankfully, there is a
package I can use for this purpose. I rolled out a
package with minimal effort. It can be found here.
Drush is important for one particular reason: having installed the
base Drupal (“core”?) system, drush can be used to build a
preconfigured site, including default user credentials and database
configuration. This means we do not need to force the user of the
Drupal package to go through the post-install install script. They’d
be presented with a ready-made site, all configured and ready to go.
Providing most of the details needed to configure a Drupal site using
drush is simple, we can simply dump the info in
default.toml to be
pulled out anytime. Mildly trickier is the database config.
Using Habitat Binds For The Drupal Database
Just as with the default account credentials, I could simply dump all
the default database config into
default.toml. This would not be a
very Habitat-y thing to do.
Much better is to use service binding, to bind my Drupal service to an
existing database service. In Habitat a service bind is the mechanism
that allows me to say, “this service relies on this other service in
order to run properly”. At runtime, I simply tell my service which
other service to bind to:
$ hab start baggerspion/drupal --bind database:mysql.default
I will spare the full details on how binds work. There is plenty of
available on the
Habitat website. What’s important here is that, because I have bound
my Drupal service to a Mysql service, I can now configure my service
to use that database automatically. What does the user see now?
This is much better. I think.