72

I've developed a URL shortening web application.

It consists of two separate docker containers: one containing the backend REST api and another containing the frontend static website.

These two containers are linked to an nginx container. The configuration for this nginx container is below:

worker_processes 1; events { worker_connections 1024; } http { upstream api { server short-url:8080; } upstream frontend { server short-url-frontend:8081; } gzip on; gzip_vary on; gzip_min_length 860; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain text/css text/xml application/javascript application/x-javascript application/xml; gzip_disable "MSIE [1-6]\."; server { listen 80; root /user/share/nginx/html; location /urlshortener/v1 { proxy_pass http://api/urlshortener/v1; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $server_name; } location ~ ^/([A-Za-z0-9]+) { rewrite ^/([A-Za-z0-9]+) /$1 proxy_pass http://api/urlshortener/v1; } location / { proxy_pass http://frontend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-for $remote_addr; } } } 

If a url ends with /urlshortening/v1, I'm proxying to the backend.

If a url starts with /, I'm proxying to the frontend.

Shortened urls e.g. /3xTy or /a0q need to be proxied to the backend so that the user can be navigated to the original url. In order to do this, I've defined a location with a regular expression.

location ~ ^/([A-Za-z0-9]+) { rewrite ^/([A-Za-z0-9]+) /$1 proxy_pass http://api/urlshortener/v1; } 

This block of code gives me the following error:

2018/11/17 16:47:03 [emerg] 1#1: "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /etc/nginx/nginx.conf:36

I've gone through several examples and reviewed a number of answers and I believe that the configuration I have should work. Can someone please explain why I'm getting this error?

4
  • 1
    Your proxy receives a request for /3xTy, what is the full URI to be passed upstream? http://api/urlshortener/v1/3xTy? Commented Nov 17, 2018 at 17:51
  • @RichardSmith: Yes, that is what I'm trying to accomplish Commented Nov 17, 2018 at 17:53
  • 2
    Remove the rewrite statement and try: proxy_pass http://api/urlshortener/v1/$1; Commented Nov 17, 2018 at 17:54
  • 1
    Thank you, that solved it! Why was the rewrite statement not applicable in this case? If you could write your comment as the answer, I'd upvote and accept it :) Commented Nov 17, 2018 at 18:18

2 Answers 2

102

If you use a URI with a proxy_pass statement within a regular expression location, you need to build the entire URI using one or more variables. See proxy_pass docs for details.

So the alternatives are to (1), capture the URI from the location expression and add it to the proxy_pass statement. For example:

location ~ ^/([A-Za-z0-9]+) { proxy_pass http://api/urlshortener/v1/$1; } 

Or (2), use proxy_pass without a URI part, and construct the desired URI using a rewrite...break. For example:

location ~ ^/([A-Za-z0-9]+) { rewrite ^/([A-Za-z0-9]+) /urlshortener/v1/$1 break; proxy_pass http://api; } 

See rewrite docs for details.

Sign up to request clarification or add additional context in comments.

Comments

14

I was getting same error and the correct answer could not be helping in my situation. here was my problematic configs:

# proxying wordpress static files location ~* (((product|blog|product-category)\/.*)|(\.(ogg|ogv|svg|svgz|eot|otf|woff|woff2|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)))$ { proxy_pass https://mainhost.cdkeysell.ir/; ... } 

so after comparing it with my other wesite with similar configs without such error I found this could be simply solved by removing the latter / at end of proxy_pass config:

# proxying wordpress static files location ~* (((product|blog|product-category)\/.*)|(\.(ogg|ogv|svg|svgz|eot|otf|woff|woff2|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)))$ { # proxy_pass https://mainhost.cdkeysell.ir/; ==> final `/` caused error proxy_pass https://mainhost.cdkeysell.ir; ... } 

1 Comment

thank you very much, removing / at the end solved by issue.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.