I want my nginx docker to be able to proxy_pass dynamically if anyhow using one simple config..
I currently use this config for three apps, but I would like to make it work dynamically that I could also use it with /xyz_987 which automatically passes to http://xyz_987:3000:
server {
listen 3000;
server_name _;
location /user1/ {
proxy_pass http://user1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
location /user2/ {
proxy_pass http://user2:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
location /user3/ {
proxy_pass http://user3:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
I tried this but it always results in a 502 Bad Gateway:
server {
listen 3000;
server_name _;
location ~ ^/(?<username>[\w]+)/ {
proxy_pass http://$username:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
# Fallback for root path
location / {
return 404;
}
}
The configuration you came up with is almost correct. The only thing you missed is a
resolver
directive, which is needed when your proxy hostname specified via variable(s). You may ask, why wouldn't nginx use the host's DNS facility? Here is a pretty good explanation:To use docker internal DNS, you need to use the user-defined network (see Networking overview - User-defined networks, Networking with standalone containers - Use user-defined bridge networks documentation pages). Another article I can recommend is Understanding Docker DNS. Docker daemon’s embedded DNS resolver listens on the IP address 127.0.0.11 by default, so you need to change your nginx configuration to
and ensure your docker containers use the user-defined network.
Try this:
The
~
specifies a Perl compatible regular expression match. Then, we match the string that starts withuser
and any numbers or letters, and captures that into the$1
variable.We cannot allow all characters here, because that would make the server an open proxy which malicious people will use to attack different targets.