In this blog, I'll share my journey of transforming my Raspberry Pi into a React app server. We'll start by installing nginx followed by configuring nginx for optimal React app hosting.
Prerequisites
nginx installed in your Raspberry pi. The installation guide can be found here.
LTS version of Nodejs installed in your Raspberry pi.
Connecting to the Raspberry Pi
A SSH connection can be established between your local machine and a Raspberry Pi provided
They are on the same network
Raspberry Pi is configured to accept SSH connections
Follow this guide to enable SSH and connect the Raspberry Pi to a network.
After the Pi has connected to the wifi, you can use tools like nmap or arp-scan to figure out the IP address of the Raspberry Pi.
Once we have the IP address of the Raspberry Pi, we can connect to it via SSH.
Configuring nginx
Understanding nginx.conf
The way nginx and its modules work is determined in the configuration file. By default, the configuration file is named nginx.conf
and placed in the directory /usr/local/nginx/conf
, /etc/nginx
, or /usr/local/etc/nginx
.
user <USER>;
error_log /var/log/nginx/error.log notice;
pid /var/log/nginx/pid.log;
events {
worker_connections 1024;
}
http {
listen 80;
server {
location / {
root <LOCATION>;
}
}
}
The above block represents a sample configuration,
user
- Definesuser
credentials used by worker processeserror_log
- Configures logging. The first parameter defines afile
that will store the log. The second parameter determines thelevel
of logging, and can be one of the following:debug
,info
,notice
,warn
,error
,crit
,alert
, oremerg
.pid
- Defines afile
that will store the process ID of the main process.events
- Provides context in which the directives that affect connection processing are specifiedworker_connections
- Sets the maximum number of simultaneous connections that can be opened by a worker process
http
- Provides context in which the HTTP server directives are specifiedlisten
- Sets theaddress
andport
for IP, or thepath
for a UNIX-domain socket on which the server will accept requests. Bothaddress
andport
, or onlyaddress
or onlyport
can be specified.server
- Sets configuration for a virtual serverlocation
- Sets configuration depending on a request URIroot
- Sets the root directory for requests
nginx.conf
for a simple HTTP server
user <USER>;
error_log /var/log/nginx/error.log notice;
pid /var/log/nginx/pid.log;
events {
worker_connections 1024;
}
http {
listen 80;
server {
location / {
root /data/www;
}
}
}
nginx
by following this guide.Verify the configuration
Create a sample index.html
file in /data/www/
. This will be our sample HTML file which will be served by nginx
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
</head>
<body>
<p>Hello World</p>
</body>
</html>
Following this, start nginx by using
sudo systemctl start nginx
127.0.0.1/
from the browser in it to see the HTML fileWe can view the HTML file from the local machine by navigating to the IP address of the Raspberry Pi from the browser.
Setting up the React App
We will be using a basic weather application. The react app uses an external API to fetch weather data of a place. It uses this API to fetch weather data. The API uses a token to authorise its users, hence users have to register to the free tier.
Instead of using the API directly from the client, we will have nginx act as a proxy between the client and the API. In order to achieve this, the app will make a GET request to /weather/place/{location}
.
fetch(`/weather/place/${location}`).then(res => res.json()).then(data => {
// Do something with the data
})
If the user wants to know the weather in Delhi
, the resulting URL of the GET request will be http://<RASPBERRY PI IP ADDRESS>/weather/place/Delhi
.
Setting up nginx.conf
for the Weather App
Weather API can be accessed using the following endpoint:
http://api.weatherapi.com/v1/current.json?key=<YOUR KEY>&q=<LOCATION>&aqi=no
This will return a JSON response containing the weather data like temperature, humidity, wind speed, etc. We will use this in nginx.conf
as follows:
user srinivas;
error_log /var/log/nginx/error.log notice;
pid /var/log/nginx/pid.log;
events {
worker_connections 1024;
}
http {
listen 80;
server {
location ~* ^/weather/place/(.*)$ {
resolver 8.8.8.8;
proxy_pass http://api.weatherapi.com/v1/current.json?key=<YOUR KEY>&q=$1&aqi=no;
}
location / {
root /data/www;
}
}
}
proxy_pass
- Sets the protocol and address of a server and an optional URI to which a location should be mapped. As a protocol, โhttp
โ or โhttps
โ can be specified. The address can be specified as a domain name or IP address, and an optional port.resolver
- Configures name servers used to resolve names of upstream servers into addresses.8.8.8.8
is Google's DNS.
location ~* ^/weather/place/(.*)$ {
resolver 8.8.8.8;
proxy_pass http://api.weatherapi.com/v1/current.json?key=<YOUR KEY>&q=$1&aqi=no;
}
The above block contains ~*
which is a modifier that allows for case insensitive matching with regular expressions. ^/weather/place/(.*)$
is a regular expression that matches /weather/place/Delhi
or any other location.
(.*)
creates a capture group (you can read more about capturing groups here). Essentially, it groups a sub-pattern allowing us to use it as a single entity. These groups are numbered starting from 1 and can be accessed via the $
notation.
Therefore, in the following line, $1
references the location that the user has provided.
proxy_pass http://api.weatherapi.com/v1/current.json?key=<YOUR KEY>&q=$1&aqi=no;
Serving Weather App from the Raspberry Pi
In order to serve the react app from the Raspberry Pi, we need to
Get the application in the Pi
Build the application
Move the build files into
/data/www
Load
nginx.conf
with the new configurationReload nginx
Getting the application into the Pi
Create a public GitHub repository for the react application. Push the code into it and clone it from the Raspberry Pi.
Building the application
Move into the code directory and run the following command:
npm run build
Moving the build files
Move the files into /data/www
. This can be done using the mv
command.
mv <SOURCE> /data/www/
Here's how my /data/www
directory looks:
Loading the nginx.conf
Modify the nginx.conf
file as follows:
user srinivas;
error_log /var/log/nginx/error.log notice;
pid /var/log/nginx/pid.log;
events {
worker_connections 1024;
}
http {
listen 80;
server {
location ~* ^/weather/place/(.*)$ {
resolver 8.8.8.8;
proxy_pass http://api.weatherapi.com/v1/current.json?key=<YOUR KEY>&q=$1&aqi=no;
}
location / {
root /data/www;
}
}
}
Reload nginx
Run the following command:
nginx -s reload
Viewing the Weather app
From your local machine, navigate to the IP address of your Raspberry Pi and you should be able to view the weather app.
The full code along with the nginx.conf
file is available here.