Package: testflows.github.hetzner.runners
PyPi:VersionsLicense:Apache-2.0Autoscaling GitHub Actions Runners Using Hetzner CloudA simple alternative to Github’sRecommended autoscaling solutions.🔍 Tip:SeeWikifor full documentation.Thegithub-hetzner-runnersservice program starts and monitors queued-up jobs for GitHub Actions workflows.
When a new job is queued up, it creates a new Hetzner Cloud server instance
that provides an ephemeral GitHub Actions runner. Each server instance is automatically
powered off when the job completes, and then powered off servers are
automatically deleted. Bothx64(x86) andarm64(arm) runners are supported.
SeeFeaturesandLimitationsfor more details.❗Warning:This program is provided on “AS IS” basis without warranties or conditions of any kind. See LICENSE.
Use it at your own risk. Manual monitoring is required to make sure server instances are cleaned up properly
and costs are kept under control.Costs depend on the server type, number of jobs, and execution time. For each job, a new server instance is created
to avoid any cleanup. Server instances are not shared between jobs.✋ Note:Currently, Hetzner Cloud server instances are billed on an hourly basis. So a job that takes 1 minute will be billed
the same way as for a job that takes 59 minutes. Therefore, the minimal cost
for any job, the cost of the server for 1 hour plus the cost of one public IPv4 address.Table of ContentsHomeInstallationQuick StartGetting Started TutorialBasic ConfigurationSpecifying the Maximum Number of RunnersSpecifying the Maximum Number of Runners Used in Workflow a RunRecycling Powered‐Off ServersSkipping JobsJobs That Require the Docker EngineSpecifying The Runner TypeSpecifying The Runner LocationSpecifying The Runner ImageSpecifying The Custom Runner Server Setup ScriptSpecifying The Custom Runner Server Startup ScriptDisable Setup or Startup ScriptsSpecifying Standby RunnersSpecifying Logger ConfigurationListing All Current ServersOpening The SSH Client To The ServerDeleting All Runners and Their ServersUsing a Configuration FileSpecifying SSH KeySpecifying Additional SSH KeysRunning as a ServiceRunning as a Cloud ServiceScaling Up RunnersScaling Down RunnersHandling Failing ConditionsMeta LabelsProgram OptionsFeaturescost-efficient on-demand runners usingHetzner Cloudsupports server recycling to minimize costssimple configuration, no Webhooks, no need for AWS lambdas, and no need to setup any GitHub applicationsupports specifying custom runner server types, images, and locations using job labelsself-contained program that you can use to deploy, redeploy, and manage the service on a cloud instancesupports x64 (x86) and ARM64 (arm) runnerssupports using any Hetzner Cloud server typessupports runners with pre-installed Dockersupports using any standard Hetzner Cloud images and applicationssupports auto-replenishable fixed standby runner pools for jobs to be picked up immediatelysupports limiting the maximum number of runners created for each workflow runsupports efficient GitHub API usage using HTTP caching and conditional requestssimpler alternative to what GitHub lists inRecommended Autoscaling SolutionsLimitationsGroup runners are not supported✎ However, you can run individual services for each repository using different Hetzner Cloud projects.A unique Hetzner Cloud project must be used for each repository✎ However, unique projects allow you to easily keep track of runner costs per repository.PrerequisitesPython >= 3.7Hetzner CloudaccountGitHub API token with admin privileges to manage self-hosted runnersInstallationpip3installtestflows.github.hetzner.runnersCheck that thegithub-hetzner-runnersutility was installed correctly by executing thegithub-hetzner-runners -vcommand.github-hetzner-runners-vThegithub-hetzner-runnersutility is installed in the~/.local/bin/folder. Please make sure that this folder
is part of thePATH.whichgithub-hetzner-runners~/.local/bin/github-hetzner-runnersIf yourPATHis missing this folder on Ubuntu, modify your~/.profileand add the following section:~/.profile:# set PATH so it includes the user's private bin if it existsif[-d"$HOME/.local/bin"];thenPATH="$HOME/.local/bin:$PATH"fiInstallation from SourcesFor development, you can install from sources as follows:gitclonehttps://github.com/testflows/testflows-github-hetzner-runners.git./package&&./installQuick StartSet environment variables corresponding to your GitHub repository and Hetzner Cloud project.exportGITHUB_TOKEN=ghp_...exportGITHUB_REPOSITORY=testflows/testflows-github-hetzner-runnersexportHETZNER_TOKEN=GJzdc...Then, start thegithub-hetzner-runnersprogram:github-hetzner-runners07/22/2023 08:20:37 PM   INFO MainThread            main 🍀 Logging in to Hetzner Cloud
07/22/2023 08:20:37 PM   INFO MainThread            main 🍀 Logging in to GitHub
07/22/2023 08:20:37 PM   INFO MainThread            main 🍀 Getting repository testflows/testflows-github-hetzner-runners
07/22/2023 08:20:37 PM   INFO MainThread            main 🍀 Creating scale-up services
07/22/2023 08:20:37 PM   INFO MainThread            main 🍀 Creating scale-down services
07/22/2023 08:20:38 PM   INFO   worker_2   create_server 🍀 Create server
...Alternatively, you can pass the required options using the command line as follows:github-hetzner-runners--github-token<GITHUB_TOKEN>--github-repository<GITHUB_REPOSITORY>--hetzner-token<HETZNER_TOKEN>Getting Started Tutorial✅ Launch your first self-hosted runner in:5 minutesThis tutorial will guide you on how to use thegithub-hetzner-runnersprogram to provide autoscaling GitHub Actions runners
for a GitHub repository and a Hetzner Cloud project that you’ll create.Installing TestFlows Github Runners❶ Before we get started, you will need to installtestflows.github.hetzner.runnersPython package. See theInstallationsection for more details.pip3installtestflows.github.hetzner.runners❷ Check that thegithub-hetzner-runnersutility was installed correctly by executing thegithub-hetzner-runners -vcommand.github-hetzner-runners-v1.3.230731.1173142✋ Note:Thegithub-hetzner-runnersutility is installed in to the~/.local/bin/folder. Please make sure that this folder
is part of thePATH.whichgithub-hetzner-runners~/.local/bin/github-hetzner-runnersIf yourPATHis missing this folder, on Ubuntu, you can modify your~/.profileand add the following section:~/.profile:# set PATH so it includes the user's private bin if it existsif[-d"$HOME/.local/bin"];thenPATH="$HOME/.local/bin:$PATH"fiIn order to launch thegithub-hetzner-runnersprogram, we’ll need to specify the GitHub repository as well as GitHub and
Hetzner Cloud tokens. So, let’s create these.Creating a GitHub Repository With Actions Workflow and TokenBefore using thegithub-hetzner-runners, you need a GitHub repository with a GitHub Actions workflow set up.❶ First, create a GitHub repository nameddemo-testflows-github-hetzner-runnersand note the repository name.The repository name will have the following format:<username>/demo-testflows-github-hetzner-runnersFor me, my GitHub repository is:vzakaznikov/demo-testflows-github-hetzner-runners❷ Now, create an example GitHub Actions workflow as described in theQuickstart for GitHub Actionsarticle.
Note that we need to modify the example YAML configuration and specify that our job will run on a runner with theself-hostedand thetype-cpx21labels.Explore-GitHub-Actions:runs-on:[self-hosted,type-cpx21]So, the completedemo.ymlthat uses a self-hosted runner is as follows:demo.yml:name:GitHub Actions Demorun-name:${{ github.actor }} is testing out GitHub Actions 🚀on:[push]jobs:Explore-GitHub-Actions:runs-on:[self-hosted,type-cpx21]steps:-run:echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."-run:echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"-run:echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."-name:Check out repository codeuses:actions/checkout@v3-run:echo "💡 The ${{ github.repository }} repository has been cloned to the runner."-run:echo "🖥️ The workflow is now ready to test your code on the runner."-name:List files in the repositoryrun:|ls ${{ github.workspace }}-run:echo "🍏 This job's status is ${{ job.status }}."❸ Finally, you will need to create a GitHub API token with theworkflowprivileges. Make sure to save the token!For me, mydemoGitHub token is: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You should now have your GitHub repository ready.See these steps in action:Creating a Hetzner Cloud Project and TokenNext, you will need to create a Hetzner Cloud project and an API token that we can use to create and manage Hetzner Cloud server instances.❶ Create a new Hetzner Cloud projectDemo GitHub Runners.❷ Now, create an API token and save it.For me, the Hetzner Cloud token for myDemo GitHub Runnersproject is:5Up04IHuY8mC7l0JxKwh3Aps4ghGIyL0NJ9rGlhyAmmkddzuRreR1YstTSTFCG0NYou should now have your Hetzner Cloud project ready.See these steps in action:Creating a Cloud ServiceWith the GitHub repository and GitHub and Hetzner Cloud tokens in hand, we can deploy thegithub-hetzner-runnersservice
to the Hetzner Cloud instance. This way, the service is not running on your local machine.During the deployment, we’ll create agithub-hetzner-runnersinstance in your Hetzner Cloud project on which the service will be running.
See theRunning as a Cloud Servicesection for details.❶ To deploy the service run thegithub-hetzner-runners cloud deploycommand and specify your
GitHub repository, GitHub, and Hetzner Cloud tokens usingGITHUB_REPOSITORY,GITHUB_TOKEN, andHETZNER_TOKENenvironment variables.exportGITHUB_REPOSITORY=exportHETZNER_TOKEN=exportGITHUB_TOKEN=github-hetzner-runnersclouddeployYou should now have the cloud service up and running.See these steps in action:Waiting for the GitHub Actions Job to Complete❶ Thegithub-hetzner-runnerscloud service is now running. So, now you can just sit back and wait untilgithub-hetzner-runnersspins up a new runner to complete any queued-up GitHub Actions jobs in your GitHub repository.See this step in action:As you can see, our job was executed and completed using our own self-hosted runner!✋ Note:If you run into any issues, you can check the cloud service log using thegithub-hetzner-runners cloud log -fcommand. For other cloud service commands, see theRunning as a Cloud Servicesection.github-hetzner-runnerscloudlog-f🔍 SeeWikifor full documentation.Developed and maintained by theTestFlowsteam.