Looking at (and a debugging tip) the Domain module for Drupal

Topics: 

This week I decided to try out the Domain module for Drupal. The immediate goal was to support multiple domains and what looks like multiple websites out of one Drupal instance. I'm thinking there might be an advantage where the content across related websites could be more easily cross-referenced between the sites. Plus I'm expecting a maintenance gain from having one Drupal instance rather than several. Plus I'm working with an organization that could want to support multiple websites for its committees.

I've looked at the Subdomain and Domain modules before but never got past kicking the tires. This time the Domain module seems good enough and I have a clear enough purpose for it that I'll keep it around.

One reason to choose Domain over Subdomain is that, going by the project page, the Domain module supports top level domains. For example I'm planning to install SocialMedia4Good.com and PeaceGuide.com onto DavidHerron.com. By the project page the Subdomain module only supports, well, sub-domains.

On the other hand the Domain module has more complex installation considerations. Because it works with Node Access, if your site is already using a Node Access module it'll require a patch to Drupal Core to accommodate multiple Node Access modules. For example I run VisForVoltage.org, which uses the Forum Access module to provide detailed permissions for the forums. I want to attach multiple domains to that site, but it would mean mucking around this patch for multiple Node Access modules. Maybe I'll wait for Drupal 7 where this issue is supposed to be resolved.

Installation of the Domain module is more complex than the typical "drop it in sites/all/modules, and enable the module" so read the INSTALL and README files carefully. One oddball thing is the method to customize the initial set up. There are three settings (DOMAIN_INSTALL_RULE, DOMAIN_SITE_GRANT, and DOMAIN_ASSIGN_USERS) which are customized by editing domain.module. Current best practice is to expose settings and configuration in some "code" that would be separated from the module, as in the methodology espoused by the Features module. Also you'll have to remember when updating the Domain module to later releases to propagate this setting change to the next version. Whatever.

I chose to set DOMAIN_SITE_GRANT to FALSE rather than its default TRUE. It's defined to, during installation, set all existing content to be visible on all domains. The Domain module attaches values to each node that governs which domain it's visible on, or whether it's visible on all domains. I personally don't understand why the default for this is to make everything visible on all domains. My reasoning on this is only a few items should be visible on all sites such as an "about" page, and that the default should be for nodes to appear on specific domains. Setting DOMAIN_SITE_GRANT to FALSE means I don't have to go to every node and remove the "all domains" setting on that node.

In the Domain administrative page (admin/build/domain) one can create multiple "domain records". It's relatively easy to add a new domain to your site, just create a domain record. Oh, and make sure to fix up DNS records and details with your web hosting provider. The domain DNS records for all domains have to point to the same place. And the web server configuration has to recognize that multiple domain names all go to the same Drupal instance.

There are settings per-domain and across-the-board settings. A theme can be chosen for each domain. These settings are pretty straightforward. On the Settings tab, under the Domain Module Behaviors section, there is a setting "Show debugging output on node view" which is useful if you're having trouble getting it to work right. It's important to understand whether you want nodes to automatically appear on all sites, or whether you want to proactively choose which site(s) each node should appear on. The defaults appear to be for nodes to appear on all sites, and as I said before in my mind it's better to choose which site the node should appear on.

An important setting is the "Enforce rule on administrators" choice. The default is that administrators (users with the administer nodes permission and user 1) will view all nodes on all domains regardless of any choice made on the node. This can be confusing especially if you're trying to get a specific node to show up only on a specific domain. I prefer to set this to "Restrict node views for administrators" so that my view of the site is more like the normal view of the site.

The Domain module attaches/alters various forms all across the admin area labeled "Domain-specific settings". It contains a list of checkboxes, one for each domain you've checked. The effect is to make a setting for one domain distinct from settings for another domain. It depends on how much behavior difference you want between the domains.

Basically the Domain module works by overriding two behaviors on a per-domain basis. One is the Node Access determination, it uses Node Access rights to determine which nodes are visible on what domains. The other is to override various settings on a per-domain basis, such as theme, slogan, footer, front page, etc.

I had a huge problem getting this module to work correctly. It took a couple days and during that time the content on my main domain was invisible, due to node access problems. Fortunately I got it worked out.

First, during the installation the Domain module makes a lot of per-node settings that cannot be re-done after the installation. Again, some settings are made by patching the domain.module file. Those settings have two meanings, one being behavior during install, the other being behavior after install. It took me several rounds of installing and uninstalling the module, to experiment with different settings. This was kind of inconvenient.

The final problem, which made my content invisible, had something weirdo to do with Node Access for anonymous content access. I, as a logged in person, was having some fun adding nodes to the site and seeting that they showed up on the desired domain. Then I decided to look at my site as anonymous and couldn't see anything, had the "Welcome to your new Pressflow site" screen, and was getting "not allowed to access" errors on accessing any page. Eep.

I went over lots of details such as the user permissions screen and carefully reading every setting. I turned on the debugging mode for Domain module, and also turned on the Devel module because it has a module for debugging Node Access. The important thing it showed me is that Node Access did not allow Anonymous to access the nodes. (See http://drupal.org/node/841042#comment-3518412 for some details)

FWIW I found an excellent blog post about debugging node access issues - http://www.juliakm.com/drupal-permissions-issues-debugging-checklist - but my specific issue fell outside that list. The post suggests rebuilding node permissions which was not enough. The rebuild had to happen AFTER re-enabling the module. For some reason. Breezing through the comments on that blog post it's clear that there are other modules where it's helpful to disable then re-enable the module before rebuilding node permissions.