Last week I decided to try some deep diving for back end in the Telescope repository. I found a very legitimate issue which I felt would be good to implement. Along the way I learned a lot about how nginx works.
Once I was able to understand how nginx uses the template files to redirect, I realized the logic behind the issue was actually simple. However, for someone who doesn't know what nginx is, it is not so easy to implement.
The Issue:
The task at hand is to redirect all calls from https://dev.telescope.cdot.systems/deploy
and https://telescope.cdot.systems/deploy
to the actual auto deploy port which is at https://dev.telescope.cdot.systems:4000
or https://telescope.cdot.systems:4000
. The reason for this is that the port value is difficult to remember and not really user friendly. (Programmers can't be bothered to remember every port... I mean can you imagine?).
Understanding redirects in nginx
In order to redirect using nginx, we normally have code which looks like this:
server {
listen 80 default_server;
server_name _;
return 307 https://$host$request_uri;
}
This code block can be translated to:
listen to port 80, the default server.
server_name _;
means that we can accept any requests on this port, and return 307 https://$host$request_uri;
says to return 307 as the header(code 307 is temporary redirect), and then the route to redirect to. The variables host
and request_uri
are defined higher up in the template file.
This one is simple enough right?
So, why is it so difficult to redirect?
- The redirection can only be viewed on dev or stage. Currently I don't have privileges for this, and honestly I'm not too familiar with the code base to earn this.
- The redirection is for all route parametres, including anything followed after
/deploy
. For example, in this case we need it for/deploy/status
and/deploy/log
- We need the same results when we navigate in the browser and in the command line.
Progress #1
Find out exactly where you need to use the redirect. I was lucky enough to have help and was told you don't really need to specify the server. So because this was a redirect, we can use /location
to specify the route to redirect. I was also helped with finding the correct server to put this under.
Progress #2
The first attempt at the issue looked like this:
location /deploy/log {
return https://${TELESCOPE_HOST}:4000/log;
}
This worked... but it didn't work in the CLI. We quickly learned to use the proxy_pass method instead.
Progress #3
As you guessed it, we put it in as a proxy_pass.
location /deploy/log {
proxy_cache_bypass 1;
proxy_pass https://${TELESCOPE_HOST}:4000/log;
}
So this worked!
Why wasn't this the final code?
It really isn't the best solution. For example if tomorrow we decide to put another route on the autodeploy servers /deploy/newroute
will not work. We need to add another redirect. What happens when we have 20+ redirects now in this area?
Progress #4
To make this solution correct for future features on port 4000, I was provided with this solution:
# Redirect traffic from /deploy/* to the autodeployment server
location /deploy {
proxy_cache_bypass 1;
proxy_pass https://${TELESCOPE_HOST}:4000$request_uri
}
This made absolute sense to me, and we went and tested it.. but the problem is request_uri picks up all the parameters after the server route. The redirect was actually going to https://${TELESCOPE_HOST}:4000/deploy/log
. After reading, and searching some solutions, I found an article which actually worked to solve the same problem.
The third answer seems to be simple enough to explain:
location /foo/ {
proxy_pass http://localhost:3200/; # note the trailing slash!
}
so as long as you end the route you want to redirect with the slash /foo/
and the proxy_pass also ends in the slash, you can redirect all parameters in the route to the route you want.
Final code:
# Redirect traffic from /deploy/* to the autodeployment server
# extra slash for accepting all request_uri e.g. /deploy/status
location /deploy/ {
proxy_cache_bypass 1;
proxy_pass https://${TELESCOPE_HOST}:4000/;
}
We made sure to write a note for future contributors. A little later we realized a similar redirection was already implemented in the same file - however, since we weren't too familiar with the redirection using nginx, we could not understand the intention, and overlooked it.
Top comments (1)
Great !! … thanks for sharing !! 👍😎