Note: This article was originally published in 2014. Some steps, commands, or software versions may have changed. Check the current NginX documentation for the latest information.
Prerequisites
Before you begin, make sure you have:
- A Linux server with Nginx installed
- Root or sudo access to the server
- Basic understanding of web server configuration
How to: Override a Location directive on (</technologies/web/nginx/nginx/> “What is: NginX”)
Sometimes when coding you are in need to re-use a lot of the logic across different systems but find yourself needing to overwrite some of that functionality on a special case. In this particular scenario I needed to overwrite a Location directive on NginX. What do I mean by that? Well, I do a lot of includes as a lot of functionality is shared across several sites but from time to time I have a special request/need where I need to implement custom behavior. For that reason I was defining a Location directive twice on NginX. To avoid itI could had dropped an include but it would mean manually maintaining a copy of some directives specially for this site. To avoid that I was looking for a way to define a Location directive twice and have one of them take preference. For those using EasyCamp’s EasyEngine you might find yourself trying to overwrite some of the default functionality/configuration but come across issues when trying to define the same location elsewhere.
When you declare the same Location directive on NginX you get an error indicating:
nginx: duplicate location “/wp-login.php” in /etc/somepath/common.conf:25
In order to achieve this functionality I relied on NginX ability to stop processing further location directives. You need to change the declaration of the Location directive by using a different operator. Like, if you were using the = operator, have the new definition use the ^~ operator. Below is an example:
location = /wp-login.php
becomes
location ^~ /wp-login.php
If you read NginX’s documentation: https://wiki.nginx.org/HttpCoreModule#location you’ll find the following:
This directive allows different configurations depending on the URI. It can be configured using both literal strings and regular expressions. To use regular expressions, you must use a prefix:
- ”~” for case sensitive matching
- ”~*” for case insensitive matching
- there is no syntax for NOT matching a regular expression. Instead, match the target regular expression and assign an empty block, then use location / to match anything else.
The order in which location directives are checked is as follows:
- Directives with the ”=” prefix that match the query exactly (literal string). If found, searching stops
- All remaining directives with conventional strings. If this match used the ”^~” prefix, searching stops.
- Regular expressions, in the order they are defined in the configuration file.
- If #3 yielded a match, that result is used. Otherwise, the match from #2 is used.
So all directives were searching stop would help you to completely overwrite a Location directive. As I mentioned, you need to leverage the fact that NginX considers a query with different operator an entirely different Location directive avoiding the “duplicate location” error message when running “nginx -t” to verify your configuration.