serving multiple react apps with nodejs and nginx - reactjs

I have a Loopback App, which provides the API, and serves the static files. And 2 React apps which use the same Loopback App.
I serve the static files (from React Build folders) using serve-static and vhost.
var serveSubdomainAbc = serveStatic('abc/build', {
index: ['index.html']
});
var serveSubdomainXyz = serveStatic('./../../xyz-abc/build', {
index: ['index.html']
});
app.use(vhost('abc.example.com', serveSubdomainAbc));
app.use(vhost('xyz-abc.example.com', serveSubdomainXyz));
I also setup an nginx server with very basic settings.
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://127.0.0.1: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;
}
}
When I directly visit the root of the apps, everything works fine, like
abc.example.com
xyz-abc.example.com
index.html is served, and then the react app starts fine. When I use a router link like,
xyz-abc.example.com/ssoRedirect, then it cannot find the ssoRedirect and it falls back to abc.example.com's index.html and serves that file, so ssoRedirect does not work. How can I make it to fallback to the correct index.html when it cannot find the required static file.

Related

React app doesnt launch from url location as set by nginx reverse proxy but does when port explicitly set

I'm trying to run a single react app on a separate port and using proxy pass from nginx to location '/app'
"http://localhost/app" -> React Application
The application is running under PM2 using its generated build with the command: 'pm2 serve build 3002'.
My thought was i do all this tested locally and then will port it to my own domain.
I've swapped 'localhost' for '127.0.0.1' just in case that had anything to do with it.
From online tutorials i've ended up with the following in my nginx "../sites-available/my_domain" file
server {
listen 80;
listen [::]:80;
server_name localhost;
location / {
root /var/www/my_domain/html;
index index.html index.htm index.nginx-debian.html;
try_files $uri $uri/ =404;
}
location /app {
proxy_pass http://localhost:3002;
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;
}
}
If i type "http://localhost:3002" into the url it works fine however "http://localhost/app" does not work and shows 404 error.
Side-note: "http://localhost" works fine and directs to the index.html stored at root.

Deploying react on ubuntu droplet

I've got a locally perfectly working react app on port 3000.
Finally bought a droplet, installed and configured nginx + ssl.
Everything 'normal' is working just fine.
When i'm deploying my react app, npm server starts, looks normal but...
mydomain.net, mydomain.net:3000 etc. is just not working (i see only my html file, no react rendering).
What i'm missing?
Maybe to configure NGINX as a reverse proxy?
https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/
eg adding in NGINX configuration file:
location / {
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;
}

NGINX proxy pass to React App not working

I want to run the following projects using NGINX under a single subdomain: http://localhost:3000 (Loopback API) and http://localhost:3006 (React Application)
Both applications are running under PM2. React App is running in production (using its generated build) with the command: 'pm2 serve build 3006'.
/etc/nginx/sites-available/default
server {
listen 80;
server_name subdomain.domain.com;
location / {
proxy_pass http://localhost:3006;
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;
try_files $uri /index.html;
}
location /api {
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;
}
Loopback project under location /api es working perfectly. The issue is with my React project under my / route. When I enter to subdomain.domain.com I just get a blank page. In the developer console I'm getting the following errors:
Using http://localhost:3006 to access my React App works perfectly fine with no console issues so I'm totally sure it is something related with nginx.
I have been investigating a lot about the incorrect MIME type being loaded, but my /etc/nginx/nginx.conf is already running with the following configuration:
http {
include /etc/nginx/mime.types;
}
I would really appreciate your help, thanks.
Are you using Create React App? By default, its build script assumes the app is going to be served in the root directory. To correctly serve React under a subdirectory, you need to specify homepage in your package.json file.
"homepage" : "http://example.com/your-subdirectory"
Additionally, you'll want to modify server/app.js to reflect this change.
app.use('/your-subdirectory/api', require('./api'));
Lastly, and most importantly, you'll want to set a basename for React Router as well.
const Routes = () => {
return (
<Router basename={'/your-subdirectory'}>
<div>
<Route exact path={`/`}component={App} />
</div>
</Router>
)
};
There is no need to use pm2 since they are static files and nginx is able to serve it by itself.
You just have to let nginx know where the files are.
server {
listen 80;
root /home/user/app/buld <--- LOCATION_OF_YOUR_BUILD
index index.html
server_name subdomain.domain.com;
location / {
try_files $uri /index.html
}
location /api {
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;
}

Deploy express server that serves react behind nginx

I have an express server on an ec2 instance that has an api (/api) and a client (everything that's not /api handled in react.)
Goging to http://ip.address:3000 works fine. It shows the app and everything works.
However going to https://ip.address (forwarded by nginx) doesn't work fine. It loads my index.html correctly but 404s on all the /static/bundle.js and /static/bundle.css files.
nginx
# redirect to node for the dynamic stuff
location / {
proxy_pass https://localhost:8003/index.html;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_hide_header X-Powered-By;
}
express
let router: express.Router = express.Router();
router.use(express.static(path.join(__dirname, "/build")));
const api: ApiRouter.Api = new ApiRouter.Api();
router.use("/api", api.router.bind(api.router));
//Catch all for react - client side routing
router.get("*", function(req, res) {
res.sendFile(path.resolve(__dirname, "/build/index.html"));
});
If you tell Nginx to
proxy_pass https://localhost:8003/index.html;
Then every request which matches that location block will have the matching part of its URL path replaced with whatever path you have added to your proxy_pass URL.
Your location block is simply / So if I request www.yoursite.com/static/bundle.js then Nginx will match the first /, replace it with your path and add the rest. So it will try and serve www.yoursite.com/index.htmlstatic/bundle.js
You should proxy /api through Nginx too, and if the static files are coming from an upstream proxy you should enable proxy caching within Nginx too

Angular route without hash

I have an app where the admin side is built in angular, but the front consumer facing side is not.. and lives on a different server.
I'd like if visitors coming to:
domain.com/#/admin => angular app
But if they got to:
domain.com
This goes to the other server
Is this possible?
Thanks.
For a little more clarity, I think what I need is this:
I have a rails app as an api that angular consumes. Rails lives on server A and Angular lives on server B.
Both servers use nginx as the web server.
Also, the rails app serves up its own content, so I want any path other than admin to go to rails.
What I want is if users go to:
mydomain.com --> they hit the rails app and content on server A
when they go to:
mydomain.com/admin or mydomain.com/#/admin --> they hit the angular app on server B
I think I almost figured it out with the following nginx configs on the rails server, server A:
upstream serverA {
server rails;
server unix:///var/www/rails/shared/tmp/sockets/puma.sock;
}
upstream serverB {
server angular;
}
server {
listen 80;
server_name serverA;
root /var/www/rails/current/public;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://serverA;
}
location ~* ^/assets/ {
expires 1y;
add_header Cache-Control public;
add_header Last-Modified "";
add_header ETag "";
break;
}
location /admin/ {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://serverB/#/;
}
}
While this gets me close, my angular scripts and styles that are references by my angular index.html file are not being found.

Resources