I have recently been trying out a number of content management systems (CMSes) on a server with Apache + FastCGI (PHP) as a backend, and Nginx as a frontend (reverse-proxy). Of these (WordPress, Joomla, MediaWiki, and Drupal) the only one to encounter any difficulties was Drupal (version 7).
A number of content management systems are affected by a bug in FastCGI which prevents the passing of the correct path to the script. As such, some scripts ‘see’ their path as including cgi-bin (a typical location for the FastCGI handler script). Drupal exhibited this problem, while all the other CMSes (above) were able to obtain the correct path without additional configuration. In this case, Drupal would load any given page, but the paths for all (relative) links (and server-side included files) were incorrect. To expand a bit:
- Going to http://example.com would try to load http://example.com/cgi-bin/index.php and the page would not load
- Going to http://example.com/install.php would load the page but image links were broken, CSS was incorrectly linked (paths included cgi-bin), and the continue/next links pointed to the wrong path.
Discounting the webserver
In theory this could have been caused by the webserver (an incorrectly configuration) or the CMS. A simple test script (e.g. PHPInfo) should be sufficient to rule out the webserver as the cause. In this case, the cause traced back to the CMS.
This particular server, runs Apache as a backend with Nginx as a frontend (reverse-proxy), which raises the question of how one could distinguish between the two servers if the web server was deemed to be the cause. In most similar setups, the backend server is firewalled to prevent direct access, which means only the front-end server can be accessed, the problem is compounded by the fact that most environments are setup for virtual hosting, which eliminates direct IP based access of the site. Any attempt to access the site via its URL will be seen as outside access and will only get to the frontend server (this is true even if a text-based browser was installed on the server and pointed at the URL in question). The solution, is rather simple – you can access the backend server locally (i.e. from the server), through curl, and passing the ‘Host’ header (to address the virtual hosting problem).
curl --header "Host: example.com" --head localhost:8080
An easy confirmation of the results is to note the ‘Server’ header that is returned – in most cases, direct access will list the front-end server, while specifically accessing the backend server, will return its matching header.
Resolving the issue
While not quite elegant, the solution was simple enough. Copying
sites/default/settings.php and modifying
$base_url (around line 249) to point to the correct url (e.g. http://example.com). The reason I classed this as inelegant, is that the installer still took three tries to finish – each time completing a part (and continuing, fortunately, on subsequent attempts). The reason being that the configuration was re-written, and resulted in reverting the
$base_url value. Once again, this problem is limited to FastCGI installations, and quite possibly only a subset of those. The underlying cause appears to be more a FastCGI issue than one with Drupal, but is notable for the fact that other CMSes overcame the problem.
Another oddity I came across, after the installation, was with the setup of clean URLs. In my particular case, I had to setup an apache redirect before it would let me use clean URLs – some other CMSes (e.g. WordPress) will allow the setup of clean URLs first and handle them internally, and allow Apache to be used as an optimization (but not a requirement). Quite possibly, this is a result of the specific server setup, but it was unusual none-the-less.
To setup clean URLs:
- Edit the
.htaccessfile (in the root folder)
- Uncomment line 106:
- Modify line 113:
RewriteRule ^ index.php [L]to
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
- Under Home » Administration » Configuration » Search and metadata, select and enable Clean URLs