{"id":13408,"date":"2023-04-18T15:10:10","date_gmt":"2023-04-18T09:40:10","guid":{"rendered":"https:\/\/opstree.com\/blog\/\/?p=13408"},"modified":"2026-03-05T17:58:31","modified_gmt":"2026-03-05T12:28:31","slug":"github-self-hosted-runner-on-kubernetes","status":"publish","type":"post","link":"https:\/\/opstree.com\/blog\/2023\/04\/18\/github-self-hosted-runner-on-kubernetes\/","title":{"rendered":"GitHub: Self-Hosted Runner on Kubernetes &#8211; How to Setup"},"content":{"rendered":"\r\n<p>GitHub Actions is a powerful <a href=\"https:\/\/buildpiper.io\/\" target=\"_blank\" rel=\"noopener\">CI\/CD tool<\/a> that lets developers build, test, and deploy software through customizable workflows. It provides a managed infrastructure for executing tasks, but sometimes it&#8217;s necessary to use a self-hosted infrastructure.<\/p>\r\n<p>In this blog, we will detail how to set up and leverage self-hosted runners with GitHub Actions, aiming to optimize workflow and improve your development process.<\/p>\r\n\r\n\r\n\r\n<p>GitHub Actions can use two types of runners: hosted and self-hosted.<\/p>\r\n\r\n\r\n\r\n<ul>\r\n<li><strong>Hosted runners<\/strong> are provided by GitHub and run on virtual machines in the cloud.<\/li>\r\n\r\n\r\n\r\n<li><strong>Self-hosted runners<\/strong> are machines that you set up and manage yourself. They run on your infrastructure, and you can customize them to meet your needs.<\/li>\r\n<\/ul>\r\n<p><!--more--><\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-13481\" style=\"width: 704px; height: 383px;\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2023\/03\/diagram.png?w=859\" alt=\"\" width=\"704\" height=\"383\" \/><\/figure>\r\n\r\n\r\n\r\n<p>In this tutorial, we will show you how to set up GitHub&#8217;s self-hosted runner on Kubernetes.<\/p>\r\n\r\n\r\n\r\n<p><strong>Prerequisites<\/strong><\/p>\r\n\r\n\r\n\r\n<p>Before you begin, make sure you have the following:<\/p>\r\n\r\n\r\n\r\n<ul>\r\n<li>A Kubernetes cluster<\/li>\r\n\r\n\r\n\r\n<li>Helm Installed<\/li>\r\n\r\n\r\n\r\n<li>Access to a <a href=\"https:\/\/opstree.com\/blog\/2022\/06\/21\/what-is-a-bare-git-repository\/\" target=\"_blank\" rel=\"noopener\">GitHub repository<\/a> for creating PAT and adding runners.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">Installing Cert Manager on K8s cluster.<\/h3>\r\n\r\n\r\n\r\n<ul>\r\n<li>Well, actions-runner-controller(ACR) uses\u00a0cert-manager\u00a0for certificate management of\u00a0admission webhook, so we have to ensure cert-manager is installed on Kubernetes before installing actions-runner-controller.\u00a0<\/li>\r\n\r\n\r\n\r\n<li>Refer to this link for <a href=\"https:\/\/artifacthub.io\/packages\/helm\/cert-manager\/cert-manager\" target=\"_blank\" rel=\"noopener\">Cert Manager Installation via Helm<\/a><\/li>\r\n\r\n\r\n\r\n<li>Verify the installation by running the below command.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-13442\" style=\"width: 701px; height: 310px;\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2023\/03\/cert_manager-1.png?w=797\" alt=\"\" width=\"701\" height=\"310\" \/><\/figure>\r\n\r\n\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">Authentication for Self-Hosted Runners<\/h3>\r\n\r\n\r\n\r\n<p>There are two ways for the actions-runner-controller to authenticate with the GitHub API (only 1 can be configured at a time, however):<\/p>\r\n\r\n\r\n\r\n<ol>\r\n<li>Using a GitHub App (not supported for enterprise-level runners due to lack of support from GitHub)<\/li>\r\n\r\n\r\n\r\n<li>Using a PAT(Personal Access Token)<\/li>\r\n<\/ol>\r\n\r\n\r\n\r\n<p>We are going to use PAT for our use case.<\/p>\r\n\r\n\r\n\r\n<p>To register the self-hosted runner with GitHub, generate a PAT with the <code>repo<\/code> scope. Here&#8217;s how to generate the PAT:<\/p>\r\n\r\n\r\n\r\n<ul>\r\n<li>Go to your GitHub account settings and select &#8220;Developer settings&#8221;.<\/li>\r\n\r\n\r\n\r\n<li>Select &#8220;Personal access tokens&#8221;.<\/li>\r\n\r\n\r\n\r\n<li>Click the &#8220;Generate new token&#8221; button.<\/li>\r\n\r\n\r\n\r\n<li>Give your token a name and select the <code>repo<\/code> scope.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-13424\" style=\"width: 706px; height: 336px;\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2023\/03\/github_token-1.png?w=989\" alt=\"\" width=\"706\" height=\"336\" \/><\/figure>\r\n\r\n\r\n\r\n<ul>\r\n<li>Click &#8220;Generate token&#8221; and save the token somewhere safe.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-13426\" style=\"width: 703px; height: 192px;\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2023\/03\/generate_token.png?w=571\" alt=\"\" width=\"703\" height=\"192\" \/><\/figure>\r\n\r\n\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n\r\n\r\n<ul>\r\n<li>Use the below command to create Kubernetes secret which will be used by ACR(Actions Runner Controller)<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code># Creating Namespace for ARC\r\nkubectl create ns actions-runner-system\r\n\r\n# Creating secret for ARC, so that it can register runners on github\r\nkubectl create secret generic controller-manager -n actions-runner-system \r\n--from-literal=github_token=&lt;GitHub Token&gt;<\/code><\/pre>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">Installing ARC on Kubernetes Cluster<\/h3>\r\n\r\n\r\n\r\n<ul>\r\n<li>Execute below mentioned Helm commands,<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code># Adding Helm Repo of ARC\r\nhelm repo add actions-runner-controller https:\/\/actions-runner-controller.github.io\/actions-runner-controller\r\n\r\n# Updating Helm Repo\r\nhelm repo update\r\n\r\n# Installing ARC\r\nhelm upgrade --install --namespace actions-runner-system \r\n--create-namespace --wait actions-runner-controller \r\nactions-runner-controller\/actions-runner-controller --set \r\nsyncPeriod=1m\r\n<\/code><\/pre>\r\n\r\n\r\n\r\n<ul>\r\n<li>Verify that the action-runner-controller is installed properly using the below command<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-13429\" style=\"width: 710px; height: 174px;\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2023\/03\/arc.png?w=991\" alt=\"\" width=\"710\" height=\"174\" \/><\/figure>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">Creating Runners for Repository<\/h3>\r\n\r\n\r\n\r\n<ul>\r\n<li>Create a RunnerDeployment Kubernetes object, which will create a self-hosted runner for the GitHub repository.<\/li>\r\n\r\n\r\n\r\n<li>Create file\u00a0<strong>runner.yaml<\/strong> and paste the below content<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<figure class=\"wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler\">\r\n<div class=\"wp-block-embed__wrapper\">https:\/\/gist.github.com\/vikas-bisht16\/3d5c1068b66a7205a276179c919e528d<\/div>\r\n<\/figure>\r\n\r\n\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n\r\n\r\n<p>Here, change the <strong>Repository Name<\/strong> to your GitHub Repo name &amp; labels for runners, so that you can customize your workflow in such a way that a particular job would run on a particular runner only. The below image shows custom labels on a runner.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-13454\" style=\"width: 714px; height: 95px;\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2023\/03\/runner_labels.png?w=784\" alt=\"\" width=\"714\" height=\"95\" \/><\/figure>\r\n\r\n\r\n\r\n<ul>\r\n<li>Execute the below command to create a <strong>RunnerDeployment<\/strong> object.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>kubectl create -f runner.yaml<\/code><\/pre>\r\n\r\n\r\n\r\n<ul>\r\n<li>Check that the pod is running using the below command.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>kubectl get pod -n actions-runner-system | grep -i \"k8s-action-runner\"<\/code><\/pre>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-13458\" style=\"width: 701px; height: 42px;\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2023\/03\/runner_pod-1.png?w=727\" alt=\"\" width=\"701\" height=\"42\" \/><\/figure>\r\n\r\n\r\n\r\n<ul>\r\n<li>Now, you should see actions runner pods on <a href=\"https:\/\/opstree.com\/blog\/2025\/11\/18\/kong-gateway-in-kubernetes\/\" target=\"_blank\" rel=\"noopener\">Kubernetes<\/a>, which is also registered on GitHub. Check under Repository Settings &gt; Actions &gt; Runner.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-13459\" style=\"width: 738px; height: 200px;\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2023\/03\/github_runner.png?w=1024\" alt=\"\" width=\"738\" height=\"200\" \/><\/figure>\r\n\r\n\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">Creating HRA(HorizontalRunnerAutoscaler) for Runners<\/h3>\r\n\r\n\r\n\r\n<p>Setting up a <a href=\"https:\/\/github.com\/actions\/actions-runner-controller\/blob\/master\/docs\/automatically-scaling-runners.md\" target=\"_blank\" rel=\"noopener\">HorizontalRunnerAutoscaler<\/a> for your self-hosted runner can help to ensure that you have the appropriate amount of resources available to handle your continuous integration and deployment needs. By automating the scaling process based on predefined rules and metrics, you can reduce the risk of resource constraints and ensure that your builds and deployments remain fast and reliable.<\/p>\r\n\r\n\r\n\r\n<ul>\r\n<li>Create a file &#8220;horizontal_runner_autoscaler.yaml&#8221; &amp; paste the below content.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<figure class=\"wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler\">\r\n<div class=\"wp-block-embed__wrapper\">https:\/\/gist.github.com\/vikas-bisht16\/f75d4a65f96ea2525dcfe4ac9c581870<\/div>\r\n<\/figure>\r\n\r\n\r\n\r\n<ul>\r\n<li>Execute the below command.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code># Applying the HRA\r\nkubectl apply -f horizontal_runner_autoscaler.yaml\r\n\r\n# Run below to command to verify the HRA object\r\nkubectl get HorizontalRunnerAutoscaler -n actions-runner-system<\/code><\/pre>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-13467\" style=\"width: 673px; height: 70px;\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2023\/03\/hra.png?w=622\" alt=\"\" width=\"673\" height=\"70\" \/><\/figure>\r\n\r\n\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">Testing HRA<\/h3>\r\n\r\n\r\n\r\n<ul>\r\n<li>Now to test HRA, I have created a &#8220;test.yaml&#8221; workflow. Remember that we have created RunnerDeployment above in which we defined labels, here they come in handy by mentioning them on the <strong>runs-on<\/strong> field.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<figure class=\"wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler\">\r\n<div class=\"wp-block-embed__wrapper\">https:\/\/gist.github.com\/vikas-bisht16\/868b9bf991c8245041b0fee46fa94086<\/div>\r\n<\/figure>\r\n\r\n\r\n\r\n<ul>\r\n<li>The above workflow works on the push-based events, you can customize your workflow accordingly.<\/li>\r\n\r\n\r\n\r\n<li>Now to invoke HRA, I have pushed changes multiple times into the Repo so that multiple actions would be triggered and thus enabling the HRA.<\/li>\r\n\r\n\r\n\r\n<li>After push found the below result, HRA&#8217;s <strong>DESIRED<\/strong> state has been changed from 1 to 4.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>kubectl get HorizontalRunnerAutoscaler -n actions-runner-system<\/code><\/pre>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-13472\" style=\"width: 670px; height: 68px;\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2023\/03\/hra_output_ex.png?w=698\" alt=\"\" width=\"670\" height=\"68\" \/><\/figure>\r\n\r\n\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n\r\n\r\n<ul>\r\n<li>Checking the number of runner pods,<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>kubectl get pod -n actions-runner-system | grep -i \"k8s-action-runner\"<\/code><\/pre>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-13474\" style=\"width: 668px; height: 92px;\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2023\/03\/pod_output.png?w=703\" alt=\"\" width=\"668\" height=\"92\" \/><\/figure>\r\n\r\n\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n\r\n\r\n<ul>\r\n<li>Checking the controller logs as well,<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>k logs -f actions-runner-controller-7c8756c587-np4tt -c manager -n actions-runner-system<\/code><\/pre>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-13477\" style=\"width: 750px; height: 42px;\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2023\/03\/hra_logs2.png?w=1024\" alt=\"\" width=\"750\" height=\"42\" \/><\/figure>\r\n\r\n\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\"><strong>Benefits of using Self-Hosted Runner<\/strong><\/h3>\r\n\r\n\r\n\r\n<ul>\r\n<li><strong>Improved Performance: <\/strong>By hosting your runners, you can ensure that the build and deployment processes are faster and more reliable, as you have complete control over the hardware and networking resources.<\/li>\r\n\r\n\r\n\r\n<li><strong>Increased Security:<\/strong> GitHub self-hosted runners can be configured to run on your own servers, which provides an extra layer of security compared to using shared runners. This helps to protect sensitive information and data in your workflows.<\/li>\r\n\r\n\r\n\r\n<li><strong>Customizable Environments:<\/strong> With self-hosted runners, you can create custom environments that match your exact needs, including specific software versions and configurations.<\/li>\r\n\r\n\r\n\r\n<li><strong>Cost-Effective:<\/strong> If you have a large number of workflows or use cases that require a lot of resources, self-hosted runners can be more cost-effective than using GitHub&#8217;s shared runners or <a href=\"https:\/\/opstree.com\/services\/cloud-engineering-services\/\" target=\"_blank\" rel=\"noopener\">cloud-based solutions<\/a>.<\/li>\r\n\r\n\r\n\r\n<li><strong>High Availability:<\/strong> With self-hosted runners, you can set up Horizontal Runner Autoscaler, which provides redundancy and high availability for your workflows.<\/li>\r\n\r\n\r\n\r\n<li><strong>Greater Control:<\/strong> Self-hosted runners give you complete control over the resources and environment used for your workflows, which can help you optimize performance and ensure that your builds and deployments run smoothly.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p>Overall, GitHub self-hosted runners offer greater flexibility, control, and customization options than using shared runners or cloud-based solutions. However, setting up and managing self-hosted runners requires additional effort and resources, so it&#8217;s essential to weigh the benefits against the costs and resources needed to maintain them.<\/p>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">Conclusion<\/h3>\r\n\r\n\r\n\r\n<p>In conclusion, the Actions Runner Controller with Self-Hosted Runner is a powerful tool that can help you improve your GitHub Actions workflows. It simplifies the management of runners by automating tasks such as the creation, scaling, and deletion of runners. It also provides an easy way to create and manage runners in a Kubernetes cluster. By using Actions Runner Controller with Self-Hosted Runner, you can take full advantage of the power of GitHub Actions while having full control over your infrastructure.<\/p>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\"><strong>References<\/strong><\/h3>\r\n\r\n\r\n\r\n<ul>\r\n<li><a href=\"https:\/\/github.com\/actions-runner-controller\/actions-runner-controller\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>https:\/\/github.com\/actions-runner-controller\/actions-runner-controller<\/strong><\/a><\/li>\r\n\r\n\r\n\r\n<li><a href=\"https:\/\/docs.github.com\/en\/actions\/learn-github-actions\/understanding-github-actions\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>https:\/\/docs.github.com\/en\/actions\/learn-github-actions\/understanding-github-actions<\/strong><\/a><\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p><strong>Blog Pundits: <strong>\u00a0<a href=\"https:\/\/opstree.com\/blog\/\/author\/shwetatyagiot\/\" target=\"_blank\" rel=\"noreferrer noopener\">Shweta Tyagi<\/a><\/strong> and <a href=\"https:\/\/opstree.com\/blog\/\/author\/sandeep7c51ad81ba\/\" target=\"_blank\" rel=\"noreferrer noopener\">Sandeep Rawat<\/a><\/strong><\/p>\r\n\r\n\r\n\r\n<p><b>Related Searches &#8211; <a href=\"https:\/\/opstree.com\/\">DevOps Solutions<\/a> | <a href=\"https:\/\/opstree.com\/aws-consulting-services\/\">AWS Consulting Services<\/a><\/b><\/p>\r\n\r\n\r\n\r\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\"><\/div>\r\n\r\n\r\n\r\n<ul class=\"wp-block-social-links aligncenter is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-1 wp-block-social-links-is-layout-flex\"><li class=\"wp-social-link wp-social-link-linkedin  wp-block-social-link\"><a href=\"https:\/\/www.linkedin.com\/company\/opstree-solutions\" class=\"wp-block-social-link-anchor\" target=\"_blank\" rel=\"noopener\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z\"><\/path><\/svg><span class=\"wp-block-social-link-label screen-reader-text\">LinkedIn<\/span><\/a><\/li>\r\n\r\n<li class=\"wp-social-link wp-social-link-youtube  wp-block-social-link\"><a href=\"https:\/\/www.youtube.com\/channel\/UCeLma6SpNYH7jjYKSBNSexw\" class=\"wp-block-social-link-anchor\" target=\"_blank\" rel=\"noopener\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z\"><\/path><\/svg><span class=\"wp-block-social-link-label screen-reader-text\">YouTube<\/span><\/a><\/li>\r\n\r\n<li class=\"wp-social-link wp-social-link-github  wp-block-social-link\"><a href=\"https:\/\/github.com\/OpsTree\" class=\"wp-block-social-link-anchor\" target=\"_blank\" rel=\"noopener\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z\"><\/path><\/svg><span class=\"wp-block-social-link-label screen-reader-text\">GitHub<\/span><\/a><\/li>\r\n\r\n<li class=\"wp-social-link wp-social-link-facebook  wp-block-social-link\"><a href=\"https:\/\/www.facebook.com\/opstree\" class=\"wp-block-social-link-anchor\" target=\"_blank\" rel=\"noopener\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z\"><\/path><\/svg><span class=\"wp-block-social-link-label screen-reader-text\">Facebook<\/span><\/a><\/li>\r\n\r\n<li class=\"wp-social-link wp-social-link-medium  wp-block-social-link\"><a href=\"https:\/\/medium.com\/buildpiper\" class=\"wp-block-social-link-anchor\" target=\"_blank\" rel=\"noopener\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M20.962,7.257l-5.457,8.867l-3.923-6.375l3.126-5.08c0.112-0.182,0.319-0.286,0.527-0.286c0.05,0,0.1,0.008,0.149,0.02 c0.039,0.01,0.078,0.023,0.114,0.041l5.43,2.715l0.006,0.003c0.004,0.002,0.007,0.006,0.011,0.008 C20.971,7.191,20.98,7.227,20.962,7.257z M9.86,8.592v5.783l5.14,2.57L9.86,8.592z M15.772,17.331l4.231,2.115 C20.554,19.721,21,19.529,21,19.016V8.835L15.772,17.331z M8.968,7.178L3.665,4.527C3.569,4.479,3.478,4.456,3.395,4.456 C3.163,4.456,3,4.636,3,4.938v11.45c0,0.306,0.224,0.669,0.498,0.806l4.671,2.335c0.12,0.06,0.234,0.088,0.337,0.088 c0.29,0,0.494-0.225,0.494-0.602V7.231C9,7.208,8.988,7.188,8.968,7.178z\"><\/path><\/svg><span class=\"wp-block-social-link-label screen-reader-text\">Medium<\/span><\/a><\/li>\r\n\r\n<li class=\"wp-social-link wp-social-link-twitter  wp-block-social-link\"><a href=\"https:\/\/twitter.com\/opstreedevops\" class=\"wp-block-social-link-anchor\" target=\"_blank\" rel=\"noopener\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M22.23,5.924c-0.736,0.326-1.527,0.547-2.357,0.646c0.847-0.508,1.498-1.312,1.804-2.27 c-0.793,0.47-1.671,0.812-2.606,0.996C18.324,4.498,17.257,4,16.077,4c-2.266,0-4.103,1.837-4.103,4.103 c0,0.322,0.036,0.635,0.106,0.935C8.67,8.867,5.647,7.234,3.623,4.751C3.27,5.357,3.067,6.062,3.067,6.814 c0,1.424,0.724,2.679,1.825,3.415c-0.673-0.021-1.305-0.206-1.859-0.513c0,0.017,0,0.034,0,0.052c0,1.988,1.414,3.647,3.292,4.023 c-0.344,0.094-0.707,0.144-1.081,0.144c-0.264,0-0.521-0.026-0.772-0.074c0.522,1.63,2.038,2.816,3.833,2.85 c-1.404,1.1-3.174,1.756-5.096,1.756c-0.331,0-0.658-0.019-0.979-0.057c1.816,1.164,3.973,1.843,6.29,1.843 c7.547,0,11.675-6.252,11.675-11.675c0-0.178-0.004-0.355-0.012-0.531C20.985,7.47,21.68,6.747,22.23,5.924z\"><\/path><\/svg><span class=\"wp-block-social-link-label screen-reader-text\">Twitter<\/span><\/a><\/li><\/ul>\r\n","protected":false},"excerpt":{"rendered":"<p>GitHub Actions is a powerful CI\/CD tool that lets developers build, test, and deploy software through customizable workflows. It provides a managed infrastructure for executing tasks, but sometimes it&#8217;s necessary to use a self-hosted infrastructure. In this blog, we will detail how to set up and leverage self-hosted runners with GitHub Actions, aiming to optimize &hellip; <a href=\"https:\/\/opstree.com\/blog\/2023\/04\/18\/github-self-hosted-runner-on-kubernetes\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;GitHub: Self-Hosted Runner on Kubernetes &#8211; How to Setup&#8221;<\/span><\/a><\/p>\n","protected":false},"author":211160191,"featured_media":29900,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[28070474],"tags":[44070,460,768739308,676319247,5603054,768739309,4996032],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2025\/11\/DevSecOps-1.jpg","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pfDBOm-3ug","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/13408"}],"collection":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/users\/211160191"}],"replies":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/comments?post=13408"}],"version-history":[{"count":28,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/13408\/revisions"}],"predecessor-version":[{"id":30904,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/13408\/revisions\/30904"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media\/29900"}],"wp:attachment":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media?parent=13408"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/categories?post=13408"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/tags?post=13408"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}