Nginx can handle the rewrite parameter differently, depending on the destination syntax.
Here are some examples how to define redirects and URL rewrites in Nginx.
The simplest form to create a redirect is to append the rewrite URL with the keyword "redirect":
server {
server_name www.example.com;
root /var/www/www.example.com;
location / {
rewrite ^/$ http://websrv1.example.com/mypage redirect;
}
}
This will result in a HTTP 302 Moved Temporarily redirect. In a browser, the URL in the address bar will change to the forwarded URL.
The 302 status above is a helpful fix for a quick redirect - but not optimized for SEO. If you create a definitive redirect, you should set the permanent keyword at the end of the rewrite config:
server {
server_name www.example.com;
root /var/www/www.example.com;
location / {
rewrite ^/$ http://websrv1.example.com/mypage permanent;
}
}
This results in a HTTP 301 Moved Permanently status. A user will see the same experience in the browser as with the 302 redirect: The URL in the address bar will change and show the redirect destination URL.
Let's try this without a redirect or permanent option but with break or last:
server {
server_name www.example.com;
root /var/www/www.example.com;
location / {
rewrite ^/$ http://websrv1.example.com/mypage last;
}
}
Although the rewrite option is now set to last, the browser will still follow the URL and changes the URL in the address bar. As soon as the rewrite destination contains http:// (or https://), this is considered an external redirect and will therefore always redirect the client (and browser).
So if you want to keep your requested URL in the browser address bar and simply want to rewrite the URL (same as with mod_rewrite in an Apache web server), you must use a relative path:
server {
server_name www.example.com;
root /var/www/www.example.com;
location / {
rewrite ^/$ /mypage last;
}
}
This will load the website for www.example.com from the subfolder /mypage within the document root (/var/www/www.example.com).
But what if the destination website is loaded from somewhere else, for example from a Tomcat upstream server in the background? The following configuration covers this:
upstream tomcat {
server 127.0.0.1:8080;
}
server {
server_name www.example.com;
root /var/www/www.example.com;
location / {
include proxy-settings.conf;
proxy_pass http://tomcat;
rewrite ^/$ /mypage last;
}
}
First everything (location /) is passed to tomcat (the defined upstream server). Then the redirect for the root path (/) is happening and is relative to the path.
This results in keeping the browser's address URL at www.example.com but loads the website from 127.0.0.1:8080/mypage.
Sometimes you may want to change the internal path, but still use (some parts of) the requested URI. You can use this by creating a selection using parentheses "()" and then refer to the selection with $1 for the first selection, $2 for the second selection and so on.
upstream tomcat {
server 127.0.0.1:8080;
}
server {
server_name www.example.com;
root /var/www/www.example.com;
location / {
include proxy-settings.conf;
proxy_pass http://tomcat;
rewrite ^/(.*)$ /mypage/$1 last;
}
}
If the original requested URL was http://www.example.com/hello-my-world, it would actually load the following URL from the upstream server: http://127.0.0.1:8080/mypage/hello-my-world.
Some address rewrites are very basic - but others might be much more complex. To verify how your rewritten request URI looks like, you can play with internal Nginx variables and show them as response headers. The following configurations shows the additional headers Requested-URI and Final-URI which will be part of the Nginx server response:
upstream tomcat {
server 127.0.0.1:8080;
}
server {
server_name www.example.com;
root /var/www/www.example.com;
location / {
include proxy-settings.conf;
proxy_pass http://tomcat;
rewrite ^/(.*)$ /mypage/$1 break;
add_header Requested-URI $request_uri always;
add_header Final-URI $uri always;
}
}
You can see these headers when using curl and looking at the response headers:
$ curl http://www.example.com/hello-my-world -I
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 21 Feb 2022 13:00:36 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Requested-URI: /hello-my-world
Final-URI: /mypage/hello-my-world
Claudio Kuenzler from Switzerland wrote on Jan 25th, 2021:
Markus, no, including a proxy settings file is not required. However you might want to use some proxy settings such as X-Forwarded-Proto or X-Forwarded-For headers. You can of course also write these settings (using proxy_set_header) or other settings (such as proxy_redirect) directly in the location context.
Markus Kugler from wrote on Jan 24th, 2021:
Thanks Claudio Kuenzler!
what is proxy-settings.conf for? Do I need it?
Claudio Kuenzler from Switzerland wrote on Jan 23rd, 2021:
Hi Markus! In this case you should redirect your root location to "/this/is/important/" and the path "/this/is/important/" is proxying to the external domain.
server {
server_name sub1.domain.com;
root /var/www/sub1.domain.com;
location / {
rewrite ^.* https://sub1.domain.com/this/is/important/ permanent;
}
location /this/is/important/ {
include proxy-settings.conf;
proxy_pass https://some-other-domain.com;
}
}
Markus from wrote on Jan 22nd, 2021:
Hi *
great tutorial thanks!
What if I want to rewrite from https://sub1.domain.com/ to physically https://some-other-domain.com/this/is/important/link.html but the browser should show https://sub1.domain.com/this/is/important/link.html
in other words some-other-domain.com needs to be hidden from the public AND url should be redirected from / to /this/is/important/link.html
thanks
Markus
ck from St. Gallen, Switzerland wrote on Apr 8th, 2015:
Hi U-lis. It worked fine in my testing environment but now I do not have access to this environment from back then anymore. But what is also possible is that your application itself (mypage) is automatically causing the redirect, not nginx. You can try with the setting "proxy_redirect off" and do the debugging with curl -v, following all the redirects manually to find out where the redirect happens.
U-lis from wrote on Mar 27th, 2015:
Hello, I have a question!
I tried your last server config to show example.com on address bar and load page from 127.0.0.1:8000/mypage.
But I got example.com/mypage on my addressbar with correct page I wanted.
Is Nginx config changed or my mistake?
I need your help. Thanks for your article.
== following is my nginx config, and I use python(gunicorn) webserver ==
upstream main { 127.0.0.1:8000 }
server {
listen 80;
server_name example.com;
location / {
include proxy_params;
proxy_pass http://main;
rewrite ^/$ /mypage last;
}
}
AWS Android Ansible Apache Apple Atlassian BSD Backup Bash Bluecoat CMS Chef Cloud Coding Consul Containers CouchDB DB DNS Database Databases Docker ELK Elasticsearch Filebeat FreeBSD Galera Git GlusterFS Grafana Graphics HAProxy HTML Hacks Hardware Icinga Influx Internet Java KVM Kibana Kodi Kubernetes LVM LXC Linux Logstash Mac Macintosh Mail MariaDB Minio MongoDB Monitoring Multimedia MySQL NFS Nagios Network Nginx OSSEC OTRS Office PGSQL PHP Perl Personal PostgreSQL Postgres PowerDNS Proxmox Proxy Python Rancher Rant Redis Roundcube SSL Samba Seafile Security Shell SmartOS Solaris Surveillance Systemd TLS Tomcat Ubuntu Unix VMWare VMware Varnish Virtualization Windows Wireless Wordpress Wyse ZFS Zoneminder