Setup Self-Hosted GitHub Runner on Raspberry Pi 5

June 17, 2026 · View on GitHub

Arm Examples » Setup Self-Hosted GitHub Runner on Raspberry Pi 5

Setup Self-Hosted GitHub Runner on Raspberry Pi 5

Setup of Raspberry Pi 5 for test execution

This is a step-by-step guide for the configuration of a Raspberry Pi 5 that runs GitHub Actions for test execution on hardware targets.

1. Flash Ubuntu to microSD

Use Raspberry Pi Imager to flash (image) Ubuntu Server onto a microSD card.

Before you start:

  • Download and install Raspberry Pi Imager on a computer with a microSD card reader.
  • Insert the microSD card you’ll use with the Raspberry Pi.
  • Start Raspberry Pi Imager.

Use the following settings with the Raspberry Pi Imager:

  • Device: Raspberry Pi 5
  • OS: Other general-purpose OS → Ubuntu → Ubuntu Server 24.04.3 LTS (64-bit)
  • Storage: Your microSD card (example: Generic STORAGE DEVICE USB Device)
  • Customization:
    • Enter a unique hostname, for example: rpi-ci
    • Set locale, time zone, and keyboard layout
    • Configure username and password (example: username devuser, password devuser)
    • If the Raspberry Pi is connected via LAN, no Wi-Fi configuration is required
    • SSH authentication: enable SSH access. For simplicity, use password authentication (default).
  • Write image: It summarizes the configuration and lets you confirm the image setup.

Caution

Selecting a storage device and writing the image will erase the contents of the microSD card.

2. First boot and updates

  1. Power up the Raspberry Pi

    • Insert the microSD.
    • Connect the Raspberry Pi to the monitor, keyboard, and LAN.
    • Power on the Raspberry Pi.
  2. Boot messages

    • Top left corner: Ubuntu 24.04.3 LTS rpi-ci tty1
    • The boot process takes a long time during the initial setup because Ubuntu performs several initializations.
    • If you see no progress, press Enter.
  3. Login Prompt: devuser@rpi-ci. Log in with username devuser and password devuser.

  4. Welcome screen

    Welcome to Ubuntu 24.04.3 LTS (GNU/Linux 6.8.0-1031-raspi aarch64)
    :::::
    74 updates can be applied immediately.
    
  5. Apply available updates (this may take some time)

    sudo apt update        # Fetches the list of available updates
    sudo apt upgrade       # Installs some updates; does not remove packages
    sudo apt full-upgrade  # Installs updates; may also remove some packages, if needed
    sudo apt autoremove    # Removes any old packages that are no longer needed
    

3. Register MAC on corporate network

Some corporate networks require device registration (often called MAC address postive listing or whitelisting) before a new device can get network access.

  1. Check your corporate IT/network onboarding process.

    • Look for a device registration portal, NAC onboarding page, or a helpdesk workflow.
  2. Find the LAN MAC address of your Raspberry Pi 5 with:

    ip a
    

    In the eth0 section, the value after link/ether, e.g., 88:A2:9E:49:E6:CB is the LAN (Ethernet) MAC address of your Raspberry Pi 5.

  3. Register the Raspberry Pi's Ethernet MAC address (from Section 3) in your corporate system.

    • Typical fields are:
      • Device name: rpi-ci (example)
      • Device ID / MAC: 88:A2:9E:49:E6:CB (example)
      • Description: Raspberry Pi 5 (runner)
  4. Wait for approval/propagation (if applicable), then reconnect the Ethernet cable, reboot the Raspberry Pi 5, and continue with the next section.

4. Find IP address

  1. Connect to your Raspberry Pi with keyboard, monitor, and LAN.

    • The Raspberry Pi is assigned an IP address.
  2. Type:

    ip a
    

    The value behind eth0, e.g. 10.41.0.178 is the assigned IP address that is used in section 5.

5. Connect with SSH from remote computer

  1. Open PowerShell or Bash console and type:

    ssh devuser@10.41.0.178
    
  2. Enter password: devuser to complete the connection.

6. Install tools and packs

  1. Update and install build tools and other software

    sudo apt update
    sudo apt upgrade
    sudo apt install cmake ninja-build -y
    sudo apt install unzip -y
    
  2. Download and install CMSIS-Toolbox (any version newer then 2.14.1)

    wget https://artifacts.tools.arm.com/cmsis-toolbox/2.14.1/cmsis-toolbox-linux-arm64.tar.gz
    tar -xf cmsis-toolbox-linux-arm64.tar.gz
    
  3. Download and install pyOCD (any version newer than 0.44.1)

    wget https://github.com/pyocd/pyOCD/releases/download/v0.44.1/pyocd-linux-arm64-0.44.1.zip
    mkdir pyocd && cd pyocd
    unzip ./../pyocd-linux-arm64-0.44.1.zip
    cd ..
    
  4. Download and install the SDSIO-server (any version newer than 3.0.1)

    wget https://github.com/ARM-software/SDS-Framework/releases/download/v3.0.1/sdsio-server-linux-arm64-3.0.1.zip
    mkdir sdsio-server && cd sdsio-server
    unzip ./../sdsio-server-linux-arm64-3.0.1.zip
    cd ..
    
  5. Set up environment variables

    export PATH="$HOME/pyocd:$PATH"
    export CMSIS_TOOLBOX_ROOT="$HOME/cmsis-toolbox-linux-arm64"
    export PATH="$CMSIS_TOOLBOX_ROOT/bin:$PATH"
    export CMSIS_PACK_ROOT="$HOME/packs"
    export PATH="$HOME/sdsio-server:$PATH"	
    

    IMPORTANT: Make paths available after a reboot of the Raspberry Pi hardware with:

    echo 'export PATH="$HOME/pyocd:$PATH"' >> ~/.bashrc
    echo 'export CMSIS_TOOLBOX_ROOT="$HOME/cmsis-toolbox-linux-arm64"' >> ~/.bashrc
    echo 'export PATH="$CMSIS_TOOLBOX_ROOT/bin:$PATH"' >> ~/.bashrc
    echo 'export CMSIS_PACK_ROOT="$HOME/packs"' >> ~/.bashrc
    echo 'export PATH="$HOME/sdsio-server:$PATH"' >> ~/.bashrc	
    

    TIP: Sanity check pyOCD, cpackget, and sdsio-server installation and version numbers:

    pyocd --version            # expected version 0.44.1 or higher
    cpackget --version         # expected version 2.2.1 or higher
    sdsio-server --version     # expected version 3.0.1 or higher
    
  6. Install required software packs

    Install the BSP and DFP software packs for your target hardware. The *.cbuild-run.yml file of your application lists this information. Alternatively, use www.keil.arm.com/packs to discover this information. For the NUCLEO-H563ZI, these packs are required:

    cpackget add Keil::NUCLEO-H563ZI_BSP@1.1.1
    cpackget add Keil::STM32H5xx_DFP@2.2.0
    

    NOTE: This is a one-time installation that depends on the target hardware connected to the Raspberry Pi 5.

  7. Install udev rules (required for USB access)

    The udev rules control how USB devices are detected and what permissions they get. The following examples show typical setups:

    # ---- STLINK V3 ----
    sudo wget https://raw.githubusercontent.com/pyocd/pyOCD/main/udev/49-stlinkv3.rules -O /etc/udev/rules.d/49-stlinkv3.rules
    
    # ---- CMSIS-DAP ----
    sudo wget https://raw.githubusercontent.com/pyocd/pyOCD/main/udev/50-cmsis-dap.rules -O /etc/udev/rules.d/50-cmsis-dap.rules
    
    # ---- KitProg3 CMSIS-DAP (Cypress) ----
    sudo tee -a /etc/udev/rules.d/99-kitprog3.rules > /dev/null << 'EOF'
    # KitProg3 CMSIS-DAP (Cypress) - allow runner user access
    SUBSYSTEM=="usb", ATTR{idVendor}=="04b4", ATTR{idProduct}=="f155", MODE="0666", GROUP="plugdev"
    EOF
    
    # ---- Keil USB SDSIO Client ----
    sudo tee -a /etc/udev/rules.d/99-sdsio-client.rules > /dev/null << 'EOF'
    # c251:8007 Keil USB SDSIO Client
    SUBSYSTEM=="usb", ATTR{idVendor}=="c251", ATTR{idProduct}=="8007", MODE="0666"
    EOF
    
  8. Reload udev so the new rules take effect:

    sudo udevadm control --reload-rules
    sudo udevadm trigger
    
  9. Ensure plugdev group

    Add your user to plugdev for USB device access:

    sudo groupadd -f plugdev
    sudo usermod -aG plugdev $USER
    
  10. Connect the target hardware to Raspberry Pi 5 and verify the debug adapter connection using the pyOCD list command. In this example, two debug adapters are connected. Use the Unique ID with the pyOCD option --uid to select a specific probe.

    pyocd list
    
       #   Probe/Board                                Unique ID                  Target
     ---------------------------------------------------------------------------------------------
       0   KEIL - Tools By ARM Keil ULINKplus         L96807771A                 n/a
    
       1   STLINK-V3                                  001700054142501320353451   stm32h563zitx NUCLEO-H563ZI
    

7. Add self-hosted runner

Use GitHub’s official documentation for the most up-to-date steps:

High-level flow (GitHub UI will generate the exact commands and a time-limited token):

  1. Decide where to add the runner: repository, organization, or enterprise.
  2. In GitHub, go to SettingsActionsRunners.
  3. Click New self-hosted runner and select OS/architecture.
  4. On the Raspberry Pi, run the Download, Configure, and Run commands shown by GitHub.
  5. Verify the runner shows as Idle on the Runners page.

8. Autostart runner (systemd)

It is recommended to use the GitHub svc.sh helper that is created after you add/configure the runner on the Raspberry Pi 5. Refer to Configuring the self-hosted runner application as a service.

  1. Open a shell in the directory where you installed the runner (the folder that contains config.sh).

  2. If the runner is currently running interactively, stop it.

  3. Install and start the service:

    sudo ./svc.sh install
    sudo ./svc.sh start
    
  4. Check status:

    sudo ./svc.sh status
    

Note

If you need a custom systemd unit, GitHub recommends invoking the runner via runsvc.sh and using the service template under bin/ in the runner directory.