This recent article at Smashing Magazine discussed trends and challenges in deploying WordPress sites. The biggest issue cited by the article and the lengthy comments that follow is the issue of the database: because WordPress stores strings in the database that contain the site domain (including configuration options and asset paths), it’s hard to migrate content and config between dev, staging, and production environments. A bunch of possible solutions were offered up, including interconnectit/Search-Replace-DB, which I use fairly often and really like.

I was surprised, however, that no one talked about my preferred strategy, which is, in a way, the simplest: Dev, staging, and production should all have the same domain names. When you remove the need to change the domain, you make it much easier to deploy specific pieces of content, spin up new instances, etc.

Since all versions of a site have the same domain name – say, booneisthebomb.com – I use my local hosts file (/etc/hosts on *nix systems) to switch between instances. So I may have the following lines in /etc/hosts:

With these two lines commented out, going to booneisthebomb.com in a browser will use DNS for the lookup, which is to say it’ll go to the production site. Uncommenting one of the lines allows me to work on the local or staging site.

The biggest pitfall of this technique is that now there is no obvious way to tell your environments apart (and you definitely don’t want to mistake your production site for a dev site). My solution for this is to drop this file into wp-content/mu-plugins/. Then, in my environment file (which contains env-specific config, such as database connection info), I put a line like this:

define( 'ENV_TYPE', 'staging' );

Now, when I load up the staging site, it shows booneisthebomb.com in the URL bar, and the following box appears at the bottom of every page:

Many WordPress plugins and themes need to write to the filesystem, to cache data, create a debug log, download libraries that for one reason or another aren’t distributed with the main package, etc. And many of these plugins do it wrong, by writing (or attempting to write) to their own plugin/theme directories. This is a bad idea for a couple of reasons:

If you use version control to deploy/manage a site, you probably have configured your repo to ignore the content of dynamic directories like wp-content/uploads. Obviously, you don’t want to ignore plugin and theme directories. When Git etc detects your newly created files, it wreaks all sorts of havoc with workflow and, depending on the content of the files and the carelessness of the deployment manager, poses the risk of losing user content or endangering sensitive data.

Some people have their file permissions set very conservatively, so that the webserver user doesn’t have write access to wp-content/plugins or wp-content/themes. So plugins that attempt to write to those directories often break altogether.

The good news is that every properly-configured WordPress installation will have at least one location where the webserver can write, and which is highly likely to be ignored by all version control setups: the upload directory wp-content/uploads. The situation is more complicated on Multisite, where each site has its own subdirectory of wp-content/blogs.dir. Happily, there’s an easy way to concatenate an upload path that’ll work across installations:

This weekend at BuddyCamp Miami (which ruled btw) I chatted with a number of folks about putting GPL clauses into client contracts. It can be especially challenging when working with universities or other bureaucracies that have hardcore, work-for-hire-ish intellectual property clauses already built into their consultant contract boilerplate. On a number of occasions, my clients and I have worked with the legal departments at universities to develop new language that fits the spirit and law of GPL software. In my opinion, this kind of work is among the most important work I’ve done since I started in this business, even more important than most of the software I’ve written. By having the discussions with legal, and by getting free-software-friendly boilerplate on their books, we take steps toward legitimatizing free software in the university, and making it part of the culture.

Anyway, I was asked privately to share some of this contract language, and I figured it would be more useful to do it in a blog post than in an email. So here are a few examples that have been approved by the legal departments at large universities. (Side note: We should come up with a system for sharing these kinds of strategy docs in a more organized way.)

Foundation acknowledges and agrees that enhancements, bug fixes and other custom developments produced under the scope of this agreement will be subject to release under the GNU Public License v2, or another compatible and relevant open-source license.

The following clause is added as a footnote to the existing language about IP:

Section VIII (1-3) shall not apply when work is being performed in the public domain. Consultant agrees to comply with the GNU General Public License version 2, as set out in the Attachment #2, when work is being performed in the public domain.

A few notes about the language in this second example (which their lawyers wrote, not me). First, “Attachment #2” is a copy of the GPLv2. Second, I think there is a little bit of confusion here about “public domain”, because strictly speaking, “public domain” means that no one owns the copyright, while the GPL is dependent on copyright. I think the spirit of the phrase “performed in the public domain” is supposed to be something like “written for public consumption”. But a literal reading of this clause probably means that I must relinquish copyright over the work done under this contract into the public domain. In this specific case, the end goal is for me to extend one of my existing GPL-licensed WordPress plugins; so I will then be integrating this newly-created public-domain code into the plugin, and then distributing the whole thing under the GPL, with a note that the newly added library is in the public domain. This is not ideal, but it’s OK for this case where I’m building a standalone add-on for my own work – good enough not to continue negotiations 🙂

If I can dig up others, I’ll post them here. If you have real-life examples, please share in the comments.