Using GitHub Actions to deploy a web page to Raspberry Pi
Henrique Ramos
Posted on May 3, 2022
A couple of months ago I bought a Raspberry Pi 4. Since then, I've been getting my hands dirty w/ SSH, SCP, Systemd, DDNS and some other things I've never done before. This machine now hosts my Veloren server (Join me at vlrn.duckdns.org) and a landing page which, after manually building and SCP'ing a lot, is now deployed through GitHub Actions. And this is today's topic: How to deploy a webpage to a RPi using GH Actions?
Before starting
If you have a dynamic IP address, you'll have to setup a Dynamic DNS, otherwise, you'd have to change the target IP address every time yours change (It can happen monthly, weekly or even daily). This won't be covered here, since the process differs based on your Router model. However, if you want a good and free Dynamic DNS service, consider using (and donating!) to duckdns.org which is the one I currently use.
Preparing the RPi
In this case, preparing is pretty straightforward, you just need to install NGINX using:
apt install nginx
And then start it:
systemctl enable nginx
systemctl start nginx
Port forwarding
Port forward RPi's port 80 to external port 80. Now, when accessing the IP from a browser, this screen will appear:
Also, port-forward the port 22 of the RPi to anything other than 22. This is the default SSH port, so it's better not to expose it for security reasons.
Creating the Action
This is a pretty simple step, because of the great appleboy/scp-action. The action will have only one job with two steps: Building and pushing to Raspberry Pi.
Building
There's no secret here, this is the build step:
name:deployon:push:branches:-mainjobs:deploy:name:Deployruns-on:ubuntu-lateststeps:-uses:actions/checkout@v3-uses:actions/setup-node@v3with:node-version:"14"-name:"Install&build"run:|npm inpm run buildmv public/index.html public/index.nginx-debian.html
The only thing to be aware here is the last line, where index.html gets renamed to index.nginx-debian.html. This is done because on Debian, NGINX uses /var/www/html/index.nginx-debian.html. Be aware that other distros can use a different directory and index naming.
Pushing
To push the recently-built artifact to the Raspberry Pi, we'll use appleboy/scp-action. To correctly set it up, add the following secrets to your GitHub repo:
SSH_HOST: IP/URL of the RPi;
SSH_PORT: The SSH port used by the RPi, which was forwaded in the Port Forwarding section;
SSH_USERNAME: The RPi username to SCP to. Since the files will be copied to /var/www/html, this user should have root privileges, preferrably without asking for password;
SSH_KEY: An SSH Private Key, generate it using either ssh-keygen or an online generator.
Once you have everything created, add the SSH Public key to ~/.ssh/authorized_keys. Now it's time to create the "Push" step:
There shouldn't be anything new other than strip_components: 1. This
setting removes the specified number of leading path elements, without it, we'd push the content to /var/www/html/public instead of /var/www/html.
The end
Now you should have a fully functional GitHub action that automatically builds and pushes to a Raspberry Pi. No more SCP'ing for changing a single line or running npm run build inside the RPi. You can see the repo for my website here:
Psst — looking for a more complete solution? Check out SvelteKit, the official framework for building web applications of all sizes, with a beautiful development experience and flexible filesystem-based routing.