How To Host a Public Website on Your Home Raspberry Pi

How To Host a Public Website on Your Home Raspberry Pi
(Image credit: Tom's Hardware)

From time to time, I like to let the internet control things in my home. Sometimes it’s letting a live stream turn on and off a light and  others it's driving a RC car around my living room. When building these projects, I normally use a Raspberry Pi to listen for web traffic and perform an event when someone visits the site.

I could give people my IP address and port forward my router to my Raspberry Pi, but I’d rather keep my IP private and my network as secure as possible. We can get the best of both worlds with a SSH tunnel, nginx, and a virtual machine in the cloud. All this creates a reverse proxy, where visitors hit a public IP address that’s not your home network’s and get directed to the Pi that’s on your LAN.

If you’re looking to build something interactive with your Pi while still keeping things as secure as possible, here’s how to do it.

What You’ll Need For This Project 

  • Raspberry Pi 4 or Raspberry Pi 3 with power adapter
  • 8 GB (or larger) microSD card with Raspberry Pi OS. See our list of best microSD cards for Raspberry Pi
  • A Google Cloud Platform account and the gcloud command line tool or another cloud provider you’re familiar with. Note that the incoming traffic will cost some money which, in our case, is $5 a month.

How To Host a Public Website on Your Home Raspberry Pi

Before you get started, make sure that you have your Raspberry Pi OS set up. If you haven’t done this before, see our article on how to set up a Raspberry Pi for the first time or how to do a headless Raspberry Pi install (without the keyboard and screen).

1. Install git, which will allow us to clone this project’s code.

sudo apt-get update && sudo apt-get install -y git

2. Clone the repository with example code. This code takes care of communication with the sensor, and sets up a simple server for monitoring on your home network. 

cd ~/
git clone https://github.com/rydercalmdown/pi_home_reverse_proxy.git

3. Run the installation command after descending into the repository. This will install all necessary SSH components as well as nginx, a simple server we’ll use as an example.

cd pi_home_reverse_proxy
make install-pi

4. Create a SSH public/private keypair. The private key will remain on the Raspberry Pi, and will be used in conjunction with the public key to connect to our cloud virtual machine. 

ssh-keygen
# press enter to accept all default settings

5. Copy the SSH public key for later. We’ll need this when setting up our virtual machine in the cloud.

/home/pi/.ssh/id_rsa.pub
# Copy the results

6. Visit your Google Cloud Console and navigate to the VM Instances page.

7. Click “Create Instance” to create a new virtual machine.

(Image credit: Tom's Hardware)

8. Choose a memorable name for your instance. I’m calling mine “home-reverse-proxy”.

9. Choose your desired region and zone. This doesn’t matter as much, but it’s good to pick something close to you for low latency. 

(Image credit: Tom's Hardware)

10. Under machine configuration, choose “N1” for the series, and f1-micro for the machine type. This will give us the lowest monthly cost, around $5 USD per month. 

(Image credit: Tom's Hardware)

11. Scroll down to the “Boot Disk'' section and click the change button. Set the Operating system to Ubuntu, and the version to “Ubuntu 20.04 LTS”, leave everything else the same and cick Select.

(Image credit: Tom's Hardware)

12.  Scroll down to “Firewall” and check both “Allow HTTP traffic” and “Allow HTTPS traffic”.

(Image credit: Tom's Hardware)

13. Scroll down to the bottom of the instance and click “Create”.

14. Once the machine is running, click the dropdown next to SSH to get the SSH command. I recommend using the “View gcloud command”. Paste that command into your terminal to SSH on to your cloud virtual machine

(Image credit: Tom's Hardware)

15. Once connected to your virtual machine, install nginx with the following commands.

sudo apt-get update
sudo apt-get install -y nginx

16. Check to see if nginx is running by running the following command. You can also visit the External IP in your browser listed next to your virtual machine in the Google Cloud console. When visiting, you should see a nginx welcome page.

sudo service nginx status
# Ctrl + C then enter to exit
# It should show “active (running)” in green if all is well

(Image credit: Tom's Hardware)

17. Update the default configuration with a custom reverse-proxy config. This tells nginx to forward all traffic it receives to a port on your machine. 

cd /etc/nginx/sites-enabled
sudo rm default
sudo touch default
sudo nano default
# copy in the code below

This code rate limits the number of requests to 5 per second to not overwhelm the pi during interactive projects. If you’d like to accept more, simply increase the number, or remove any lines that start with limit_req from the file for no limits.

limit_req_zone $binary_remote_addr zone=basic:10m rate=5r/s;


server {
  listen 80;

  location / {
    limit_req zone=basic;
    proxy_pass  http://0.0.0.0:5000;
  }

}

18. Restart the nginx service and visit the external IP of the virtual machine again. You should be presented with a “502 Bad Gateway” page if all goes correctly. 

sudo service nginx restart

(Image credit: Tom's Hardware)

19. Using the following command, create a user for the pi to SSH into on the virtual machine.

sudo useradd -m -p raspberry -s /bin/bash piconnect

20. Create the SSH directory and authorized key files, and copy in the public key you copied from your Raspberry Pi

sudo mkdir /home/piconnect/.ssh/
sudo touch /home/piconnect/.ssh/authorized_keys
sudo nano /home/piconnect/.ssh/authorized_keys
# copy in the public key you copied from your raspberry pi

21. Back on the Raspberry Pi, edit the establish_remote_connection.sh file to include your remote server’s IP address. 

cd ~/pi_home_reverse_proxy
sudo nano scripts/establish_remote_connection.sh
# change REMOTE_HOST=your_remote_ip_address to the external IP you got from the Google Cloud Platform console

22. Run the make connect command to establish the SSH connection between your Raspberry Pi and your virtual server.

make connect

23. Visit your virtual machine’s IP address to see the content running on the Raspberry Pi served remotely and not on your home IP address. 

(Image credit: Tom's Hardware)

And there you have it! You are serving content from your Raspberry Pi from a Google Cloud IP address, via an SSH tunnel. I only use this setup from time to time, but for a more permanent setup, I'd recommend connecting a domain and securing it with LetsEncrypt on the virtual machine side.

Ryder Damen
Freelance Writer

Ryder Damer is a Freelance Writer for Tom's Hardware US covering Raspberry Pi projects and tutorials.

  • hqmhqm
    Another easy way to do this is to use the ngrok service. They provide an ssh tunnel to an IP address of your choice, with a public facing TCP port you can use for HTTP

    see ngrok.io for instructions
    Reply
  • JOSHSKORN
    Neat, but I just saw Hostinger for only $2.59/month, and you don't even have to pay for electricity. I get it though, you could have total control.
    Reply
  • DotNetMaster777
    This is good tutorial what we can do with Raspberry !!!
    Reply
  • blando
    How would you use this to host wordpress?
    Reply
  • Eon046
    I've done it, it works, thank you very much.

    But I have a problem though;

    I'm starting gnix with "make connect", using PuTTY from another computer (as I have no peripheral plugged into my Pi).

    Should I close Putty or turn my PC off, it will also terminate the Gnix process, and the reverse-proxy stops.

    I have been told to use
    make connect &as it was supposedly putting the command "in the background", but it doesn't work still. Reverse proxy will stop if I close Putty.

    How could I work around this?
    Reply