MODX friendly URLs on Nginx

July 14, 2015 3.8k views
Nginx PHP Frameworks Ubuntu

Has anyone deployed a MODX app using Nginx? I'm using a LEMP stack on Ubuntu and I would like to be able to utilise MODX's friendly urls.

Having more experience with Apache, I'm unsure of what re-write rules Nginx requires in the configuration file.

Thanks

4 Answers

I haven't used MODx before but nginx is pretty smooth to use. You probably need something like this:

server {
        listen 80;
        server_name modxsite.com
        root /home/sites/modxsite.com;
        index index.php;
        client_max_body_size 30M;
        location / {
                root /home/sites/modxsite.com;
                if (!-e $request_filename) {
                        rewrite ^/(.*)$ /index.php?q=$1 last;
                }
        }
        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(.*)$;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                include fastcgi_params;
                fastcgi_ignore_client_abort on;
                fastcgi_param  SERVER_NAME $http_host;
        }

        location ~ /\.ht {
                deny  all;
        }
}

Try to use that, and please give a report when done. Hope this will work for you.

Never mind, don't use that one. In an nginx environment its better not to use an if statement, so try this one:

server {
    listen 80;
    server_name www.modxsite.com modxsite.com;
    root /path/to/www.modxsite.com;
    index index.php index.html;

    location / {
        #try to get file directly, try it as a directory or fall back to modx
        try_files $uri $uri/ @modx;
    }

    location @modx {
        #including ? in second rewrite argument causes nginx to drop GET params, so append them again
        rewrite ^/(.*)$ /index.php?q=$1&$args;
    }

    location ~ \.php(.*)$ {
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

Please give a report if you got any luck with this config

Hi,

Thanks for the fast response. Your answer helped a lot!

The part:

location / {
            root /home/forge/gowildinwirksworth.co.uk/www;
            if (!-e $request_filename) {
                    rewrite ^/(.*)$ /index.php?q=$1 last;
            }
    }

was crucial.

My whole config files now looks like:

server {
    listen 80;
    server_name site.co.uk;
    root /home/path/to/www;

    # FORGE SSL (DO NOT REMOVE!)
    # ssl_certificate;
    # ssl_certificate_key;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    index index.html index.htm index.php;

    charset utf-8;

    location / {
            root /home/path/to/www;
            if (!-e $request_filename) {
                    rewrite ^/(.*)$ /index.php?q=$1 last;
            }
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  /var/log/nginx/site-error.log error;

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }
}

For others that might be looking for the same thing, I'm using MODX 2.3.5 and have the Friendly URLs system setting ON.

Thanks again.

  • No problem. Please try the second answer, an if statement isn't recommended to use in a nginx environment.

You answered just as I was posting my first response.

Your second solution (omiting the if statement also works).

server {
        listen 80;
        server_name site.co.uk;
        root /home/path/to/www;
        index index.php;


        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;


        charset utf-8;

        location / {
            #try to get file directly, try it as a directory or fall back to modx
            try_files $uri $uri/ @modx;
        }

        location @modx {
            #including ? in second rewrite argument causes nginx to drop GET params, so append them again
            rewrite ^/(.*)$ /index.php?q=$1&$args;
        }

        location ~ \.php(.*)$ {
            include fastcgi_params;
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }

        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }

        access_log off;
        error_log  /var/log/nginx/site.co.uk-error.log error;

        error_page 404 /index.php;


        location ~ /\.ht {
                deny  all;
        }
}
  • Great to hear you got it solved now, the if statement does work indeed but its "evil". You can read more about that here. If you got any more questions I'll be happy to help you.

Have another answer? Share your knowledge.