Enabling simultaneous HTTP and HTTPS access for Joomla (Nginx)

When enabling HTTPS access to your Joomla website, you may run into problems of invalid URLs, mixed content, or infinite redirects.

Joomla uses the $_SERVER[‘HTTPS’] variable to construct an adequate HTTP/HTTPS base URL. While the Apache webserver (supposedly) passes the HTTPS variable to PHP/CGI, the default Nginx configuration does not. If you are using PHP-FPM/fastcgi with another webserver, you may run into the same issue. A description of how to configure Nginx appropriately follows.

First off, you want to configure the $live_site in the configuration.php. You want to set it to http://example.com, as the http protocol prefix will automatically be replaced by Joomla once it determines via the $_SERVER[‘HTTPS’] variable that HTTPS has been accessed.

Then, make sure your webserver passes the HTTPS variable to PHP correctly. You can do this by echoing $_SERVER['HTTPS'] via an accessible PHP script, and accessing it. If it is set up correctly, the variable should be set to on when accessed via HTTPS. Otherwise, it should be empty (according to the manual) – but depending on your webserver may also be off.

If the SERVER variable is not set with HTTPS, you need to make your webserver pass the SERVER variable to PHP-FPM/FCGI. For Nginx on Ubuntu/Debian, you can do that by adding an additional fastcgi_param to your fastcgi_params file (or wherever you put your custom param declaration you are using for the scripts).

fastcgi_param HTTPS $https;

Now, make Nginx notice the configuration changes.

service nginx configtest
service nginx reload

After that, the $_SERVER['HTTPS'] should be correctly set to on when the PHP script is accessed via HTTPS, and not if not.


For versions of Nginx prior to 1.1.11, the $https variable is not available. In that case, you can declare one yourself, and make its value depend on the request URL scheme (protocol).

In Ubuntu/Debian, in the folder /etc/nginx/config.d create a file php-https-fix, and inside of it create a variable mapping to set a variable to on if the access was via HTTPS or leave it empty if not.

map $scheme $fastcgi_param_https {
https on;
}

Then, in your fastcgi_params (whichever you use for passing to PHP), add the HTTPS parameter.

fastcgi_param HTTPS $fastcgi_param_https;

Then, make Nginx reload the configuration.

service nginx configtest
service nginx reload

After that, the $_SERVER['HTTPS'] should be correctly set to on when the PHP script is accessed via HTTPS, and not if not.