In frontend nginx check backend health for custom error page - reactjs

I have simple configuration of nginx for React application:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
server_tokens off;
server {
listen 80;
location / {
limit_req zone=mylimit burst=10;
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html =404;
}
}
Let's say that our backend load balancer address is 10.0.0.0:443. We can check it's health with going to /health endpoint. How nginx configuration should look like to have logic: if backend health returns 200 - use React app, if not - open simple error.html page. Thank you

Related

ReactJS with NGINX: How to run an SPA alongside other proxied locations on NGINX?

I have successfully deployed a MERN stack website to a Ubuntu 20.x server using pm2 and nginx. The issue I'm facing is that URL links manually entered, or links redirected from my Express routes don't work. This is because I have my nginx config file set up like this:
location / {
root /root/amfmfx.com/build;
index index.html;
# First attempt to serve request as file, then
# as directory, then fall back to displaying a
# 404.
try_files $uri $uri/ =404;
}
location /user {
proxy_pass http://loadbalancer;
proxy_buffering on;
}
location /api {
proxy_pass http://loadbalancer;
proxy_buffering on;
}
location /email {
proxy_pass http://loadbalancer;
proxy_buffering on;
}
The /usr, /api, and /email locations are my backend route receivers. I have Routes and Links set up in React that work perfectly when clicked on, but if I type in 'http://mywebsite.com/login' it comes back with an nginx error, because it's trying to send /login to the backend apparently.
How can I configure my nginx web server to allow for manual link entries to be read by the front end, while still sending route requests to my Express server?
Thanks!
As you have the root and index in your root location any non-matching location will not have a default webroot. I would change the configuration for your react app to
server {
// listen, server_name and friends ...
root /root/amfmfx.com/build;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /user/ {
proxy_pass http://loadbalancer;
proxy_buffering on;
}
location /api/ {
proxy_pass http://loadbalancer;
proxy_buffering on;
}
location /email/ {
proxy_pass http://loadbalancer;
proxy_buffering on;
}
}
I would define the locations for your backend services using a trailing slash like /api/ and /email/ for example. Reason is that without the slash nginx would match your user location for a incomming request to /userbob in the same it would do for user.
2nd the proxy_buffering can be removed IF your are not turning it off on server or http level as on is default.
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering

Why Nginx load balancer is not serving js/css files from nginx nodes?

I have load balancer with really simple config for domain.com:
server {
listen 80;
server_name domain.com;
location / {
proxy_pass http://dev-admin;
}
}
upstream dev-admin {
server ip1:8001;
server ip2:8001;
server ip3:8001;
}
IMPORTANT:
Ip1, Ip2 and Ip3 are docker containers that are made by making docker swarm service.
Now when you open ip1:8001 or any other ip2 or ip3 you got website and all is good. Website is from react build.
On each node ip1, ip2 and ip3 i have nginx with this config:
server {
listen 80;
listen [::]:80;
root /usr/share/nginx/html;
index index.html index.htm index.nginx-debian.html;
server_name localhost;
location / {
try_files $uri /index.html;
}
}
So when you try website on domain.com instead serving css or js files it is serving index.html response. So domain.com/static/some.js -> this shows in the response index.html content.
I have no idea what else to debug.
Help. Please.
It turned, out I was missing $uri/ on nodes config.
So it is:
location / {
try_files $uri $uri/ /index.html;
}

Create internal connection between React and Laravel in Docker containers on server

I am using a React app as frontend and a Laravel app for backend. These two are connected with each other through Laravel Sanctum APIs. The whole environment is deployed on the server using Docker, frontend & backend being separate containers, but connected with network: someNetwork
The API call is done from the frontend using the URL HTTP://myserverip:8000 - this is working, but I would like to close the 8000 port (externally) and just keep open the 3000 port where the frontend is working. Now when I'm closing the 8000 port (with firewall), and trying to make API request from frontend I get a network error.
The question is, how to make the API request internally so I can keep only 3000 open, do I need some kind of redirection inside the .conf file of the nginx? This is my .conf file:
server {
listen 80;
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/public;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
}
Thanks, any hint would be appreciated.
What you are trying to do will never work.
ReactJS (I guess thats what you mean by ReactApp) should be "build" before used in production. The result will be a build folder with a bunch of static files.
These files can be deployed / serverd using NGINX. The API-Calls from ReactJS (your Frontend App) will always come from outside of your network as the client / customer will not be part of your Docker NAT network (I guess).
I would use NGINX as a Webserver for your ReactApp (ReactJS Build) as well as a reverse Proxy / Proxy for your Laravel Backend.
Something like:
server {
listen 443 ssl;
server_name example.com
.....
root /path/to/your/reactapp/static/files;
location / {
try_files $uri /index.html;
}
}
server {
listen 443 ssl;
server_name api.example.com;
...all the laravel PHP config here
}
if you can not or want not create a subdomain for your API use a location
server {
listen 443 ssl;
server_name example.com
.....
root /path/to/your/reactapp/static/files;
location / {
try_files $uri /index.html;
}
location /api/ {
Do your Laravel config here (use nested locations for handling the php files)
Or do a `proxy_pass` and configure an internal server (listen `8000`) and do not expose it.
}
}

How do I configure my Nginx server to work with create-react app in a subfolder?

I'm using the create-react app template with react router and I want to deploy my app on a subfolder using nginx.
My nginx.conf file looks like this. (I'm using the nginx-alpine docker image)
events { }
http {
server {
listen 80;
# You would want to make a separate file with its own server block for each virtual domain
#access_log logs/host.access.log main;
location /procejts/myproject/ {
root /usr/share/nginx/html;
try_files $uri $uri/ /procejts/myproject/index.html;
}
}
}
However I'm getting an empty page when I go to mydomain.com/procejts/myproject
I have tried the answer here but it is giving me a 500 error “rewrite or internal redirection cycle”. I changed the
try_files $uri $uri/ /procejts/myproject/index.html;
To
try_files $uri $uri/ =404;
and I start to get 404 not found.

Nginx rewrites for React app with 2 HTML pages

so I'm building a react site using browserHistory, my current Nginx setup serves index.html for all URLs, however I have split out my admin part of the site so I need any url under /admin to server admin.html but I can;t figure it out (not a server guy!).
This is my current config, any help would be greatly appreciated!
server {
listen 80;
server_name http://178.62.98.191/;
root /www/rawnet-one-web/dist;
index index.html index.htm;
rewrite ^/(.*)/$ $1 permanent;
location / {
auth_basic "Restricted";
auth_basic_user_file /www/.htpasswd;
try_files $uri /index.html;
}
}
Based on the examples in the location documentation, you should just have to define the /admin/ location and serve the /admin.html file for any location that matches it.
location /admin/ {
try_files $uri $uri/ /admin.html
}
If you want /admin to not have a trailing slash, you will need to hard code that location.
location = /admin {
try_files /admin.html
}

Resources