Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm trying to convert a set of rewrite rules which were created for Apache for hosting a WordPress site to use with NginX (fastcgi, PHP).

From what I understand, WordPress has a page ("expo") which then uses code in a theme to check for a request parameter ("p"). It then uses "p" to do some database queries and render content.

So you can access this page by calling /expo?p=name_of_expo.

The requirement is that the URL be structured thus: /expo/name_of_expo

I've stripped it down to the most basic rewrite rule I can:

location ~ ^/expo/.+/?$ {
    rewrite ^/(.+)/(.+)/?$ /$1/?p=$2? last;
    try_files $uri $uri/ /index.php?$args;

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

location ~ \.php$ {
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;

When going to /expo?p=name_of_expo, the correct page is displayed. However, when going to /expo/name_of_expo, the WordPress 404 is triggered.

The rewrite log from nginx suggests that the correct URL is being written:

2012/03/08 16:56:16 [notice] 15995#0: *7698 "^/(.+)/(.+)/?$" matches "/expo/name_of_expo", client: [snip...]

2012/03/08 16:56:16 [notice] 15995#0: *7698 rewritten data: "/expo/", args: "p=name_of_expo", client: [snip...]

Obligatory software version information:

nginx version: nginx/1.0.13

spawn-fcgi v1.6.3 (ipv6) - spawns FastCGI processes
Build-Date: May 25 2010 12:33:48

PHP 5.2.10 (cli) (built: Nov 13 2009 11:44:05)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies

CentOS release 5.7 (Final)
share|improve this question

Try this

server {
  error_page   405   = @handler;
  error_page   404   = @handler;

  location / {
    if (-f $request_filename) {

    if (!-e $request_filename) {
      rewrite . /index.php last;

  location @handler { 
    rewrite / /index.php;

  location ~ \.php/ {
    rewrite ^(.*.php)/ $1 last;

  location ~ \.php$ {
    if (!-e $request_filename) { rewrite / /index.php last; }

    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;


And in your fastcgi_params

fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;
share|improve this answer
Don't use "if" in your rewrites: – skyler May 13 '12 at 20:19
I agree IfIsEvil - but in this context, there are limited alternatives and it is a tested, working configuration. – Ben Lessani - Sonassi May 14 '12 at 13:09
if can be used with a rewrite, but try_files is much better and faster. – Michael Hampton Aug 14 '12 at 23:59

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.