Skip to content
[shareaholic app="share_buttons" id="14657658"]
Share this..

Migrate from Apache to nginx (and keep rewrites intact)

2010 January 28
by Eddie

nginx is a very fast and very lightweight web server that can handle static HTML blazingly fast, and does very well with dynamic (PHP) content as well.   In fact the very site your viewing is running atop of nginx.  nginx isn’t ideal for every server, and can’t handle SVN or WebDAV among other protocols.  But for your average site running PHP, Ruby or Django, nginx is choice.

The trouble was that I have lots of site (like this one!) that rely on a myriad of rewrite rules and logic to direct users properly.  Because we lose the mod_rewrite provided by apache, we need to tell nginx about our rewrite rules.

Luckily the logic is very similar, and all expression based as before…

create domain specific configuration

The first step is creating directories for each site you want to customize.  Any file within this directory will be read into configuration when nginx starts or reloads.


Harvest those .htaccess files

next we turn to our existing rules as a launch pad for our new rewrite logic.

your apache rule (from .htaccess)

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]

your new nginx config (into wordpress.conf)

if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?url=$1 last;

Note the similarity!

” if the path they are looking for does not exist, give them this path instead. ”

The differences are subtle but important.  Apache assumed absolute paths in the created path, so index.php would be /index.php – but nginx does not make that assumption, so we need to explicitly include the root /.

Got more rules to rewrite?

I am actually finding nginx’s logic based syntax much easier to master than Apache’s.  You can specify rules for specific domains or servers, and use many variables including the user agent and

Reload nginx

For any changes to take affect you will need to force nginx to reload.

sudo /etc/init.d/nginx reload

If you still have questions maybe it is because you have not read the page here – but please post your thoughts!

4 Responses leave one →
  1. James Nuvat permalink
    January 31, 2011

    Your example can be simplified significantly and it appears you are using old WordPress .htaccess rules. Use ‘try_files’ wherever possible because “if is evil” under nginx.

    Also, be aware that bad configurations in nginx can and likely will introduce security vulnerabilities into your website. nginx is a proxy server first and a web server second, so it defaults to the assumption that files may not necessarily exist on the host it is running on and a simple regular expression can cause havoc. An example of this:,88845

    Took them way too long to come up with a reasonable solution to the problem. And, if you read through the conversation, people today are still getting bitten by the issue. As an added bonus, it doesn’t look like there will ever be a solution to the problem because it isn’t fixable and Igor isn’t interested in fixing it.

  2. Eddie permalink*
    February 13, 2011


    Thanks for the info!
    I took a look at my config files and should be ok, runninga pretty recent version.

    As for simplifying the wordpress script,i would love to hear more, perhaps am example.

  3. January 12, 2012

    Eddie: the try_files directive just gives nginx a fallback in case the request URI is invalid. Basic syntax would be something like this, based on your example:
    try_files $uri $uri/ /index.php?url=$uri&$args;

Trackbacks and Pingbacks

  1. Running Pligg on Nginx – Rewrite rules | Edward A. Webb (.com)

Leave a Reply

Note: You can use basic XHTML in your comments. Your email address will never be published.

Subscribe to this comment feed via RSS