Home
Projects
Blog
Toggle Cursor trail
LinkedIn
GitHub
Printables
Email Me
Switch to dark theme

Setting up Proxmox self-hosted Github runners for Subtext

First Published: 2025-04-25

Last Updated: 2025-04-25

Documenting how the Subtext self-hosted runners were setup

Background

When I was developing Subtext I wanted to set a CI/CD pipeline to automate builds because my development branch often had debug flags and features enabled which I kept forgetting to disable for production builds.
A CI/CD pipeline would generate builds that were theoretically production "ready" with the correct flags and require minimal effort from me.

To answer a pre-empted question: Why not use Github's own hosted runners instead of a self-hosted runner?
Ans: The built application executable is extremely sizable. Downloading these executables for testing even with a fast internet connection would take ages.
So I had an idea: why not set up a self-hosted runner which saves artifacts to a local isolated SMB share after application is built.

With that being stated, it is probally important to note that this blogpost is to document the 2nd time I set up this pipeline as the first attempt somehow catastrophically failed as the proxmox VM refused to start after a system reboot.
As such some instructions might be light on details as to why specific settings are being chosen.

Proxmox Setup

I used fairly standard settings to set up the env for the windows VM:
  1. OVMF (UEFI) Bios
  2. q35 Machine Type for PCIE Features
  3. 6 Host Cores and 16gb of RAM
  4. VirtIO SCSI Controller
  5. Bridged Network bond
  6. Windows 11 Enterprise LTSC ISO
The only thing to note during the installation is that Windows cannot see the Virtual disk, and requires the VirtIO Disk driver has to be installed (Instructions)

Windows VM Setup

Software

Apart from the direct dependencies required for my application, there are some other necessary pieces which need to be installed
These include
  1. Rest of the VirtIO Driver Suite (Instructions)
    This is needed for networking to function.
  2. Microsoft Store
    This is for installing WinGet and simplify downloading software.
    Since this is normally not installed in Win 11 LTSC, this needs to be re-installed with
    wsreset -i
  3. WinGet
    Once the Microsoft Store has been installed, WinGet can be installed with the "App Installer" System App within the store.
  4. Windows Terminal
    For some terminal QOL
    Install:
    winget install --id=Microsoft.WindowsTerminal -e

Settings

Since this VM is mostly going to be interacted with within QEMU, these tweaks from this TechHut video disabling some Windows graphics effects improves the experience greatly.

Github Runner Setup

To download the Github Runner application, follow the instructions from the runner release notes

Since setting up the Github Runner as a Service lets it auto starts when the VM boots,
Run the config script as Administrator

config.cmd --url "REPO URL HERE" --token "RUNNER TOKEN GOES HERE"

Additionally, to prevent permission issues running as "NT AUTHORITY\NETWORK SERVICE", when the script asks, set the runner to run as "NT AUTHORITY\SYSTEM".

PATH Limitations

A Limitation to running as a service are restrictions to using the PATH
The Github Runner will not be able to access the user PATH.
It appears that the official solution is to add your necessary PATH variables to a .env file in the runner folder.

Given that I will likely be the only person to ever use my runner, I found it easier to add a hard-coded path into the script, which is enabled when a specific argument is passed to the script.

Exporting Build Artifacts

One of my stated goals in setting up the runner was to save the build artifacts to a local SMB share.
Be it either a skill issue or a Windows Service limitations, I have not been able to get this working.

Instead I found the easiest solution was to utilise syncthing. To achieve this,

  1. Set up a builds folder ("C:\Builds\Subtext\") and then add a step to the Github action to copy artifacts to that folder
  2. Make a one-way send syncthing connection between that folder and the build folder on the NAS. (Syncthing Documentation)

Conclusion

In the end this is how I set up a Github Self-Hosted runner in Windows for Subtext.
If I were ever to need to redo this again, I would properly set up the env file to properly fix the Path issues.
All in all, I am quite happy with how it turned out, and it works quite well.

Notes

Github Runner Bugs

When I was setting up the runner, I kept needing to restart Windows as I installed new dependencies.
One time, I started Windows and the Github Runner Service stopped working as it reported that the repo had removed the runner.
When I checked on the repo settings, the runner was still assigned.
To fix this, I removed the runner and reconfigured the runner using the script.
I have not been able to recreate this bug since.

Implementation Notes

I wanted to note some implementation details that I improved from the first attempt

  1. The minimum amount of RAM for a good experience seems to be a minimum of 16GB, 8GB of ram in Windows 11 is really not enough.
  2. The bottleneck in the build pipeline for Subtext in my experience tends to be CPU-based as the Innosetup and 7Zip compression step tends to be take the longest.
    As such, it is recommended to allocate as many CPU cores to the VM as possible.
This work is licensed under

CC BY 4.0

Creative Commons IconCreative Commons BY Icon
Profile Picture
linkedIn Profile LinkGitHub