NGinx and Apache with Joomla!

I recently published a guide to configuring NGinx as a reverse proxy to Apache on CentOS. It works well with Joomla! 2.5 and 3.x but doesn't always play quite so nicely with Joomla! 1.5.

Having had to configure a system today, I thought I'd document what I had to do differently.

Live Site

If you haven't set $live_site in configuration.php, every URL generated with JURI::base() will come back with Apache's port number on it (i.e. http://www.example.com:8080 instead of http://www.example.com).

 

SSL Connections

This arises from the need to set $live_site, when on an SSL connection, URL's generated using JURI::base() will point to the standard URL. If one of these is used to load a page requisite (such as Javascript or CSS) many browsers are going to show a warning about insecure content.

The downside is, this requires a (small) core hack to resolve.

File: libraries/joomla/environment/uri.php 

On Line 231, change

$live_site = $config->getValue('config.live_site');

to

$live_site = ($_SERVER['HTTPS']) ? str_replace("http://","https://",$config->getValue('config.live_site')) : $config->getValue('config.live_site');

Normally, I'd go out of my way to avoid recommending a core hack, but the alternative is to find every call to JURI::base() and re-write that. As there aren't going to be any further updates to the 1.5 branch, and it's only a small change it seems acceptable in this instance.

Unfortunately, looking at the codebase it does look like the 2.5.x and 3.x branches are affected by this as well and as both branches will receive updates in the future, any core hacks are likely to be overwritten. So it may be worth locating uses of JUri::base and correcting there until it's fixed in the core (pull request inbound)

 

SEF URLs

This may be peculiar to the Ubuntu Server I was working on, but it's worth mentioning in case anyone else encounters this issue, it certainly wasn't a problem with Joomla 2.5 or 3 on CentOS.

If once you've gone live, you find that SEF URLs don't 404, but only return the homepage, make the following changes to your NGinx server block (we created this rule in My previous article)

location / {
try_files $uri $uri/ /index.php; }
location ~ \.php$ {

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;

}

Becomes

location ~* \.(js|css|jpg|jpeg|gif|png|svg|ico|pdf|html|htm)$ { } 
location ~* {
 
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $remote_addr;
 proxy_set_header Host $host;
 proxy_pass http://127.0.0.1:8080;

}

The difference basically being that we're telling NGinx exactly which files it should serve. The issue described arises because NGinx appears to be falling back on the last declaration of the try statement (which it does by design) - the issue we have is that it therefore places a request through the proxy to index.php - so, we get the homepage.

In theory, you could replace

location / {
try_files $uri $uri/ /index.php; }

With

location / {
try_files $uri $uri/ @proxy; }

But I prefer knowing exactly what's going to be served by which server. The defined extensions make up the bulk of the static content on a typical Joomla! site anyway, so for most users there should be little performance impact in doing it this way.

 

Conclusion

There's a little more work involved in getting Joomla 1.5.26 working behind a NGinx Reverse Proxy but it's still do-able and still isn't particularly complex. There are still plenty of reasons why you should upgrade from Joomla 1.5, and needing to do a core hack to avoid breaking SSL support when implementing NGinx should be considered one of them.