How to keep Nginx upstream for ExpressJS routes? - node.js

I have an express app with two routes: an index route (/) and an article route (/article).
Now I try to deploy this application on an Ubuntu server behind a Nginx.
The problem I have is that the index route available at https://servername/app works fine, however, if I am entering a route (starting from index) via the upstream /app is lost and I am routed to https://servername/article/param which clearly is not available as I would like to be routed to https://servername/app/article/param.
It works smoothly on my local computer where no upstream/Nginx is interposed.
My Nginx config looks as follows:
upstream app {
server localhost:3000;
}
server {
#listen [::]:80 default_server ipv6only=on;
#root /usr/share/nginx/html;
# index index.html index.htm;
# Make site accessible from http://localhost/
server_name example.test.at;
#Enable the verification for letsencrypt
location /.well-known {
root /usr/share/nginx/html;
}
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# try_files $uri $uri/ noen;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.test.at/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.test.at/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location ~^\/(images|stylesheets|fonts|javascripts) {
expires 1M;
access_log off;
add_header Cache-Control "public";
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET;
add_header Access-Control-Allow-Headers X-Requested-With,content-type;
add_header Access-Control-Allow-Credentials true;
root /var/www/webviews/app/public;
}
location ^~ /app {
#rewrite ^/noen(/.*)$ $1 break;
proxy_pass http://app/;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
}
}
server {
if ($host = example.test.at) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 ;
server_name example.test.at;
return 404; # managed by Certbot
}
Do you see any issues in my Nginx config?

I missed a location section for the article, where the (.*) handles the param (subpath):
location ~^/article/(.*) {
proxy_pass http://noen;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
}

Related

I get 500 internal server error when I try to reach the website. I run nginx postgres and keycloak in docker container

500 internal server error
when checked the nginx container logs this is the error that was showing.
rewrite or internal redirection cycle while internally redirecting to "/index.html", client: x.x.x.x, server: *.domain.com, request: "GET / HTTP/1.1", host: "master.domain.com
In location /auth when mentioned localhost keycloak cannot be reached when localhost is replaced with ip in nginx config it works fine.
Below is the nginx config file
server {
listen 80;
listen [::]:80;
server_name domain.com;
#root /usr/share/nginx/html;
root /home/admin/newprodle/frontend/build/;
index index.html;
return 301 https://$host$request_uri;
}
server{
listen 443 ssl;
server_name *.domain.com domain.com;
ssl_certificate /etc/nginx/fullchain.pem;
ssl_certificate_key /etc/nginx/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:MD5;
root /home/admin/newprodle/frontend/build;
# root /usr/share/nginx/html;
index /index.html;
client_max_body_size 10M;
location / {
try_files $uri $uri/ /index.html;
}
location /auth {
proxy_pass http://localhost:8080;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
}
location /api {
proxy_pass http://localhost:5000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
}
location \~ .(jpg|png|jpeg|gif|pdf|xlxs|xl|doc❘docx) {
add_header 'Access-Control-Allow-Origin' '*' always;
root /home/admin/newprodle/backend/src/uploads;
}
location /socket.io {
proxy_pass http://localhost:5000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
}
}

Socket.io connection from ReactJS is not being redirected by nginx as any other

I have a React web App which uses axios to communicate with the backend API. Backend receives all requests from suffix /api address. And after that, those are redirected by nginx to localhost:1337 where my backend listens to requests. Everything works okay but the socket connection. The console says it can not find domain/socket.io/... but it should be domain/api/socket.io/.... My connection in the client code:
const ENDPOINT = "https://sinavhukuk.com/api";
const socket = io(ENDPOINT);
Would mention that Strapi is used as a backend service (NodeJS).
Here is /etc/nginx/sites-available/default file configuration.
server {
# Listen HTTP
listen 80;
server_name sinavhukuk.com www.sinavhukuk.com;
# Redirect HTTP to HTTPS
return 301 https://$host$request_uri;
}
server {
# Listen HTTPS
listen 443 ssl;
server_name sinavhukuk.com www.sinavhukuk.com;
# SSL config
ssl_certificate /etc/letsencrypt/live/sinavhukuk.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sinavhukuk.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
# Static Root
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $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 Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass_request_headers on;
}
# Strapi API and Admin
location /api/ {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://localhost:1337;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $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 Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass_request_headers on;
}
}
It is responsible for redirecting /api/...s to localhost:1337. But on socket it is not completely redirected. The error I get is:
https://sinavhukuk.com/socket.io/..... is not found
As I said, if the nginx worked here as always, it should be
https://sinavhukuk.com/api/socket.io/.....
What am I doing wrong?
EDIT: Added redirection from /socket.io/ to /api/socket.io/ manually, but still redirection happens to /socket.io/ instead of /api/socket.io/
# Socket.io
location /socket.io/ {
proxy_pass http://localhost:3000/api/socket.io/;
}

Nginx Not finding static files

I'm trying to serve some static files (images) on nginx and I'm always getting 404.
This is the url I'm testing:
/uploads/test.png
I have the folder with the images in:
/root/project/server/uploads
This is my nginx configuration:
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name domain.com www.domain.com;
location ^~ /assets/ {
gzip_static on;
expires 12h;
add_header Cache-Control public;
}
location /uploads {
alias /root/trendcircle/server/uploads;
try_files $uri $uri/ =404;
autoindex on;
}
location /api {
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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 Access-Control-Allow-Origin '*';
proxy_set_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
proxy_set_header 'Access-Control-Allow-Headers' 'X-Requested-With, Accept, Content-Type, Origin, x-access-token';
proxy_pass http://localhost:8080;
}
location / {
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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_pass http://localhost:8081;
}
}
Can some one help me?
Thanks in advance!!
The folder didn't have the same user as the user running nginx. If it by executing this command:
chmod o+x /root

nginx reverse proxy for nodejs express,works with ip address but not domain name

I have nginx works as a reverse proxy for a node.js express application.
I can access to
http://ip:8081/data/emoji.json
but it doesn't work with domain name
http://domain_name/data/emoji.json
doesn't work.
Here is the configuration of nginx:
server {
listen 80 default_server;
listen [::]:80 default_server;
index index.html index.htm index.nginx-debian.html;
server_name domain_name;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:8081;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /mongo {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
rewrite /mongo/(.+) /$1 break;
proxy_pass http://127.0.0.1:28017;
break;
}
}
}

Nginx forward /socket.io requests to proxied nodejs server

I am trying to forward all /socket.io requests to /broadcaster. Here is my nginx config:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
access_log /home/ubuntu/logs/broadcaster/access.log;
error_log /home/ubuntu/logs/broadcaster/error.log;
root /usr/share/nginx/html;
index index.html index.htm;
# Make site accessible from http://localhost/
server_name localhost;
# Enable WS
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
location /broadcaster {
rewrite ^/broadcaster/(.*) /$1 break;
proxy_pass http://127.0.0.1:1337;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
# simply forward socket.io requests.
# only one site can run socket.io on this server now
location /socket.io {
proxy_pass http://127.0.0.1:1337;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection $connection_upgrade;
}
}
When I (socket.io) makes a request like GET http://my-ec2-public-dns/socket.io/1/?t=1408981904508 I get the error 400 (Bad Request).
How can I nginx forward the /socket.io requests?

Resources