When using Nginx as a reverse proxy, the server_name, location, and proxy_pass directives are almost always required. However, each of them has several variations, and the subtle differences can easily lead to pitfalls. Here's a quick reference.


Variations of server_name

1. Exact domain name matching

server_name example.com www.example.com;

The most common approach is to directly write the domain name; multiple domains can be written, separated by spaces.

2. Wildcard Matching (Prefix or Suffix)

server_name *.example.com;          # 匹配所有子域名,如 www.example.com, mail.example.com
server_name example.*;              # 匹配所有后缀,如 example.com, example.org
server_name *.example.*;            # 匹配子域名和后缀,如 www.example.com, mail.example.org

Wildcards can only appear at the beginning or end, not in the middle. For example, www.*.com is not allowed.

3. Regular Expression Matching

server_name ~^www\d+\.example\.com$;    # 匹配 www1.example.com, www2.example.com 等
server_name ~^(.*)\.example\.com$;      # 匹配所有 example.com 的子域名

The regular expression starts with ~, and Nginx will match based on the regular expression. However, regular expressions have lower priority than exact matches and wildcard matches, and their performance is slightly worse. Use wildcards whenever possible instead of regular expressions.

4. Empty Value (Default Host)

server_name "";
# 或
server_name _;

"" matches requests without a Host header. _ is not actually special syntax; it's just a domain name that can never be truly matched, typically used as a fallback default server.

5. IP Addresses

server_name 192.168.1.1;

This server block will be matched when accessed directly via IP.

6. Variables

server_name $hostname;  # 使用服务器的主机名

$hostname automatically retrieves the server's hostname, although this syntax is rarely used.

7. Combining Usage

server_name example.com *.example.com ~^www\d+\.example\.com$;

Multiple matching methods can be used together. The priority of Nginx's location matching is: exact match > prefix wildcard > suffix wildcard > regular expression.


What is the difference between location /, location /image, and location /image/?

These three look similar, but their matching behaviors differ.

Impact of Trailing Slashes

  • location /image matches /image and /image/, and even /imageabc will match (because it is a prefix match).
  • location /image/ only matches paths starting with /image/, such as /image/photo.jpg, but will not match /image (in the absence of a trailing slash).

If a client requests /image, location /image will handle it, while location /image/ will not match. The request may fall back to location /.

Priority When Multiple locations Exist

Nginx selects the prefix with the longest match. For example, consider a request for /image/photo.jpg:

  • If location /image/ exists, it takes priority.
  • If only location /image exists, it matches.
  • If neither exists, it matches location /.

location / has the shortest prefix, so it acts as a catch-all; any path can match it.


Difference Between Trailing and Non-Trailing Slashes in proxy_pass

This is one of the most common pitfalls with Nginx. Whether or not there is a trailing / after proxy_pass completely changes the forwarded path.

Assume our location block is defined as follows:


```nginx
location /api/ {
    proxy_pass ...;
}

1. proxy_pass http://backend (without path)

location /api/ {
    proxy_pass http://backend;
}

Request http://example.com/api/users is forwarded to http://backend/api/users.

The original URI /api/users is preserved intact and directly appended to the backend.

2. proxy_pass http://backend/ (with trailing slash)

location /api/ {
    proxy_pass http://backend/;
}

The request to http://example.com/api/users is forwarded to http://backend/users.

Note that /api/ is stripped here, leaving only /users appended to http://backend/. This happens because when proxy_pass includes a path (even just /), Nginx replaces the prefix matched by the location block.

For example, a request to http://example.com/api/ is forwarded to http://backend/.

3. proxy_pass http://backend/image (with specific path)

location /api/ {
    proxy_pass http://backend/image;
}

Forward requests to http://example.com/api/users to http://backend/imageusers.

This illustrates the pattern: Nginx removes the matched /api/ portion from the location and appends the remaining users directly to http://backend/image, resulting in /imageusers—which is usually not what you want.

If you intend to forward to /image/users, it should be written as:

location /api/ {
    proxy_pass http://backend/image/;
}

Summary of the pattern

Simply put:

  • proxy_pass without a path component (e.g., http://backend): The original URI is forwarded as-is.
  • proxy_pass with a path component (e.g., http://backend/ or http://backend/xxx): The prefix matched by the location block is replaced by the path part in proxy_pass.

This distinction regarding / may seem minor, but mixing them up will route requests to the wrong path, making troubleshooting quite tedious.

This content is automatically translated to English. View Original