Raspberry Pi is a bit underpowered to compete with a full server, no doubt about it, but a lot of our hobby apps which don't ever see the light of the internet, or our test projects which are not ready for the cloud world are the best match with this tiny marvel. You learn a lot about how servers work and get a project hosted on internet, for the cheapest price possible.
What I run on my Raspberry Pi
I currently have an OpenFaas instance running on my Raspberry Pi serving two applications, first a Github Webhook endpoint and second a Password generator based on EFF list. OpenFaas runs over Docker swarm which I manage using a Portainer ui also running as Docker container. I monitor resource usage with Glances server. I plan on adding a Jupyter Hub instance and putting all of this behind an NGINX proxy server possibly with auth.
Yes, my setup is a bit too overkill for a small machine like raspberry pi, but it has taught me a lot of things about a lot of different software and possibilities of this tiny monster.
You can access the password generator on this link.
Prerequisites
- 5$ Raspberry Pi
- Domain Name (Optional but highly recommended for https)
Diagram Time
Reverse proxy - because, Security
Setting up a reverse proxy server might seem like a bit of a pain but it provides a secure gateway as exposing your home network and your applications on the internet is always a risk. You can also use it to setup SSL if you have a domain. I prefer Nginx simply because it has a lot of guides and is simple to setup (Apache's config scares me). Simple HTTP reverse proxy:
server {
listen 443;
location / {
proxy_pass http://locahost:[:PORT]/;
}
}
Deploying:
sudo nano /etc/nginx/sites-enabled/default
# Copy the config then Ctrl+x to save
sudo nginx -s reload
Also see: SSL with nginx
Correctly starting your applications
The second biggest mistake you can make after ignoring security, is assuming that your raspberry pi will be running most of the time, and if it reboots, you'll just start your services again. Don't make this mistake, setting up a self starting service is trivial and its the best that you can do for your peace of mind. Refer this official Raspbian guide on setting up a self starting service.
app.service
[Unit]
Description=My Applicaiton
After=network.target
[Service]
ExecStart=/usr/bin/python3 -u main.py
WorkingDirectory=/home/pi/applicaiton
Restart=always
User=pi
[Install]
WantedBy=multi-user.target
Copy and enable service
sudo cp app.service /etc/systemd/system/app.service
sudo systemctl start app.service
sudo systemctl enable app.service
ARM has come a long way
Another concern which people have before going and hosting their service is that it'll be a pain to build for a different architecture, or they'll have to submit to satan to get their application running. It was the case few years back, but not anymore! Building your application for different architecture is as easy as providing a build time flag for compiled languages, or installing the interpreted languages runtime. Interpreted languages like python and javascript can be easily installed using existing package manager.
Statically compiled languages can be cross compiled for ARM on your current machine. For example:
- Golang:
env GOOS=linux GOARCH=arm GOARM=5 go build
- .NET Core:
dotnet publish -r linux-arm
Top comments (3)
How do you get the outbound IP address of the proxy server through the internet router? I've always had trouble with this on my Comcast ISP?
All routers have a config which redirects incoming traffic on a port (which is facing the internet) to a specific local ip and port.
First you should assign your raspberry pi a static local ip address from your router. This ip is something like "192.168.x.y" x and y can be different.
Second, you need to tell you route to redirect incoming traffic on a port to that ip and the exposed raspberry pi port.
If you have your router manual it should be there, or you can lurk around your router configuration to find out.
Rad this is exactly what I was looking for! Now to pester my roommate for the router login :P