Search code examples
phpmagentonginxurl-rewritingfastcgi

How can I remove index.php from the address while redirect requests to index.php via fastcgi?


I have a basic Magento (PHP app, using index.php as the controller) setup on an Ubuntu server. I configured NGINX to use PHP-CGI to serve all PHP pages. While the site is working as expected, all the URLs are of the form:
http://domain.com/index.php/apparel/shoes.html

Is there a way to use the nginx rewrite setting so that I can have the URLs like this instead:
http://domain.com/apparel/shoes.html

Currently, this is what I have in the configuration file to handle page requests:

# catch rewritten and standard URLs
location ~* ^(/index.php)?(.*) {
    include /etc/nginx/fastcgi_params;
    fastcgi_pass  127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root/index.php$1;
    fastcgi_read_timeout 600;
}

Thanks.


Solution

  • I have some experience with nginx in this regard and have even written about it. So in a shameless act of self-promotion here is the result of my earlier research:
    http://www.magentocommerce.com/boards/viewreply/211050/


    Six years on and the above link is dead. Also my nginx configs are more mature. The following starts by blocking all files and only allowing those which are explicitly public. All other requests are rewritten to index.php. If you want to execute some other PHP file you must write your own exclusion. This is the safest way I can think of.

    /etc/nginx/magento_server:

    ##
    # Include from "server {}" block
    ##
    
    # 1M = one month
    expires 1M;
    # recommended for all content, regardless
    add_header X-Content-Type-Options "nosniff";
    
    ##
    # Front handler
    ##
    
    location / {
        # if is evil, except when it isn't
        if (-f $request_filename) {
            return 403;
        }
        rewrite ^ /index.php last;
    }
    location = /index.php {
        expires off;
        add_header X-Content-Type-Options    "nosniff";
        add_header X-Xss-Protection          "1; mode=block";
    
        # "php" must be defined as an upstream
        fastcgi_pass                         php;
        include                              fastcgi_params;
        fastcgi_param SCRIPT_FILENAME        $document_root/index.php;
    
        uninitialized_variable_warn          off;
        fastcgi_param MAGE_RUN_CODE          $mage_run_code if_not_empty;
        fastcgi_param MAGE_RUN_TYPE          $mage_run_type if_not_empty;
        fastcgi_param MAGE_IS_DEVELOPER_MODE $mage_is_developer_mode if_not_empty;
        fastcgi_param APPLICATION_ENV        $application_env if_not_empty;
        # same as max_execution_time in .htaccess
        fastcgi_read_timeout                 18000s;
    }
    
    ##
    # Whitelist public static files
    #
    # avoid regex where possible
    ##
    
    location ^~ /media/ {
        # sometimes files are retrieved from database with get.php
        try_files $uri @mediaget;
    }
    # there is no way to call get.php directly
    location @mediaget {
        add_header X-Content-Type-Options    "nosniff";
        add_header X-Xss-Protection          "1; mode=block";
        fastcgi_pass                         php;
        include                              fastcgi_params;
        fastcgi_param SCRIPT_FILENAME        $document_root/get.php;
    }
    
    location ^~ /skin/ {
        # allowed with defaults
    }
    location ^~ /js/ {
        # allowed with defaults
    }
    
    # should not be accessed normally since real favicon is in /skin/frontend
    # however this is conventional
    location = /favicon.ico {
        # pretty sure that it exists but just in case...
        log_not_found off;
    }
    
    # specific exclusions, still no regex
    location = /media/.htaccess              { return 404; }
    location ^~ /media/customer/             { return 404; }
    location ^~ /media/downloadable/         { return 404; }
    
    ##
    # Error handling
    ##
    
    # possibly change this to Magento's no-route path
    error_page 404 /errors/404.php;
    location = /errors/404.php {
        fastcgi_pass                         php;
        include                              fastcgi_params;
        fastcgi_param SCRIPT_FILENAME        $document_root/errors/404.php;
    }
    
    # used when site is in maintenance mode
    error_page 500 503 /errors/503.php;
    location = /errors/503.php {
        fastcgi_pass                         php;
        include                              fastcgi_params;
        fastcgi_param SCRIPT_FILENAME        $document_root/errors/503.php;
    }
    
    # empty blocks allow serving without modification
    # ideals for gzip and mime-type are already loaded
    location ^~ /errors/default/css/         { }
    location ^~ /errors/default/images/      { }
    location ^~ /errors/enterprise/css/      { }
    location ^~ /errors/enterprise/images/   { }
    

    /etc/nginx/conf.d/php.conf:

    upstream php {
        server 127.0.0.1:9000;
        # add more PHP-FPM processes here if you have them, or maybe a unix socket
    }
    

    Each store then has it's own server block similar to this:

    /etc/nginx/sites-enabled/yoursite.com:

    server {
        server_name        yoursite.com;
        root               /var/www;
        include            magento_server;
        set $mage_run_code "default";
        set $mage_run_type "website";
    }
    

    And since .htaccess files are ignored (because this is not Apache) it helps to put .user.ini in each web root:

    /var/www/.user.ini

    max_execution_time=600
    memory_limit=256M
    session.auto_start=off
    session.gc_maxlifetime=31536000