One url Apache-style 301 redirects in nginx

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 :

Redirect 301 /original_location/

where is where the client is looking for the file, but would not find it, and 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 ^/(.*) 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/ 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/ 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 thoughts on “One url Apache-style 301 redirects in nginx

  1. 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. 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

  3. 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!

Comments are closed.