DEV Community

Cover image for Using GitHub Actions to deploy a web page to Raspberry Pi
Henrique Ramos
Henrique Ramos

Posted on • Updated on

Using GitHub Actions to deploy a web page to Raspberry Pi

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
Enter fullscreen mode Exit fullscreen mode

And then start it:

systemctl enable nginx
systemctl start nginx
Enter fullscreen mode Exit fullscreen mode

Port forwarding

Port forward RPi's port 80 to external port 80. Now, when accessing the IP from a browser, this screen will appear:

Welcome to nginx! If you see this page, the nginx web server is successfully installed and working. Further configuration is required. For online documentation and support please refer to nginx.org. Commercial support is available at nginx.com. Thank you for using nginx.

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: deploy
on:
  push:
    branches:
      - main
jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: "14"
      - name: "Install & build"
        run: |
          npm i
          npm run build
          mv public/index.html public/index.nginx-debian.html
Enter fullscreen mode Exit fullscreen mode

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:

      - name: "Push to server"
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USERNAME }}
          key: ${{ secrets.SSH_KEY }}
          port: ${{ secrets.SSH_PORT }}
          source: "public/"
          strip_components: 1
          target: "/var/www/html"
Enter fullscreen mode Exit fullscreen mode

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:

GitHub logo hnrq / vlrn-website

Landing page for veloren server

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.

Looking for a shareable component template instead? You can use SvelteKit for that as well or the older sveltejs/component-template


svelte app

This is a project template for Svelte apps. It lives at https://github.com/sveltejs/template.

To create a new project based on this template using degit:

npx degit sveltejs/template svelte-app
cd svelte-app
Enter fullscreen mode Exit fullscreen mode

Note that you will need to have Node.js installed.

Get started

Install the dependencies...

cd svelte-app
npm install
Enter fullscreen mode Exit fullscreen mode

...then start Rollup:

npm run dev
Enter fullscreen mode Exit fullscreen mode

Navigate to localhost:8080. You should see your app running. Edit a component file in src, save it, and reload the page to see your changes.

By default, the server will only respond to requests from localhost. To allow connections from…

Discussion (0)