DEV Community

Uladzislau Murashka
Uladzislau Murashka

Posted on

Joomla on Nginx: Making SEF URLs

Outsourcing

On freelance sometimes I have interesting tasks, working as admin and security engineer. This article will be about setting up SEF urls for Joomla running on Nginx. I have searched internets for information about how to set up such urls but didn't find everything at one place. Applying some solutions administrative panel didn't work properly or was shown for example "index.php" file, so here I will add simple solution for how to make things working properly.

Requirement was following: make redirects from www to non www domain, use only HTTPS, remove slashes and hide "index.php" file from the address bar.
Our stack: ISP Manager panel, Nginx + php-fpm and Joomla. Also want to mention that customer asked to change web server from Apache (was used previously) to nginx with php-fpm.

First of all, let's send users from http to https:

server {
     listen 80;
     server_name mysite.com www.mysite.com;
     return 301 https://mysite.com$request_uri; ##sending users to https with no www
 }

The line with “return 301 ...” indicates that this redirection is permanent, not temporary (code 302 is a temporary redirect). Now users will only visit us on https. Moving forward, adding the config for https and remove the www from the path (i.e., redirect users with help of “rewrite”):

server {
     listen 192.168.1.12:443 ssl;
     server_name mysite.com www.mysite.com;
     if ($http_host = www.mysite.com) {
         rewrite  (.*)  https://mysite.com$request_uri; ##rewriting path to non www domain
     } ...other part of the config...}

Here we set up a redirect from www and started the configuration under https. The next step is to remove the “index.php” file so that it does not show:

rewrite ^/index.php/(.*) /$1  permanent; ##hiding our index.php file

Next we have the standard nginx config, taking into account the work under SSL, here I do not publish it, but at the end of the article a full config will be available as it is. The next step we have is to set up the work of the SEF urls and remove slashes (i.e. if the user enters for example 3 slashes at the end, they will disappear and the page will load correctly, there will be no error like 404), but at the same time we should not forget about the correct processing of 404:

location / {
    try_files $uri $uri/ @joomlaurls; ## adding our processing rules
}
location @joomlaurls {
    rewrite ^/(.+)/$ /$1 permanent; ## removing slashes
    try_files $uri $uri/ /index.php?$args; ## setting up SEF urls
}
location ~ [^/]\.ph(p\d*|tml)$ {
    try_files /does_not_exists @php; ## processing 404
}

access_log off;
location @php {
    fastcgi_index index.php;
    fastcgi_pass unix:/var/www/php-fpm/www-root.sock;
    fastcgi_split_path_info ^((?U).+\.ph(?:p\d*|tml))(/?.+)$;
    try_files $uri =404;
    include fastcgi_params;
}

Our site will properly handle all the SEF urls, give 404 if there is no page, remove slashes from the address bar, and also hide the “index.php” file from the path, by default we will have the “index.php” file read from the folder so here no need to point at it directly.

One more thing about the admin panel - if the config is crooked, then the Joomla admin panel will not work at all, or it will open clumsily along the path “/administrator/index.php” and only this way, with the config that I gave above - everything will be processed and work correctly. Also in Joomla itself, you also need to activate the redirect function (in the admin area or Joomla).

Below you can find full configuration file I used on nginx with php-fpm:

server {

    listen 80;

    server_name mysite.com www.mysite.com;

    return 301 https://mysite.com$request_uri;

}

server {

listen 443 ssl;

server_name www.mysite.com; 

return 301 $scheme://mysite.com$request_uri;

}

server {

    listen 192.168.1.12:443 ssl;

    server_name mysite.com www.mysite.com;

    if ($http_host = www.mysite.com) {

        rewrite  (.)  https://mysite.com$request_uri;
    }
    rewrite ^/index.php/(.) /$1  permanent;

    ssl_certificate "/var/www/httpd-cert/www-root/mysite.com.crtca";

    ssl_certificate_key "/var/www/httpd-cert/www-root/mysite.com.key";

    ssl_ciphers EECDH:+AES256:-3DES:RSA+AES:!NULL:!RC4;

    ssl_prefer_server_ciphers on;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    add_header Strict-Transport-Security "max-age=31536000;";

    ssl_dhparam /etc/ssl/certs/dhparam4096.pem;

    charset off;

    index index.php;

    disable_symlinks if_not_owner from=$root_path;

    include /etc/nginx/vhosts-includes/.conf;
    include /etc/nginx/vhosts-resources/mysite.com/.conf;

    error_log /var/www/httpd-logs/mysite.com.error.log notice;

    ssi on;

    set $root_path /var/www/www-root/data/www/mysite.com;

    root $root_path;

    gzip on;

    gzip_comp_level 9;

    gzip_disable "msie6";

    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;

    location / {

        try_files $uri $uri/ @joomlaurls;

    }

    location @joomlaurls {

        rewrite ^/(.+)/$ /$1 permanent;

        try_files $uri $uri/ /index.php?$args;

        #error_page 404 = /index.php;

    }

    location ~ [^/].ph(p\d|tml)$ {
        try_files /does_not_exists @php;
    }
    access_log off;
    location @php {
        fastcgi_index index.php;
        fastcgi_param PHP_ADMIN_VALUE "sendmail_path = /usr/sbin/sendmail -t -i -f admin@mysite.com";
        fastcgi_pass unix:/var/www/php-fpm/www-root.sock;
        fastcgi_split_path_info ^((?U).+.ph(?:p\d|tml))(/?.+)$;

        try_files $uri =404;

        include fastcgi_params;

    }

}

That's it! Seems simple? But during research and implementation still some issues appeared which were fixed in configuration example above. I didn't work with Joomla before, mainly with WordPress so this case was actually interesting for me and possibly it may help somebody else.

Latest comments (0)