0

I've an nginx configuration for about 40+ nodes server all written like:

location /39/api {
    proxy_pass http://172.31.32.233:3138;
}

location /io39 {
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_pass http://172.31.32.233:3138;
}

location /40/api {
    proxy_pass http://172.31.32.233:3139;
}

location /io40 {
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_pass http://172.31.32.233:3139;
}

As you can see the target node port increases with the ID into the /io39 and /39/api path, I know I can capture the number with a regexp into the location directive, but how can I increase the variable as an integer and use it as the destination port of the proxy, so I can write an unique directive for thousand ports ?

Thanks!

1 Answer 1

1

Although there was an evaluation regex modifier in Perl and PHP prior to 5.5, as far as I know there is no any equivalent for nginx and no regex mathematics is possible. One of the possible techniques described in this answer. For example, you can add something like 30000 this way (I use the longest 4-digit regex pattern as first because regex matching locations are checked from first to last one):

location ~ "^/(\d{4})/api" {
    set $port 3$1;
    proxy_pass http://172.31.32.233:$port;
}

location ~ "^/io(\d{4})" {
    set $port 3$1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_pass http://172.31.32.233:$port;
}

location ~ "^/(\d{3})/api" {
    set $port 30$1;
    proxy_pass http://172.31.32.233:$port;
}

location ~ "^/io(\d{3})" {
    set $port 30$1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_pass http://172.31.32.233:$port;
}

location ~ "^/(\d{2})/api" {
    set $port 300$1;
    proxy_pass http://172.31.32.233:$port;
}

location ~ "^/io(\d{2})" {
    set $port 300$1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_pass http://172.31.32.233:$port;
}

location ~ "^/(\d)/api" {
    set $port 3000$1;
    proxy_pass http://172.31.32.233:$port;
}

location ~ "^/io(\d)" {
    set $port 3000$1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_pass http://172.31.32.233:$port;
}

This will give you port number 30001 for /1/api or /io1 (as well as for /01/api or /io01), port number 30002 for /2/api or /io2 and so on up to 39999 for /9999/api or /io9999 URIs.

The other way is to use lua-nginx-module or OpenResty:

location ~ "^/(?<number>\d{1,4})/api" {
    set_by_lua_block $port { return ngx.var.number + 3099 }
    proxy_pass http://172.31.32.233:$port;
}

location ~ "^/io(?<number>\d{1,4})" {
    set_by_lua_block $port { return ngx.var.number + 3099 }
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_pass http://172.31.32.233:$port;
}
Sign up to request clarification or add additional context in comments.

1 Comment

very usefull, I found the first way as a viable solution. Thanks !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.