I am running a Nginx web server in a device that has two different network interfaces. I want to serve a React App on port 80 that makes API calls to an API server on a different port of the same device. I have configured Nginx to listen on port 80 and it correctly serves the React app on both interfaces. However, making API calls is trickier.
If I had only one interface with a fixed IP, I would set that IP as the API server address in the React APP and everyhting would be fine. However, when having several interfaces, the React App does not which interface has been used to serve it. As a result, it does not know which is the IP of the API server.
This question is also valid for a device that has only one interface but whose IP changes dyncamically. Nginx serves the web page right regardless of the IP but the React App needs to know the IP address to make API calls to.
I understand that a common solution is to assign a domain to the API server but in my scenario the connection to the device takes place only on a local network.
Solutions I have considered:
Having a fixed IP on both interfaces and have nginx serve a different React App to each of the interfaces. The apps would be the same except for the API server address parameter. This is probably an overkill.
Requesting the user to enter the IP on the React App when running in the browser. This is not really user friendly.
What I would actually like would be a method for the React App to know the IP through it has been served or a method for Nginx to serve a web with a configuration depending on the device IP. Is there any solution like these?
As the React app is served in the local network and it does not use a domain, it is requested in the browser using the device IP as href. As a result, the app can get the IP address of the device using the javascript method window.location.href and use it as the API server address.
Related
Create-React-App provides a URL that I can connect through my LAN network like this:
Is there a way to expose the NextJS URL through the LAN network?
The server is accessible on the local network, as long as the network is configured properly (and doesn't have something like client isolation enabled). All you need to do is find out which IP address your network's router is allocating to you. On Windows, this can be done by checking the results of ipconfig. On Linux, you can use ip addr. Then, when you want to access the app from another device, just use the IP found above followed by the port set in next.js.
For example, I have a machine whose network IP address is 192.168.1.2. On that machine, I have a Next app running on port 56381.
ready - started server on 0.0.0.0:56381, url: http://localhost:56381
I can access it on my phone by going to 192.168.1.2:56381.
i made a react js website and everything is working fine but i can't figure out how to host it on my rasp pi4 and make it publicly visitable by other people. I also bought a domain. So my question is: How can i make my reactjs site public and running on my rasp. Thanks!
You have to configure a web server like Apache and build the React app with npm or yarn. Then copy the build files to the /var/www/html/ directory. You will also have to look into port forwarding your router to your local web server and open it to the public. Just be careful with security.
You need to configure a web server to host the site. Either Apache2 or Nginx (I have a personal preference to Nginx, but either works fine for this). Under Debian/Raspberry Pi OS, /var/www/html should be served on port 80 on all of the pi's IP addresses. Place the site files there and make sure you can access the site from the pi's IP address.
For making the site available outside of your network, you will either need to look at port forwarding, hosting a VPS with a public IP, or using a tunnel. Port forwarding is likely going to be the hardest option and may not always work, but doesn't require any external services outside of your DNS provider. Tunneling is probably the second easiest, and using a VPS is almost certainly the easiest.
For port forwarding, yu will need to verify that your ISP does not use CGNAT, otherwise this will not work. Assuming they don't, you will need to access your routers configuration and set up port 80 on TCP to forward to your pi's IP address. I would assign your pi a static IP address, either on the pi itself, or using DHCP reservations. Next, you need to see if your DNS provider offers Dynamic DNS. If not, you will need to manually update your DNS settings in the case your networks public IP changes (unless you purchased a static IP from your provider). In this setup, you point your domain at your networks public IP. Traffic goes directly between the client's browser and your pi.
Tunneling is a fair bit easier. I personally use Cloudflare for my DNS (I set my domain with my registrar to point to Cloudflare, then used their tunneling tool (Cloudflared) to tunnel traffic from their servers to my pi. There are other tunneling services, but I think Cloudflare's is the best out of all of the ones I used. In this setup, you point your domain at Cloudflare, which forwards the traffic to you via the tunnel. Traffic goes from the browser to Cloudflare to your pi.
Using a VPS is probably the easiest, and your knowledge of working with the pi applies to working with a VPS, assuming you run Debian linux or similar on your VPS. You would install the web server on your VPS, put the app on the VPS, and point your domain at your VPS's public IP. In this setup, traffic goes from the client browser to your VPS. This is the only non-free option (excluding the price of the domain itself), and keeps your local private network safer by not putting public services on it. You can also run a tunnel between your pi and your VPS if you want (see https://www.jeffgeerling.com/blog/2022/ssh-and-http-raspberry-pi-behind-cg-nat for an example), but I don't personally see the point unless you really want the app to be served from your pi.
The issue I have is as follows,
I have a reactjs frontend and a asp.net core backend, I am trying to get data from the backend, by fetching, when accessing my frontend from outside my local network. My frontend is hosted using IIS on port 80, and portforwarded this port using ngrok. I am able to access my frontend now from outside my local network, but I am not able to fetch data from the backend, mainly because I am not sure where to make the calls to specifically.
The backend is listening on port 5000 and the frontend is making fetch requests to this port along with the target ip adress. But it can't connect. I have tried making calls using my public ip, local ip or just 0.0.0.0. I need it to work on my own pc, local network and outside my local network.
This might be a stupid issue that is easily solved, but I don't really have a clue where to begin here, hopefully someone can help me a bit further trying to resolve this issue.
When you call an API from your SPA (react app), the request is triggered from the browser showing your app.
So, when you load your port-forwarded app from outside your network, your browser, which is outside your network, is trying to call your API which is inside.
You have 2 possible solutions:
1/ port-forward the port 5000 of your router to the internal IP address (and port) of your server (e.g 192.168.1.10). Then from your React app, make the requests to your public IP address with the port (e.g 81.xx.xx.xx:5000)
2/ or, as you're already using Ngrok, install Ngrok on your server to get a direct URL to its port (ngrok http 5000) and make your requests to that URL
I have a react app as well as an express api running on a computer with an ipv4 address of 192.168.1.5
on ports 3000 & 9000.
When browsing http://localhost:3000 on that computer, my app works and I can make requests to the api. However when I open the app from another local machine I get the following output:
And here is base url for making requests in my react app:
Changing the baseUrl to http://192.168.1.5:9000/api makes the app work in my other machine in the same network, but not on the host machine anymore.
So my question is, what do I need to configure to have the app running both on my local computer as well as on another on the same network ?
You would probably have this line in express server
app.listen(3000, () => console.log("Listening"));
Pass "0.0.0.0" as host address.
app.listen(3000, "0.0.0.0");
Make sure that, your Firewall allows the selected port in Inbound rules.
Also Take a look at ngrok. Basically, it exposes your server to the Internet !
Yes, the public internet.
Before starting ngrok service, Start the express server. Pass the server port to ngrok arguments.
npm install ngrok -g
ngrok http 3000
When developing my front-end having used create-react-app, I can connect to it on my local machine using http://localhost:3000/ or on my network using http://192.168.1.160:3000/. My back-end (NodeJS/Express) is also on my local machine on http://localhost:5000/.
On my front-end, I have the URL to my back-end stored in an env variable as http://localhost:5000/. The problem is when I connect to my front-end from my mobile(on my network using http://192.168.1.160:3000/), it does not recognize http://localhost:5000/. I'm guessing it is because I have to use http://192.168.1.160:5000/ to connect to the back-end on my network.
This seems to require changing the back-end URL in my env file every time I want to test it out on mobile. Is there a way I can connect to my front and back-end from both my local machine and my network without having to constantly change the URL?