How to Make a Raspberry Pi Web Server!
by Khajan in Circuits > Raspberry Pi
2278 Views, 17 Favorites, 0 Comments
How to Make a Raspberry Pi Web Server!
When you think about the word server, you probably think about big and fancy computers sitting in big companies, needing a lot of maintenance with really complicated systems. Well, servers can actually be anything from a giant enterprise computer to an old computer laying around in your closet. The paraphrased meaning of server is "a computer that provides functionality to clients", meaning that it provides some kind of a service for another user, whether it be on your network or somebody in another country. Just imagine the fact that you can make a website and make it display whatever you want, basically giving you power at your fingertips (with some bragging rights). And that is exactly what I am going to do with a Raspberry Pi.
The goal of this project is to get some information from a sensor, then display it to a website over the internet. Also, remember that the Raspberry Pi isn't as powerful as big servers which may mean that it probably won't be able to handle as many requests, but remember that this is running on Linux, so you can do the about the same thing on any other machine with a Linux OS, with probably better hardware. But just the fact that this can be one while some people and companies use ones that cost hundreds and sometimes thousands of dollars is just fascinating!
Supplies
To start out, you will obviously need a Raspberry Pi with a power supply and a MicroSD card, and you should have a case and fan to cool it. I used Raspberry Pi OS Lite, which is an operating system without a user interface, just a terminal. I chose it because it is designed for the Pi and it is light without too many packages preinstalled on it. If you would like though, you could use the desktop version of it if you feel want an interface to work with. Also, you should probably be a bit comfortable using the Linux command prompt, because that is mostly what we are going to be using. You also have to have another computer to SSH into the command prompt over your network.
Baking the SD Card
If you are going to use Raspberry Pi OS Lite, start out by installing the Raspberry Pi Imager on the Raspberry Pi website. Once you've done that, open the application and insert your MicroSD card into your computer. For the OS option, click Raspberry Pi OS(Other) and then click the Lite version. For storage, be sure to choose the proper card. Just know that everything on it will be erased, so be sure to triple check it. After that, press Ctrl-Shift-X. This will bring up a "secret menu" to enable some "secret" settings. What we'll want to do is enable SSH by checking it and choose a password of your choice. As always, choose a secure password. Then scroll and click "enable Wi-Fi", enter the Wi-Fi name in the SSID blank and then your Wi-Fi password. Now click on save, make sure everything is right, and write to the card.
Once that's done, log into your router and check for devices connected to it. If you went for the default hostname, it should be called "raspberrypi" and it should have an IP address next to it. What you'll now want to do is hop onto another computer, and enter this command into the terminal:
ssh pi@[IP address of the Pi in your router]
Now, you're in the terminal remotely and ready to start!
Setting Up the Firewall
Now for getting everything set up. Before installing anything, you should update everything to keep things up to date. To do that, run this command:
sudo apt update && sudo apt upgrade -y
Now we're going to install a firewall. This will block any unwanted requests that can let people gain access to your Pi, but we'll also have to enable some requests to actually use it. We are going to use UFW (Universal Firewall) to do this. To do this, enter these commands:
sudo apt install ufw
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw allow 1880
Now to start it:
sudo ufw enable
Installing and Using Node-Red
Node-Red will be what is reading the sensor data, and we will be using its dashboard function to display it. To install it, use these commands:
sudo apt install build-essential git
bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
If it asks you for Pi specific nodes, type "y".
Now that Node-Red is installed, you would probably want it to automatically start on boot. To do that, run this command:
sudo systemctl enable nodered.service
You can access Node-Red by typing "[Pi IP Address]:1880" in your browser. Now you have to wire up a sensor. I chose to use an ultrasonic sensor, but you can choose any other one. I won't really go into that, so here are two websites that help with an ultrasonic sensor on the Pi:
Node-Red setup for the sensor (Ignore the "Iot flows part")
Acquire a Domain
If we are going to be able to access this website from anywhere in the world, we need to have a domain name. Those are the names you enter into a web browser to access the website. Without one, you'll need to type in the IP address over and over again, and who will remember that? So to get one for free, you'll need to sign up at noip.com. Once you've signed up, create a domain name with all the default settings. Don't change the IP address as it is your public IP which will be what we need.
Installing Nginx
So you know have a domain name, but you'll need to do something about it. To make use of it, we'll be using a reverse proxy using Nginx. What that means is that you'll be able to redirect your page to Node-Red when you enter the domain name. To install it, enter this command:
sudo apt install nginx
To check if it is working, enter the IP address of this Pi in a web browser. It should come up with a welcome page.
Now to make things happen. Run this command to create a file for the domain and open it in a text editor (Change the domain to your own one):
sudo nano /etc/nginx/sites-available/node-red.your_domain_name.com
Now enter this in the editor, making sure to change the server name example to the one you own. (Keep the text "server_name")
#proxy for node-red @ port :1880
server {
listen 80;
listen [::]:80;
server_name node-red.your_domain_name.com;
location = /robots.txt {
add_header Content-Type text/plain;
return 200 "User-agent: *\nDisallow: /\n";
}
location / {
proxy_pass http://127.0.0.1:1880;
#Defines the HTTP protocol version for proxying
#by default it it set to 1.0.
#For Websockets and keepalive connections you need to use the version 1.1
proxy_http_version 1.1;
#Sets conditions under which the response will not be taken from a cache.
proxy_cache_bypass $http_upgrade;
#These header fields are required if your application is using Websockets
proxy_set_header Upgrade $http_upgrade;
#These header fields are required if your application is using Websockets
proxy_set_header Connection "upgrade";
#The $host variable in the following order of precedence contains:
#hostname from the request line, or hostname from the Host request header field
#or the server name matching a request.
proxy_set_header Host $host;
#Forwards the real visitor remote IP address to the proxied server
proxy_set_header X-Real-IP $remote_addr;
#A list containing the IP addresses of every server the client has been proxied through
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#When used inside an HTTPS server block, each HTTP response from the proxied server is rewritten to HTTPS.
proxy_set_header X-Forwarded-Proto $scheme;
#Defines the original host requested by the client.
proxy_set_header X-Forwarded-Host $host;
#Defines the original port requested by the client.
proxy_set_header X-Forwarded-Port $server_port;
}
}
Save it by pressing Ctrl-X and type "y".
Now to enable the file to run, enter this command (Change the domain name to your own one):
$ sudo ln -s /etc/nginx/sites-available/node-red.your_domain_name.com /etc/nginx/sites-enabled/
To avoid a problem with adding new server names, you need to edit uncomment a line in the config file. To do this, enter this:
sudo nano /etc/nginx/nginx.conf
Find the line with that goes like this: server_names_hash_bucket_size 64; and uncomment it by removing the #. Now save it.
Make sure there are no errors by running this:
sudo nginx -t
Now restart it by running:
sudo systemctl restart nginx
If you ever need to remove the server file, enter this and reboot again:
sudo rm /etc/nginx/sites-enabled/node-red.your_domain_name.com
Port Forwarding
If you tried accessing the website, it probably didn't work. That's because you need to forward some ports. But wait, what is that? Well, to be able to access it from the internet, you need to be able to make it visible to others first. And that's what port forwarding is. The router creates a route between the public network and your own one.
Alright, so how do you do that? Well, you'll have to be able to log into your router to access the settings. You'll now have to find the setting for enabling port forwarding. Add an entry for the Raspberry Pi that opens port 80 to 443(That's what I used). You can find more info online on how to do this on your own router.
Test It Out
Now that you have set up the port forwarding, you are ready to test out your server! Just enter your domain name, and your Node-Red dashboard should hopefully appear. Also, credit goes to a Node-Red forum which I found the guide for. If you would like to go more in detail, check it out here. I cut out some parts to not make it so complicated, like stopping hackers from using automated attacks, making it HTTPS, and Node-Red credentials. This is my first time doing something like this, so if there is anything that I should add or improve on, please leave me some feedback. Anyways, enjoy your new server!