How to rewrite url in nginx after matching the location - nginx

I am learning nginx, trying to setup an in-house server. My configuration is:
upstream app{
server app:8000;
}
server {
listen 80;
location /api/app/ {
proxy_pass http://app;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
}
I want to request nginx with localhost/api/app/admin, but my app can only respond to app:8000/admin. Hence, I want only admin/ to be passed to the application. I tried using rewrite, but was not able to get the desired result.

Related

I want to host a static website on EC2 with nodejs app too

I am trying to host a static website on EC2 but no luck.
here is my config file node
server {
listen 80;
server_name localhost;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass "http://127.0.0.1:3000";
}
}
I want to host static website too.
How can I do that on EC2
I'm not sure how I can explain it end to end. I hope you got a basic idea of how it works.
From your question, I can understand that you are having some problems with the Nginx configuration.
your Nginx config file should look like this,
location / {
# This would be the directory where your frontend code resides
root /var/www/html/;
try_files $uri /index.html;
}
location /api {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000/;
proxy_set_header Host $http_host;
proxy_redirect off;
}
You can use PM2 for running the nodejs app in your VM.
Here Nginx would be webserver for your frontend application and a proxy to your backend application, all the request is going to hit on your Nginx server.
I hope this is what you are looking for.

Reverse proxy with nginx

I want to use reverse proxy with nginx to redirect/translate IP and port to some other IP and port. I was able to do that using the following code snippet inside http block of nginx.conf:
server {
listen 80;
server_name 13.88.1.1;
location / {
proxy_pass http://13.68.1.1:8888/;
index index.html index.htm;
} # end location
} # end server
Now the problem is that this is only usable for http requests. I have a scenario where I need to run an executable like 'uw.exe 13.88.1.1:80'. This is getting translated to 'uw.exe http://13.68.1.1:8888' but I want it to get translated to 'uw.exe 13.68.1.1:8888'. That is without the http because my app won't work with http. Does anybody know any simple solution to do that, preferably with nginx itself?
Update: This is no longer needed and cannot test it anymore. Thanks guys for chiming in. :)
Try this nginx configuration:
server {
listen 80;
location / {
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-Proto $scheme;
proxy_set_header Connection '';
proxy_redirect off;
proxy_pass http://13.88.1.1:8888/;
}
}

Nginx directs request to www.example.com but not to internal web application

I've installed several web applications on different ports on the same server. From that server when I send an http request using wget or curl the request goes through and I get the response. I've set up nginx server to not have to specify the port each time. Here's the related nginx config:
server {
listen 10.0.223.34:80;
server_name app1.domain.com;
access_log /var/log/nginx/app1.domain.com.access.log;
error_log /var/log/nginx/app1.domain.com.error.log;
location / {
proxy_pass http://10.0.223.34:8080;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
If I try app1.domain.com from outside I get 502 Bad gateway error. But if I change the proxy_pass to http:\\www.example.com, then nginx takes me to the example.com website.
Inside the nginx.conf file I've specified user nginx;. I've tried changing it to root but it didn't help either. Do you have any idea what else I need to check?
Try this:
upstream app1 {
server localhost:8080;
}
server {
listen 10.0.223.34:
server_name app1.domain.com;
access_log /var/log/nginx/app1.domain.com.access.log;
error_log /var/log/nginx/app1.domain.com.error.log;
location / {
proxy_pass http://app1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

Avoid duplication in password protect URL with proxy in nginx

I have a Flask application served using gunicorn, and with NGINX on top of it. I want to use Basic Authentication (user/password) to protect all URL's starting with /admin, which is the back office, but still continue serving all other URLs with gunicorn without password.
Here is my current NGINX config:
server {
listen 80;
server_name example.com;
charset utf-8;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /admin {
auth_basic "Administrator Login";
auth_basic_user_file /home/app/.htpasswd;
# the following four directives are duplicated :(
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
If I don't duplicate the proxy_* directives in the second location block, then the URLs starting with /admin doesn't get forwarded to gunicorn and I get a 404.
Is there any way to avoid the configuration duplication? I tried location nesting but apparently in the end NGINX only "executes" a single location block.
The proxy_pass must be within the location block. However, there's no need to duplicate the proxy_set_header directives, they can be moved into the server block. So your mistake was simply the assumption that proxy_pass could live in the server block :-)

Tornado app in multiple nginx locations

I have 2 tornado applications and I am trying to use nginx as a proxy for them, but I need those applications to be served in the same address but different locations (Access app1 with URL http://myserver/app1, and app2 with URL http://myserver/app2).
My nginx configuration file /etc/nginx/conf.d/myserver.conf:
upstream app1 {
server 127.0.0.1:8081;
server 127.0.0.1:8082;
}
upstream app2 {
server 127.0.0.1:9081;
server 127.0.0.1:9082;
}
server {
listen 80;
access_log /var/log/nginx/myserver.access.log;
error_log /var/log/nginx/myserver.error.log;
location app1/static {
root /path/to/app1/;
if ($query_string) {
expires max;
}
}
location app2/static {
root /path/to/app2/;
if ($query_string) {
expires max;
}
}
location /app1/ {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass http://app1/;
}
location /app2/ {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass http://app2/;
}
}
When I access, for instance, app1 via tornado it works fine:
Via tornado: http://myserver:8081/ redirects to login http://myserver:8081/auth/login. Good.
Via nginx: http://myserver/app1 redirects to http://myserver/auth/login (it should redirect to http://myserver/app1/auth/login).
What is the correct nginx configuration to make it work?
This is controlled by the proxy_redirects setting. You've turned it off, so when the tornado server redirects to /auth/login that gets passed through as-is. You need to either make the tornado server aware of its urls as seen by the outside world (i.e. include /app1/ in all the routes and redirects even internally) or turn on proxy_redirects to have nginx remap them. I recommend the former, since proxy_redirects only works for redirects and you'll usually run into similar issues in other places (urls for static content, for submission, etc).

Resources