Serving React frontend and Flask backend using Nginx as a reverse proxy - reactjs

I've been trying to set up a React frontend and a Flask backend using Nginx as a reverse proxy to differentiate the two. I have the flask backend running a Gunicorn server on localhost:5000, but I can't seem to get the Nginx location block to register it. My config file looks like this:
server {
listen 80;
root /var/www/[react-app-domain-name]/html;
index index.html index.htm;
access_log /var/log/nginx/reverse-access.log;
error_log /var/log/nginx/reverse-error.log;
location / {
try_files $uri $uri/ = 404;
}
location /api {
include proxy_params;
proxy_pass http://localhost:5000;
}
}
My understanding is that this should route all traffic through my react app at root, except for requests that have "/api", which should then be routed through my backend Flask api. However, when I try to access a /api route, all I get back is a 404 response. This also happens if I true to access it through curl on the command line.
Here's the 404 error log that I have:
2020/09/09 21:03:05 [crit] 36926#36926: *114 connect() to unix:/home/[name]/backend/backend.sock failed (2: No such file or directory) while connecting to upstream, client: 127.0.0.1, server: , request: "GET /api/ HTTP/1.0", upstream: "http://unix:/home/[name]/backend/backend.sock:/api/", host: "[hostname]"
Any help would be very much appreciated. I'm tearing my hair out here. Thanks.

Related

Getting 400 error while trying to fetch data from nginx docker, frontend is in reactjs and backend is in Spring boot also using Spring Cloud gateway

I have setup my whole backend in docker which is working fine while I am running frontend from npm (not in docker).
Now, I am trying to use it using nginx docker but I am getting 400 error at every GET request to the backend.
Here is nginx.conf file
#user nobody;
worker_processes 1;
# error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name <ip>;
#charset koi8-r;
access_log access.log;
error_log error.log;
location /eprimo {
root "/usr/share/nginx/html";
index index.html index.htm;
}
location / {
proxy_pass http://<ip>;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
client_max_body_size 100M;
}}
while in access logs I am getting
upstream prematurely closed connection while reading response header from upstream, client: , server: , request: "GET /user_service/api/getuserroles HTTP/1.1", upstream: "http:///user_service/api/getuserroles", host: "localhost:3000", referrer: "http://localhost:3000/eprimo/"
I have tried multiple headers but still suggest me some of the most important headers which must be in this configuration file.
Also I am using only nginx.conf file present in '/etc/nginx/nginx.conf' not using '/etc/nginx/conf.d/default.conf' here but I have tried with that also response was same.
Let me know if any more information is required.
Please suggest me any solution every relevant solution is welcome.
Thanks

Dockerized NGINX returns 404 instead of static React files

I use Docker and NGINX to serve SPA built with React. Everything was fine until I added some caching inspired by this gist. Currently, NGINX returns 404 for all files in static folder.
This is how NGINX config looks like:
server {
listen 80;
location / {
root /usr/share/nginx/html/;
include /etc/nginx/mime.types;
try_files $uri $uri/ /index.html;
}
# These two location directives cause the issue, if remove them it will be running fine
location ~* \.(?:jpg|jpeg|gif|png|ico|svg)$ {
expires 7d;
add_header Cache-Control "public";
}
location ~* \.(?:css|js)$ {
add_header Cache-Control "no-cache, public, must-revalidate, proxy-revalidate";
}
}
This is what error messages look like, there is etc folder prepended to the path which is invalid:
2022/09/28 09:58:46 [error] 11#11: *4 open() "/etc/nginx/html/static/css/main.45f86988.css" failed (2: No such file or directory), client: 172.17.0.1, server: , request: "GET /static/css/main.45f86988.css HTTP/1.1", host: "localhost:3244", referrer: "http://localhost:3244/"
Files are definitely stored within the container, but again without that etc folder:
/usr/share/nginx/html/static # find
.
./css
./css/main.45f86988.css
./css/main.45f86988.css.map
./js
./js/496.a53b338e.chunk.js
./js/NotFoundComponent.af4d0ff3.chunk.js
./js/main.adbec619.js
./js/main.adbec619.js.map
./js/285.f49f8f0e.chunk.js
./js/MapComponent.3d89394e.chunk.js
./js/MapComponent.3d89394e.chunk.js.map
./js/NotFoundComponent.af4d0ff3.chunk.js.map
./js/DemoContainer.7bc357cb.chunk.js.map
./js/496.a53b338e.chunk.js.map
./js/main.adbec619.js.LICENSE.txt
./js/285.f49f8f0e.chunk.js.map
./js/DemoContainer.7bc357cb.chunk.js
/usr/share/nginx/html/static #
P.S. I haven't used NGINX before and I'm sorry if the answer is obvious
It looks like your files are in /usr/share/nginx/html/static folder, but nginx is trying to read them from /etc/nginx/html/. I would recommend moving the root /usr/share/nginx/html/ line to the server block.
Something like that:
server {
listen 80;
root /usr/share/nginx/html/;
...
}

In frontend nginx check backend health for custom error page

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

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.
}
}

Can't open websocket from React app through NGINX

I have a dockerized React app frontend that is served through NGINX:
FROM nginx:alpine
COPY default.conf /etc/nginx/conf.d
COPY ./build /usr/share/nginx/html/
.build is my React web app. default.conf contains this:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /api/ {
proxy_pass http://api:8080;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
My webapp makes requests against another linked container named api, so all /api calls are proxy passed to the api container.
So far, so good.
Problem comes when I try to open a websocket. Websocket server is listening also in api container, but in port 8081.
In my code, I have this:
const socket = openSocket('http://api:8081'); //openSocket is from socket.io library
But, in my Chrome console, I'm getting ERR_NAME_NOT_RESOVED.
How can I configure NGINX in order to proxy pass this request to api container?

Resources