Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Using my new Raspberry Pi to run an existing GitHub Action (frankel.ch)
88 points by nfrankel on March 12, 2024 | hide | past | favorite | 31 comments


Self-hosted runners are also useful when debugging weird behaviour in a GitHub Action.

I do it by spinning up a VM on my local pc, then running the GitHub Actions software in the VM.

This gives a fully working GitHub Actions runner which I can ssh into directly and muck around with to investigate and get things working.

It's also easy to ensure only the right jobs end up on my runner.

The installer for the GitHub Actions runner asks for optional tag names to use, so I add "jc" (my initials) to the tags.

Then I add a matching "jc" to the "runs-on" clause in the workflow in my fork or PR:

    runs-on: [self-hosted, linux, x64, jc]
With that, the GitHub Actions for that workflow only run on my local VM.

Works pretty well. :)

---

Official docs for the labelling bit: https://docs.github.com/en/actions/hosting-your-own-runners/...


An easier way to debug Github Actions is to use tmate [0]. In short, you can set up an action that allows you to tmate into the worker on failure and then figure out what's wrong. In addition to the default setup, it's recommended to limit access with an SSH key [1].

[0] https://github.com/mxschmitt/action-tmate

[1] https://github.com/mxschmitt/action-tmate?tab=readme-ov-file...


Thanks, that sounds like it's worth checking out. :)


Do you do this for public repos? GitHub Actions is strongly not recommended for non-private. Struggling to have good security policies in place for a deployment I'm doing...


Sounds like outdated advice from the time before they implemented approval for running action from PR of untrusted people.

In the past, people could modify the GitHub action workflow and run crypto miners on the agents.

But since GitHub changed the default for PR where the actions aren't run anymore that killed that attack vector.


Because the self-hosted runners save state between runs, as well as publicly-opened PRs/branches giving the public access to your runner environment variables/secrets.


> GitHub Actions is strongly not recommended for non-private.

By who? Why?


Thanks, I'd not seen that recommendation.

Looks like I'd better do some research. :)


Where are you seeing that GitHub actions isn’t recommended for public repos?


I believe they're referring to this section: https://docs.github.com/en/actions/hosting-your-own-runners/...


Having recently set up a Gitlab self-hosted runner, the process seems far, far simpler - it's a case of running a Docker image on your system (or installing a binary/package), registering your runner through Gitlab settings and you're finished.

It manages running things in other Docker containers for you (or on one of many other runner options) and it worked without any modifications to my workflows. Very pleased with it.


Would love to hear more about this! Are there arm compatible images?


I'm not sure if ARM is supported in the Docker image, but it is definitely supported by the Gitlab runner itself[0]. I do also build images for ARM systems using mine and it works completely flawlessly.

[0]: https://docs.gitlab.com/runner/install/


I have a setup on a Pi for deploying progscrape.com that has a systemd task to boot a new runner in a container. I really need to turn it into a bare-metal deployment script so I can recover from an SD card crash.

Basically this service:

  [Unit]
  Description=%N Container
  After=docker.service
  Requires=docker.service
  [Service]
  TimeoutSec=3600
  Restart=always
  WorkingDirectory=/srv/progscrape/progscrape-deploy/github-runners
  ExecStartPre=-/usr/bin/docker compose -f %N.yml -p %N stop
  ExecStartPre=-/usr/bin/docker compose -f %N.yml -p %N pull
  ExecStart=/usr/bin/docker compose -f %N.yml -p %N up
  ExecStopPost=-/usr/bin/docker compose -f %N.yml -p %N rm -f
  [Install]
  WantedBy=multi-user.target
Boots this docker compose definition:

  services:
    github-docker-runner:
      image: myoung34/github-runner:latest
      restart: "no"
      environment:
        RUNNER_NAME: progscrape-docker-compose
        RUNNER_WORKDIR: /tmp/work
        EPHEMERAL: 1
        LABELS: management,linux,ARM64
        DISABLE_AUTO_UPDATE: 1
      env_file:
        - github-runner.env
      configs:
        - github-runner-start
      entrypoint: /bin/sh
      command: /github-runner-start
      security_opt:
        # needed on SELinux systems to allow docker container to manage other docker containers
        - label:disable
      volumes:
        - '/var/run/docker.sock:/var/run/docker.sock'

  configs:
    github-runner-start:
      file: runner-start.sh


      volumes:
        - '/var/run/docker.sock:/var/run/docker.sock'

The good old docker security nightmare. That thing has essentially root access to your machine. Just so you know.

You might want to move to Podman (which can be executed in rootless mode) so that you can also run podman-in-podman without much hassle (it's officially supported afaik).


Or follow the doc on running docker rootless: https://docs.docker.com/engine/security/rootless/

But in any case I think it's always better to do docker in docker for security. Also it help control what version of docker is used by the agent and it can then be a different one than the one on the host.


I am kind of surprised that the Action runner isn’t just some sort of Container or VM manager like Drone?

The runs actually occur on your real OS? That seems strange and dangerous.


It lets you manage containers in your actions. Nesting containers is not straightforward in many cases.


I can be really nice to have this option but I'm surprised it is the default. For example I use Nix and running a build on the host is great because you get the shared caching. When doing this on GitLab I have a tiny shim socket image that bind-mounts the host daemon socket.


> The script uses systemd underneath.

Just show us that mess of your's :)


We're running a lot of CI on our custom runners. The fact that it runs in the OS context is a bit meh. If someone has a good resource on setting up docker on a RPi for a custom runner, please throw it my way.


How do you guys run Github Actions locally?


GitHub provides an agent that you can run. It polls GitHub for tasks and runs them locally. They also provide docker images and even a Kubernetes controller for auto scaling runners. Some people do it with lambda functions or plain ec2 launched on the fly.

If you meant to ask how to run the GitHub actions code without GitHub then the sibling comment would help for most tasks but has limitations.


This is my attempt at running Github Actions locally on arm and arm64:

https://github.com/mutablelogic/docker-action-runner

Running the actions in a docker container is not ideal by any means. The authors of Github Actions do not have a stable API between the actions runner and whatever triggers them on their server side; you need to keep the docker container up-to-date every few months, it's not a "fire and forget" thing.


Not sure if this is what they are using, but this is a way.

  https://github.com/nektos/act



This looks promising!


Yes. But act isn't entirely compatible unfortunately. To run the "real" thing, my latest attempt is here: https://github.com/efrecon/gh-runner-krunvm. It let you create ephemeral runners in microVMs. As soon as one runner has finished a job, a new one will be created. You can have several of those loops running in parallel on the same host.


BTW if you came here to get your GitHub actions run on ARM64, you don't need RPi for that. You can get a free VM from Oracle.


I'd rather eat Surstrømming daily than get involved in anything from Oracle.


may I ask why? in my opinion, very generous free tier, and overall excellent hosting




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: