Matthew Helmke (dot) Net

Random things that interest me.

One url Apache-style 301 redirects in nginx

January8

Note: this post is outdated. Use at your own risk.

In Apache, you can create an .htaccess file to house 301 Redirect statements, or you can do it in the main config file. It is easy, and common. To change the url that appears in a client browser, as well as tell it where to find something that is no longer located in an original place, you would write something like this for http://mysampledomain.com:

Redirect 301 /original_location/ http://mysampledomain.com/new_location/

where http://mysampledomain.com/original_location/ is where the client is looking for the file, but would not find it, and http://mysampledomain.com/new_location is what you want used when the original is requested as well as in the future.

Easy, right?

I searched and searched for good documentation on how to do this with nginx. I found great documentation for doing it with a regex, such as this sample code you could put in your site-specific vhost file at /etc/nginx/sites-available/mysampledomain.com for forcing browsers to use the domain name without www.

server {
listen 80;
server_name www.mysampledomain.com;
rewrite ^/(.*) http://mysampledomain.com/$1 permanent;
}

What I couldn’t find was a simple way to do static redirects, like in my sample above. So, tonight I did some experimenting and figured it out. I hope this helps someone else. Put something like this in your /etc/nginx/sites-available/mysampledomain.com file, in the main server section (see second example following this one).

location /original_location/ {
rewrite /original_location/ http://mysampledomain.com/new_location/ permanent;
}

That would fit in a file like the one I used in my previous post like this.

server {
listen 80;
server_name www.matthewhelmke.net;
rewrite ^/(.*) http://matthewhelmke.net/$1 permanent;
}

server {
listen 80;
server_name matthewhelmke.net;

access_log /home/myusername/public_html/matthewhelmke.net/log/access.log;
error_log /home/myusername/public_html/matthewhelmke.net/log/error.log;

location /original_location/ {
rewrite /original_location/ http://mysampledomain.com/new_location/ permanent;
}

location / {
root /home/myusername/public_html/matthewhelmke.net/public;
index index.html index.htm index.php;

# this serves static files that exist without running other rewrite tests
if (-f $request_filename) {
expires 30d;
break;
}

# this sends all non-existing file or directory requests to index.php
if (!-e $request_filename) {
rewrite ^(.+)$ /index.php?q=$1 last;
}

}

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/myusername/public_html/matthewhelmke.net/public$fastcgi_script_name;
include fastcgi_params;
}
}

Have fun! You now have one less reason to give why a person shouldn’t use ngnix instead of Apache.

7 Comments to

“One url Apache-style 301 redirects in nginx”

  1. On January 8th, 2009 at 9:09 pm matthew Says:

    I’ll anticipate the “why?” question. I have a few pages on this blog that are in a regular rotation on StumbleUpon and previously on Digg that still get traffic using URLs that haven’t existed in a long time, since I changed from using DotClear as my blogging platform and went to WordPress a long time ago.

    When I was using Apache, I just put some 301 Redirects in an .htaccess file and “no big deal.” The old links still worked, sending visitors to the new location.

    Switching to nginx this week, I lost that ability and couldn’t find any good documentation on how to do this (in English, it might exist in Russian…), so I decided to experiment. Hopefully someone else with a similar need will find the info useful. If not, at least I have it recorded for when/if I need it again.

  2. On January 25th, 2009 at 3:58 am mat Says:

    Quite helpful, thanks.

    mat

    And really nice design around here.

  3. On January 25th, 2009 at 8:27 am matthew Says:

    I’m glad you found it useful and thank you for the complement! I appreciate it.

  4. On March 19th, 2009 at 4:21 pm Vahid Says:

    Do you think it’ll slow down the server if I do like 300 of these? As that’s what I plan to do when i change scripts from old to new.

    thanks,
    Vahid

  5. On March 19th, 2009 at 5:11 pm matthew Says:

    Yes, but no more than using 300 redirects with Apache. Having a large number of redirects will slow down any site.

  6. On July 12th, 2009 at 3:43 pm Miles Says:

    Many thanks Matthew – this is exactly what I was looking for. I had a slew of 301 redirects in an .htaccess file, and didn’t find any other clear explanation of how to recreate them in nginx until landing here. I put the location entries right in /etc/nginx/nginx.conf instead of /etc/nginx/sites-available/example.com – worked great. Thanks again!

  7. On July 12th, 2009 at 8:46 pm matthew Says:

    You are very welcome. I’m glad you found it useful. :)