Nginx Resource not found on refresh with React router - reactjs

I am running a React app on Nginx in production.
If I refresh on any route different that "/" I get "Resource not found".
for example:
Refresh on http://www.aaaa.com will be OK
Refresh on http://www.aaaa.com/bbb/ddd will result in Resource not found.
I searched a lot and tried everything I found including adding try_files $uri $uri/ /index.html;
This is part of my conf file:
upstream ggg_stream {
server ggg.aaa.com:9090 fail_timeout=0;
}
server {
listen 80;
server_name aaa.com;
root /var/www;
location / {
try_files $uri $uri/ /index.html;
}
location /ggg {
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;
# Fix the "It appears that your reverse proxy set up is broken" error.
proxy_pass http://ggg_stream/;
proxy_read_timeout 90;
# proxy_redirect http://127.0.0.1:8080 http://34.248.183.236:8080;
# Required for new HTTP-based CLI
proxy_http_version 1.1;
proxy_request_buffering off;
}
}
This server also used as a proxy so it has many stream mappings such as ggg
The site content is located at /var/www
We use React router 4.
Any ideas?
Regards,
Ido

Related

How to configure nginx for 2 react + express app

i've been struggling to configure the sites-available config file and was hoping to get some guidance. I'm trying to point sub.domain.com/app1 and sub.domain.com/app2 to the correct location. I have 2 react and express running on port 2000 and port 3000, and they are both working file when accessing the ip address and port number (xx.xx.xx.x:2000). One of the app works if the location is root(/), but as soon as I try to change the location or add another the page turns blank. Any help would be appreciated.
server {
listen 80;
server_name sub.domain.com;
location /app1 {
proxy_pass http://localhost:2000;
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;
proxy_buffering off;
proxy_request_buffering off;
proxy_cache_revalidate on;
}
location /app2 {
proxy_pass http://localhost:3000;
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;
proxy_buffering off;
proxy_request_buffering off;
proxy_cache_revalidate on;
}
}
If you have a standard react application(not a next.js one) then you will need to first build it and then you have to place it in the correct path, as example /var/www/html/app1/
So your default.conf would include the following:
location /app1 {
alias /var/www/html/app1/;
try_files $uri /index.html =404;
}
location /app2 {
alias /var/www/html/app2/;
try_files $uri $uri/ index.html =404;
}
Now, if you run CRA then you should have a look on their deployment guide, especially in Serving the Same Build from Different Paths

How to host an MS Teams app in a container with an nginx proxy pass

I have to host my teams app under https://mysite/myapp
The host is ruled by nginx like that
location /myapp {
proxy_pass http://ip:port;
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_http_version 1.1;
proxy_set_header Connection "";
}
http://ip:port is the real host of the teams app inside a docker container.
This is the nginx config for the container
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
this is the docker file (a part of it)
FROM nginx:alpine
COPY --from=build /nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /build /usr/share/nginx/html
If I try http://ip:port/tab I see
If I try https://mysite/myapp/tab I can't see any message from the page and the browser seems to load the index.html page
Is there a way to make the react routing work with this settings?

react, nginx reverse proxy and docker giving 404

So my website has two parts:
1- /api, /oauth and /assets locations are redirected to a laravel app and using a simple proxy_pass to their docker port
2- the web app, which is a react app. We make an image of the web app(so no files are transferred to the server) and run it on a port, say 3000.
This is a summary of my Nginx configuration:
server {
server_name mywebsite.com;
location /api {
proxy_pass http://localhost:8080/api;
proxy_set_header Host $host;
} //the same with other Laravel paths
location / {
proxy_pass http://localhost:3000/;
proxy_set_header Host $host;
proxy_redirect off;
}
}
The problem is if the user goes to a page, say site.com/profile and refreshes it, they get a 404 error. Googling a lot resulted to use try_files .. index.html which works with local files, but not when using proxy_pass and docker images.
More googling had me find a solution that actually worked:
server {
server_name mywebsite.com;
location /api {
proxy_pass http://localhost:8080/api;
proxy_set_header Host $host;
} //the same with other Laravel paths
location / {
proxy_pass http://localhost:3000/;
proxy_set_header Host $host;
proxy_redirect off;
proxy_intercept_errors on;
recursive_error_pages on;
error_page 404 = #rewrite_proxy;
}
location #rewrite_proxy {
rewrite ^/(.*)$ /index.html?$1 break;
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
}
}
It's brilliant and works like a charm. Now the problem is, I'm looking for a solution to give control of ACTUAL 404 errors to the web app, so it can react in different ways depending on the URL. Any suggestions?
Check out this, hope this will help you out
server {
listen 80;
location /api {
proxy_pass http://backend/api;
proxy_redirect off;
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-Host $server_name;
}
location / {
proxy_pass http://frontend;
proxy_redirect off;
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-Host $server_name;
try_files $uri $uri/ /index.html #backend;
error_page 405 #backend;
}
location #backend {
proxy_pass http://frontend;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
}
}

Cannot use url to navigate in react through nginx

I am serving my static file using nginx(react frontend).
I have used different urls like /login /user /home for each page.
My nginx doesn't redirect these to my index.html file.
I made some changes and now I cannot get my main page either. It returns cannot get /.
This is my nginx.conf file. I am running it on windows. My index.html is inside the build folder. How do I get my nginx to use Router and Link in reactjs, so that I can get the page by referring to the link or through navigation bar?
worker_processes 5;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name ip;
location / {
root /Users/username/projectfolder/build;
index index.html index.htm;
try_files $uri $uri/ index.html;
proxy_pass http://ipaddress:portnumber;
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;
}
}
}
UPDATE:
I have tried the following configuration
server {
listen some_port;
server_name some_ip;
root C:\\nginx-1.17.1\\build\\;
index index.html index.htm;
location /test/ {
alias C:\\nginx-1.17.1\\build\\;
index index.html index.htm;
try_files $uri \\index.html;
#internal;
#return index;
}
location = /index.html {
# no try_files here
return 502;
}
location / {
#root C:\\Users\\DEV-a0a02yc\\insurance_automation\\build;
try_files $uri $uri\ \index.html?$args;
#try_files $uri/ index.html;
proxy_pass http://some_ip:some_port;
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;
}
}
In the /test/ url I am getting a blank page and a rewrite/internal redirection error saying :
2019/07/01 09:53:22 [error] 17820#18008: *1 rewrite or internal redirection cycle while internally redirecting to "/favicon.ico\ \index.html\ \index.html\ \index.html\ \index.html\ \index.html\ \index.html\ \index.html\ \index.html\ \index.html\ \index.html\ \index.html"
This is my network tab:
How do I serve my index.html file here to handle redirection when entering this url?
What are the proxy lines for in your configuration?
Shouldn't you either serve from html files or proxy pass to a different address?
I would suggest trying to remove the proxy lines from the configuration.
Also on an unrelated note the proxy_pass line is invalid. The server address "ipaddress" is a far stretch (though not impossible with dns) and the port "portnumber" is definitely invalid.
So the minimum required configuration is the following:
location / {
root /folder/subfolder/build;
try_files $uri /index.html;
}
root defines your react build folder location and try_files defines that nginx should look if the requested file exists, if not it serves the index.html.

nginx loopback reverse proxy can't access custom paths

Im running this loopback app in my server and trying to access it through an nginx reverse proxy, but can't seem to get nginx configured correctly, I'm a total noob to nginx. Here's my config file /etc/nginx/sites-available/example.com
server {
listen 80;
server_name www.example.com;
server_name example.com;
server_name _;
root /apps/example/client;
location ~ ^/.well-known {
allow all;
}
location / {
return 301 https://example.com;
}
}
server {
server_name example.com;
server_name www.example.com;
#listen 80;
# SSL configuration
listen 443 ssl ;
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
root /apps/example/client;
# Check Alive
location ~ ^/.well-known {
allow all;
}
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_bind 127.0.0.1;
proxy_pass http://127.0.0.1:3000/;
}
location /api {
proxy_pass http://127.0.0.1:3000/api;
}
location /explorer {
proxy_pass http://127.0.0.1:3000/explorer;
}
}
and my loopback server serves static files like this:
app.use(loopback.static(path.resolve(__dirname, '../client')));
and at the end of my server.js file I serve the index.html file for any path not processed so angular processes that path in the front end
function startsWith(string, array) {
for(let i = 0; i < array.length; i++)
if(string.startsWith(array[i]))
return true;
return false;
}
let ignoredPaths = ['/css', '/fonts', '/img', '/js', '/lib', '/sfx', '/views', '/api'];
app.all('/*', function(req, res, next) {
//Redirecting to index only the requests that do not start with ignored paths
console.log("Requested url: ",req.url);
if(!startsWith(req.url, ignoredPaths)) {
res.sendFile('index.html', {root: path.resolve(__dirname, '../', 'client')});
} else {
next();
}
});
The issue is that I can only access http://www.example.com/ and it takes a lot to load and the url flashes many times like it's redirecting a lot of times, I redirect in front-end with angular to /home, I have the angular routing to use html5 to remove the /#!/ from the path, but I always get a Bad Gateway error if I try to access any other path, say http://www.example.com/admin/login and it's a nginx error, it's not reaching loopback so it can serve the index file. I've tried the try_files $uri $uri/ /index.html; but if I try to access any other custom path, say /auth/facebook it forces it to load it through index.html and that's a custom path I have setup on loopback to do special behaviour. I have no idea how to solve this, I just used that template config file, all I need is for it to redirect all requests from example.com to my app in localhost:3000 and do the same in the opposite direction.
So i kept trying, and tried again using the try_files with a #path (I guess that's kind of a label or something) and what I was missing when I tried it before was to attach $uri at the end of the proxy_pass
It ended up like this:
location / {
try_files $uri $uri/ #proxy;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_bind 127.0.0.1;
proxy_pass http://127.0.0.1:3000/;
}
location #proxy {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_bind 127.0.0.1;
proxy_pass http://127.0.0.1:3000$uri;
}
And all works dandy now :P.

Resources