Jeff Geerling's blog

Highly-Available PHP infrastructure with Ansible

I just posted a large excerpt from Ansible for DevOps over on the Server blog: Highly-Available Infrastructure Provisioning and Configuration with Ansible. In it, I describe a simple set of playbooks that configures a highly-available infrastructure primarily for PHP-based websites and web applications, using Varnish, Apache, Memcached, and MySQL, each configured in a way optimal for high-traffic and highly-available sites.

Here's a diagram of the ultimate infrastructure being built:

Highly Available Infrastructure

The configuration is similar to what many larger Drupal sites would use, and with the exception of the varnish default.vcl and the actual PHP script being deployed (in the example, it's just a PHP file that tests the rest of the infrastructure and outputs success/fail statuses), you could drop a Drupal site on the Apache servers and immediately start scaling up your traffic!

NFS, rsync, and shared folder performance in Vagrant VMs

It's been a well-known fact that using native VirtualBox or VMWare shared folders is a terrible idea if you're developing a Drupal site (or some other site that uses thousands of files in hundreds of folders). The most common recommendation is to switch to NFS for shared folders.

NFS shared folders are a decent solution, and using NFS does indeed speed up performance quite a bit (usually on the order of 20-50x for a file-heavy framework like Drupal!). However, it has it's downsides: it requires extra effort to get running on Windows, requires NFS support inside the VM (not all Vagrant base boxes provide support by default), and is not actually all that fast—in comparison to native filesystem performance.

I was developing a relatively large Drupal site lately, with over 200 modules enabled, meaning there were literally thousands of files and hundreds of directories that Drupal would end up scanning/including on every page request. For some reason, even simple pages like admin forms would take 2+ seconds to load, and digging into the situation with XHProf, I found a likely culprit:

is_dir xhprof Drupal

There are a few ways to make this less painful when using NFS (since NFS incurs a slight overhead for every directory/file scan):

Viewing email in Linux using postfix's mailq and postcat

When I'm developing using the Drupal Development VM, or checking into email processing on any of my servers, I usually use postfix to handle mail sending. Postfix is simple, preinstalled on most Linux distributions (and easy to set up if not), and is easy enough to use.

Here are the most common commands I use when either developing or troubleshooting email in production:

  • mailq - print a list of all queued mail
  • postcat -vq [message-id] - print a particular message, by ID (you can see the ID along in mailq's output)
  • postqueue -f - process the queued mail immediately
  • postsuper -d ALL - delete ALL queued mail (use with caution—but handy if you have a mail send going awry!)

There are many other helpful commands and scripts to help deal with mail (e.g. deleting all messages to a certain domain, or deleting specific message IDs easily), but these are the main ones I use during day-to-day development and troubleshooting.

Creating a contact form programmatically in Drupal 8

Drupal 8's expanded and broadly-used Entity API extends even to Contact Forms, and recently I needed to create a contact form programmatically as part of Honeypot's test suite. Normally, you can export a contact form as part of your site configuration, then when it's imported in a different site/environment, it will be set up simply and easily.

However, if you need to create a contact form programmatically (in code, dynamically), it's a rather simple affair:

First, use Drupal's ContactForm class at the top of the file so you can use the class in your code later:

use Drupal\contact\Entity\ContactForm;

Then, create() and save() a ContactForm entity using:

Midwestern Mac's Vagrant Boxes - CentOS and Ubuntu

In support of my mission to make local development easier and faster, I've released boxes for four of the most popular Linux distributions I use and see used for Drupal sites: CentOS 6/7 and Ubuntu 12.04/14.04.

Vagrant Boxes - Midwestern Mac, LLC

I've been using other base boxes in the past, but it's hard to find updated boxes (especially for newer OSes) from people or companies you can trust that are truly minimal base boxes (e.g. no extra configuration management tools or junk to kludge up my development environment!). These boxes are all minimal installs that let you bring your own configuration however you want; I typically use an Ansible playbook to build a LAMP server, or a Solr server, or an ELK server for monitoring all the other servers...

You can find all the info on the boxes (including links to the Packer/Ansible build configuration used to create the boxes) on, and the boxes are also available on Vagrant Cloud: geerlingguy's boxes.

Sync a Shared Google Calendar with OS X or iOS (iPhone, iPad)

Someone shared a Google Calendar with me recently, and it showed up at just fine. However, I could not see the shared events on my Mac (using Calendar) or on my iPhone or iPad (using the Calendar app).

To fix this, I had to visit directly, and check the shared calendar, then save the settings.

I'm posting this here because after spending an hour or so digging around all the Google Calendar settings online and settings on my Mac and iPhone, I finally found that link in some random forum post (nowhere to be found in Google's help docs!), and I don't want to forget how to manage shared calendar sync! Even using the iCal feed for the shared calendar didn't work.


Subscribe to RSS - Jeff Geerling's blog