In this article I present how to host a web app on your Raspberry Pi (or other computers) with a couple of interesting features.
- ⛔ no static IP address, Dynamic DNS or port forwarding on your router needed
- 🚀 low latency access over the public Internet without server in the middle
- 🔁 possibility to easily share access to that web app only to specific people
The web app will consist of two elements:
- ✏️ front-end: using Bootstrap 4 and websocket client written in JS
- ✏️ back-end: Python app with a websocket server providing a JSON API to the front-end part
I show a bi-directional connection over a single websocket. The demo application will be very simple - controlling a LED connected to Raspberry Pi using a button in web UI and controlling an indicator in the web UI over the button connected to Raspberry Pi.
💭 You can treat this app as a boilerplate code for your own, more sophisticated apps requiring a low-latency control over a web user interface.
To access a Raspberry Pi over the Internet, we need to configure a VPN service, because our computers don't have static IP addresses. Our choice is Husarnet VPN Client, because it works peer-to-peer so the latency to our web user interface will be minimized in comparison to solutions based on central cloud/server software.
Husarnet Client creates a virtual network interface on the level of your operating system. So from your applications point of view it's like a network adapter with IPv6 (but works over physical IPv4 or IPv6 networks provided by Ethernet, Wi-Fi, LTE or 5G). Husarnet is trying to establish a direct, peer-to-peer connection between your devices (with a fail-over route over Husarnet Base Servers), so latency is minimized and you do not need to worry about configuring a VPN server.
Husarnet infrastructure is used to help your devices find each other over the Internet, even if they do not have static IP addresses, or are behing NAT's and firewalls.
Free Husarnet Account
Husarnet is free to use for up to 5 devices, without any transfer limits. We do not care about how much data your devices transfer if the traffic goes directly between them, not through our servers. We don't even know how much data you transfer.
after the installation process is finished, run:
At first you will need to obtain a Husarnet join code for the network you want your devices to be connected to. To find your join code, create an account and log into https://app.husarnet.com . Then create a new network, by clicking [Create network] button, and then click [Add element] button. Your join code will be available under
join code tab:
It looks like this:
Now when you have your join code available all you have to do is to execute:
mylaptop are easy to remember host names under which you will be able to access your devices.
- Install Apache 2:
- Create a folder for "myrpi" domain (the same as your device hostname)
- Change permissions:
- Copy a config file for "myrpi" domain
We placed our server under 8000 port, so we also need to modify
- Enable a custom config file:
a) disable default config file at first:
b) enable a new config file:
c) reload apache2
also run websockettest.py as a root becasue of access rights to GPIO
If during executing a python3 script you will face and error like this
RuntimeError: Not running on a RPi!
You will probably need to modify access rights to GPIO:
If this is no critical for your application, the most comfortable way however is running the script as
Now connect a LED to your RaspberryPi with a serial resistor. In our case it's GPIO16.
Also connect a button to the GPIO23.
On my GitHub profile there is repository with the source code: Python, HTML and JS files.
Let's focus on client and server websocket communication implementation.
- Server (Python)
a) Clone the projects repository
websocket_client.js to the Apache webserver folder:
c) Start a python3 script running a websocket server:
At this point everything should be up and running!
mylaptop device (that is in the same Husarnet VPN network as
myrpi device), open a web browser and open the following URLs:
You should see a simple website hosted by your Raspberry Pi where you can control a LED (connected to GPIO16) and if you click a button (connected to GPIO23) you should see reaction on the red/green dot:
I presented in this article:
- how to configure a Apache 2 on Raspberry Pi,
- how to establish a bi-directional websocket connection in the Python3 script running on RaspberryPi
- how to make that working not only in LAN but also over the Internet, even if you don't have static IP and don't want to configure port forwarding on your router or dynamic DNS service.
I hope you will find this article helpful.