<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Self-hosted runner manager for GitHub</title><link>https://an-lee.github.io/gh-sr/</link><description>Recent content on Self-hosted runner manager for GitHub</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://an-lee.github.io/gh-sr/index.xml" rel="self" type="application/rss+xml"/><item><title>Introduction</title><link>https://an-lee.github.io/gh-sr/introduction/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://an-lee.github.io/gh-sr/introduction/</guid><description>&lt;h1 id="introduction"&gt;Introduction&lt;a class="anchor" href="#introduction"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="the-problem"&gt;The Problem&lt;a class="anchor" href="#the-problem"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Self-hosted GitHub Actions runners give you more control over your CI/CD infrastructure — but managing them across multiple machines is tedious. To add a new runner you must SSH into each machine, download the runner software, configure it, start the process, and remember which machine has what. Monitoring, updating, and restarting runners means touching every machine individually. As the number of runners and machines grows, this overhead becomes unmanageable.&lt;/p&gt;</description></item><item><title>File Structure</title><link>https://an-lee.github.io/gh-sr/reference/file-structure/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://an-lee.github.io/gh-sr/reference/file-structure/</guid><description>&lt;h1 id="file-structure"&gt;File structure&lt;a class="anchor" href="#file-structure"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Layout of this repository (module &lt;code&gt;github.com/an-lee/gh-sr&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh-sr/ # repository root (GitHub: gh-sr)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cmd/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; gh-sr/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; main.go # CLI entry point (binary name: gh-sr; command: gh sr)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; internal/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; config/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; config.go # YAML config parsing and validation
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; envfile.go # ~/.gh-sr/env dotenv loader
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; paths.go # Config path resolution, ~/.gh-sr helpers
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; load.go # LoadFromPath with missing-file hints
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; template.go # Embedded template for gh sr init
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; runners.yml.template # Default runners.yml content
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; editor/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; editor.go # $VISUAL / $EDITOR / platform default
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; host/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; host.go # Host abstraction
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; connection.go # SSH connection management (Executor interface)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; local.go # Local command execution (addr: local)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; doctor/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; doctor.go # gh sr doctor diagnostics
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ops/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ops.go # Shared setup/up/down/restart/update/status/logs/cleanup (CLI + TUI)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; service.go # gh sr service install/uninstall/status
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; autostart/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; autostart.go # systemd / launchd / Windows task install and Detect/Start/Stop
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; active.go # Supervisor active check for gh sr status
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; generate.go # Unit and plist text generation
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sanitize.go # Safe names for unit files and tasks
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; runner/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; runner.go # Runner lifecycle orchestration
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; native.go # Native runner management (mac/win/linux)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; docker.go # Docker runner management
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; github.go # GitHub API client
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tui/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dashboard.go # Interactive TUI dashboard (model + update)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dashboard_view.go # TUI views and layout
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; status.go # Status table rendering
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; styles.go # Lipgloss styles
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; config/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; runners.yml # Example YAML (not auto-loaded; use GH_SR_CONFIG or -c)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; docs/ # Hugo source (this site)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; go.mod
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; go.sum&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Installation</title><link>https://an-lee.github.io/gh-sr/installation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://an-lee.github.io/gh-sr/installation/</guid><description>&lt;h1 id="installation"&gt;Installation&lt;a class="anchor" href="#installation"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="install-as-a-github-cli-extension-recommended"&gt;Install as a GitHub CLI extension (recommended)&lt;a class="anchor" href="#install-as-a-github-cli-extension-recommended"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Requires &lt;a href="https://cli.github.com/"&gt;GitHub CLI&lt;/a&gt; (&lt;code&gt;gh&lt;/code&gt;).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh extension install an-lee/gh-sr&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After installing, you invoke the tool as &lt;strong&gt;&lt;code&gt;gh sr&lt;/code&gt;&lt;/strong&gt;. Create config with &lt;strong&gt;&lt;code&gt;gh sr init&lt;/code&gt;&lt;/strong&gt; (see below).&lt;/p&gt;
&lt;h2 id="install-with-go"&gt;Install with Go&lt;a class="anchor" href="#install-with-go"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;go install github.com/an-lee/gh-sr/cmd/gh-sr@latest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This installs a binary named &lt;strong&gt;&lt;code&gt;gh-sr&lt;/code&gt;&lt;/strong&gt; on your &lt;code&gt;PATH&lt;/code&gt;. Use &lt;strong&gt;&lt;code&gt;gh sr&lt;/code&gt;&lt;/strong&gt; by installing the extension as above, or run &lt;code&gt;gh-sr&lt;/code&gt; directly.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;go install&lt;/code&gt; does not create config files. After installing, run:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr init&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This creates &lt;code&gt;~/.gh-sr/runners.yml&lt;/code&gt; from a template and &lt;code&gt;~/.gh-sr/env&lt;/code&gt; (optional dotenv for other tooling). Then edit the config (or use &lt;code&gt;gh sr config edit&lt;/code&gt;), run &lt;strong&gt;&lt;code&gt;gh auth login&lt;/code&gt;&lt;/strong&gt;, then &lt;code&gt;gh sr doctor&lt;/code&gt;. gh sr uses the GitHub CLI token only; see &lt;a href="authentication.md"&gt;Authentication&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Workflows</title><link>https://an-lee.github.io/gh-sr/guides/workflows/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://an-lee.github.io/gh-sr/guides/workflows/</guid><description>&lt;h1 id="using-runners-in-workflows"&gt;Using runners in workflows&lt;a class="anchor" href="#using-runners-in-workflows"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Reference runners by label in your workflow files:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;jobs&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;build-linux&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;runs-on&lt;/span&gt;: [&lt;span style="color:#ae81ff"&gt;self-hosted, Linux, X64]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;build-mac&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;runs-on&lt;/span&gt;: [&lt;span style="color:#ae81ff"&gt;self-hosted, macOS, ARM64]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;build-win&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;runs-on&lt;/span&gt;: [&lt;span style="color:#ae81ff"&gt;self-hosted, Windows, X64]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Labels must match what you configure under &lt;code&gt;runners[].labels&lt;/code&gt; in &lt;a href="../configuration.md"&gt;Configuration&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="github-agentic-workflows-gh-aw"&gt;GitHub Agentic Workflows (gh-aw)&lt;a class="anchor" href="#github-agentic-workflows-gh-aw"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;gh sr has first-class support for &lt;a href="https://github.github.com/gh-aw/"&gt;GitHub Agentic Workflows&lt;/a&gt;. Use &lt;code&gt;profile: agentic&lt;/code&gt; to configure a runner with all the prerequisites gh-aw needs:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;runners&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;aw-runner&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;repo&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;owner/repo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;host&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;vps-1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;profile&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;agentic&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;count&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This automatically sets docker mode, host networking, &lt;code&gt;NET_ADMIN&lt;/code&gt; capability, installs &lt;code&gt;iptables&lt;/code&gt; in the container for the Agent Workflow Firewall, and adds an &lt;code&gt;agentic&lt;/code&gt; label. See the &lt;a href="../host-setup.md#github-agentic-workflows-gh-aw"&gt;host setup docs&lt;/a&gt; for details.&lt;/p&gt;</description></item><item><title>Agentic Workflows</title><link>https://an-lee.github.io/gh-sr/guides/agentic-workflows/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://an-lee.github.io/gh-sr/guides/agentic-workflows/</guid><description>&lt;h1 id="agentic-workflows"&gt;Agentic Workflows&lt;a class="anchor" href="#agentic-workflows"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://github.github.com/gh-aw/guides/self-hosted-runners/"&gt;GitHub Agentic Workflows&lt;/a&gt; (gh-aw) run AI agents inside sandboxed Docker containers on self-hosted runners. Unlike normal Actions jobs that execute a fixed script, agentic workflows run a live AI model that decides what steps to take, what tools to call, and how to respond to errors.&lt;/p&gt;
&lt;h2 id="how-it-differs-from-normal-actions-workflows"&gt;How it differs from normal Actions workflows&lt;a class="anchor" href="#how-it-differs-from-normal-actions-workflows"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;Normal workflow&lt;/th&gt;
 &lt;th&gt;Agentic workflow&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Execution model&lt;/td&gt;
 &lt;td&gt;Fixed step sequence defined in YAML&lt;/td&gt;
 &lt;td&gt;AI agent decides steps dynamically&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Environment&lt;/td&gt;
 &lt;td&gt;Runs directly on the runner&lt;/td&gt;
 &lt;td&gt;Runs inside an isolated Docker container (sandbox)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Tool access&lt;/td&gt;
 &lt;td&gt;Via action steps&lt;/td&gt;
 &lt;td&gt;Via MCP (Model Context Protocol) servers&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Network&lt;/td&gt;
 &lt;td&gt;Runner&amp;rsquo;s network namespace&lt;/td&gt;
 &lt;td&gt;Separate &lt;code&gt;awf-net&lt;/code&gt; bridge; egress via Squid proxy&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;State&lt;/td&gt;
 &lt;td&gt;Persistent runner filesystem&lt;/td&gt;
 &lt;td&gt;chroot into host filesystem&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="architecture"&gt;Architecture&lt;a class="anchor" href="#architecture"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class="mermaid"&gt;graph TB
 subgraph HostNetwork [&amp;#34;Host Network Namespace (--network host)&amp;#34;]
 Runner[&amp;#34;GitHub Actions Runner&amp;lt;br/&amp;gt;process / container&amp;#34;]
 MCPGateway[&amp;#34;MCP Gateway&amp;lt;br/&amp;gt;ghcr.io/github/gh-aw-mcpg&amp;lt;br/&amp;gt;listens on :80&amp;#34;]
 end

 subgraph AWFNet [&amp;#34;awf-net (Docker bridge 172.30.0.0/16)&amp;#34;]
 AgentSandbox[&amp;#34;Agent Sandbox&amp;lt;br/&amp;gt;ghcr.io/github/gh-aw-firewall/agent&amp;lt;br/&amp;gt;chroot into host /&amp;#34;]
 SquidProxy[&amp;#34;Squid Proxy&amp;lt;br/&amp;gt;172.30.0.10:3128&amp;lt;br/&amp;gt;whitelisted domains only&amp;#34;]
 APIProxy[&amp;#34;Anthropic API Proxy&amp;lt;br/&amp;gt;172.30.0.30:10001&amp;#34;]
 end

 Runner --&amp;gt;|&amp;#34;1. Launch&amp;#34;| AgentSandbox
 Runner --&amp;gt;|&amp;#34;2. Start MCP gateway&amp;#34;| MCPGateway
 AgentSandbox --&amp;gt;|&amp;#34;3. MCP calls via&amp;lt;br/&amp;gt;host.docker.internal:80&amp;#34;| MCPGateway
 AgentSandbox --&amp;gt;|&amp;#34;4. All HTTP/HTTPS&amp;lt;br/&amp;gt;via HTTPS_PROXY&amp;#34;| SquidProxy
 AgentSandbox --&amp;gt;|&amp;#34;5. Model API calls&amp;lt;br/&amp;gt;via HTTPS_PROXY&amp;#34;| APIProxy
 SquidProxy --&amp;gt;|&amp;#34;allowed domains only&amp;#34;| Internet[&amp;#34;External APIs&amp;lt;br/&amp;gt;github.com&amp;lt;br/&amp;gt;api.minimaxi.com&amp;#34;]
 APIProxy --&amp;gt;|&amp;#34;upstream API&amp;#34;| Internet&lt;/pre&gt;&lt;h3 id="components"&gt;Components&lt;a class="anchor" href="#components"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Runner&lt;/strong&gt; &amp;ndash; The GitHub Actions runner process. It registers with GitHub, receives job assignments, and orchestrates the workflow. For agentic workflows it is responsible for starting the MCP Gateway and Agent Sandbox containers.&lt;/p&gt;</description></item><item><title>Common Tasks</title><link>https://an-lee.github.io/gh-sr/guides/common-tasks/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://an-lee.github.io/gh-sr/guides/common-tasks/</guid><description>&lt;h1 id="common-tasks"&gt;Common tasks&lt;a class="anchor" href="#common-tasks"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="add-a-new-host"&gt;Add a new host&lt;a class="anchor" href="#add-a-new-host"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Add an entry under &lt;code&gt;hosts&lt;/code&gt; in your resolved config file (&lt;code&gt;~/.gh-sr/runners.yml&lt;/code&gt; by default)&lt;/li&gt;
&lt;li&gt;Ensure SSH key-based access works: &lt;code&gt;ssh user@host true&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add runner entries referencing the new host&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;gh sr setup &amp;amp;&amp;amp; gh sr up&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="scale-up"&gt;Scale up&lt;a class="anchor" href="#scale-up"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Change &lt;code&gt;count&lt;/code&gt; in your runners YAML, then:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr setup &lt;span style="color:#75715e"&gt;# configures new instances&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr up &lt;span style="color:#75715e"&gt;# starts them&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="update-runner-version"&gt;Update runner version&lt;a class="anchor" href="#update-runner-version"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr update&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This removes existing runners, downloads the latest runner binary, reconfigures, and starts them.&lt;/p&gt;</description></item><item><title>Configuration</title><link>https://an-lee.github.io/gh-sr/configuration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://an-lee.github.io/gh-sr/configuration/</guid><description>&lt;h1 id="configuration"&gt;Configuration&lt;a class="anchor" href="#configuration"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="config-file-location"&gt;Config file location&lt;a class="anchor" href="#config-file-location"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you do &lt;strong&gt;not&lt;/strong&gt; pass &lt;code&gt;--config&lt;/code&gt; / &lt;code&gt;-c&lt;/code&gt;, the config file is chosen in this order:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;GH_SR_CONFIG&lt;/code&gt;&lt;/strong&gt; — path to a YAML file (absolute or relative to the current working directory).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;~/.gh-sr/runners.yml&lt;/code&gt;&lt;/strong&gt; — default after &lt;code&gt;gh sr init&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There is no automatic discovery of &lt;code&gt;./config/runners.yml&lt;/code&gt; in the current directory; use &lt;code&gt;GH_SR_CONFIG&lt;/code&gt; or &lt;code&gt;-c&lt;/code&gt; if your file lives elsewhere.&lt;/p&gt;
&lt;p&gt;If you pass &lt;code&gt;-c /path/to/runners.yml&lt;/code&gt;, that path is always used (and &lt;code&gt;GH_SR_CONFIG&lt;/code&gt; is ignored).&lt;/p&gt;</description></item><item><title>Authentication</title><link>https://an-lee.github.io/gh-sr/authentication/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://an-lee.github.io/gh-sr/authentication/</guid><description>&lt;h1 id="authentication"&gt;Authentication&lt;a class="anchor" href="#authentication"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;gh sr&lt;/strong&gt; uses the &lt;a href="https://cli.github.com/"&gt;GitHub CLI&lt;/a&gt; for GitHub API authentication only. Install &lt;strong&gt;gh&lt;/strong&gt; and sign in:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh auth login&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;gh sr&lt;/strong&gt; reads the token from gh&amp;rsquo;s stored credentials (via the same mechanism as other &lt;code&gt;gh&lt;/code&gt; extensions). This also handles token refresh. For GitHub Enterprise Server, use &lt;code&gt;gh auth login --hostname enterprise.example.com&lt;/code&gt; (API hostname support in gh sr follows &lt;strong&gt;gh&lt;/strong&gt;; the default is &lt;code&gt;github.com&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Do not set &lt;strong&gt;&lt;code&gt;github.pat&lt;/code&gt;&lt;/strong&gt; in &lt;code&gt;runners.yml&lt;/code&gt; or &lt;strong&gt;&lt;code&gt;GITHUB_PAT&lt;/code&gt;&lt;/strong&gt; / &lt;strong&gt;&lt;code&gt;GITHUB_TOKEN&lt;/code&gt;&lt;/strong&gt; for gh sr — those paths are removed. If your config still contains &lt;code&gt;github.pat&lt;/code&gt;, loading will fail with an error until you remove it.&lt;/p&gt;</description></item><item><title>Local Host</title><link>https://an-lee.github.io/gh-sr/guides/local-host/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://an-lee.github.io/gh-sr/guides/local-host/</guid><description>&lt;h1 id="local-host-runners"&gt;Local host runners&lt;a class="anchor" href="#local-host-runners"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;You can set up runners on the same machine where &lt;strong&gt;gh sr&lt;/strong&gt; runs, without SSH. Set &lt;code&gt;addr: local&lt;/code&gt; on a host and &lt;strong&gt;gh sr&lt;/strong&gt; will execute commands directly via &lt;code&gt;os/exec&lt;/code&gt; instead of dialing an SSH connection.&lt;/p&gt;
&lt;p&gt;When &lt;code&gt;addr&lt;/code&gt; is &lt;code&gt;local&lt;/code&gt;, the &lt;code&gt;os&lt;/code&gt; and &lt;code&gt;arch&lt;/code&gt; fields are &lt;strong&gt;auto-detected&lt;/strong&gt; from the Go runtime (&lt;code&gt;runtime.GOOS&lt;/code&gt; / &lt;code&gt;runtime.GOARCH&lt;/code&gt;) and can be omitted. You can still set them explicitly to override.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;hosts&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;my-laptop&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;addr&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;local&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;runners&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;my-local-runner&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;repo&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;owner/repo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;host&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;my-laptop&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;count&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;labels&lt;/span&gt;: [&lt;span style="color:#ae81ff"&gt;self-hosted, Linux, X64]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;mode&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;native&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Both &lt;code&gt;native&lt;/code&gt; and &lt;code&gt;docker&lt;/code&gt; modes work with local hosts. Docker mode requires Docker to be installed and accessible to the current user.&lt;/p&gt;</description></item><item><title>Host Setup</title><link>https://an-lee.github.io/gh-sr/host-setup/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://an-lee.github.io/gh-sr/host-setup/</guid><description>&lt;h1 id="host-setup-manual-steps"&gt;Host setup (manual steps)&lt;a class="anchor" href="#host-setup-manual-steps"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;gh sr&lt;/strong&gt; automates runner installation and lifecycle over SSH, but some host preparation is still manual. After you edit config, run &lt;strong&gt;&lt;code&gt;gh sr doctor&lt;/code&gt;&lt;/strong&gt; from your laptop to verify config paths, GitHub API access, SSH connectivity, and per-host tools (Docker vs native). By default the command exits with a non-zero status only when a check is &lt;strong&gt;FAIL&lt;/strong&gt;; use &lt;strong&gt;&lt;code&gt;gh sr doctor --strict&lt;/code&gt;&lt;/strong&gt; if you also want &lt;strong&gt;WARN&lt;/strong&gt; lines to fail (for example in CI).&lt;/p&gt;</description></item><item><title>Linux on Windows</title><link>https://an-lee.github.io/gh-sr/guides/linux-on-windows/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://an-lee.github.io/gh-sr/guides/linux-on-windows/</guid><description>&lt;h1 id="linux-runners-on-a-windows-host"&gt;Linux runners on a Windows host&lt;a class="anchor" href="#linux-runners-on-a-windows-host"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;You can run Linux container runners on a Windows machine without a separate SSH endpoint into WSL2. Set &lt;code&gt;mode: docker&lt;/code&gt; on a runner that targets an &lt;code&gt;os: windows&lt;/code&gt; host and &lt;strong&gt;gh sr&lt;/strong&gt; will manage the Docker container over the same SSH connection (Docker CLI invoked through the same encoded PowerShell path as native Windows runners).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Requirements on the Windows host:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OpenSSH Server enabled (see &lt;a href="../host-setup.md#windows-openssh-and-docker"&gt;Host setup — Windows&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Docker Desktop installed and running with the default Linux containers mode&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;hosts&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;win-pc&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;addr&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;user@192.168.1.51&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;os&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;windows&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;arch&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;amd64&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;runners&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Native Windows runner&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;myapp-win&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;repo&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;owner/repo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;host&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;win-pc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;labels&lt;/span&gt;: [&lt;span style="color:#ae81ff"&gt;self-hosted, Windows, X64]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Linux runner via Docker Desktop on the same Windows host&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;myapp-linux&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;repo&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;owner/repo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;host&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;win-pc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;mode&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;docker&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;labels&lt;/span&gt;: [&lt;span style="color:#ae81ff"&gt;self-hosted, Linux, X64]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Same Linux runner, tuned for GitHub Agentic Workflows (MCP gateway + awf firewall)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;myapp-linux-agentic&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;repo&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;owner/repo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;host&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;win-pc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;mode&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;docker&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;docker_network_mode&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;host&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;docker_cap_add&lt;/span&gt;: [&lt;span style="color:#ae81ff"&gt;NET_ADMIN]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;labels&lt;/span&gt;: [&lt;span style="color:#ae81ff"&gt;self-hosted, Linux, X64]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Both runners share a single SSH connection to Windows. The native runner starts &lt;code&gt;run.cmd&lt;/code&gt; via PowerShell; the Docker runner calls &lt;code&gt;docker run&lt;/code&gt; the same way, which talks to Docker Desktop&amp;rsquo;s Linux engine.&lt;/p&gt;</description></item><item><title>Commands</title><link>https://an-lee.github.io/gh-sr/commands/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://an-lee.github.io/gh-sr/commands/</guid><description>&lt;h1 id="commands"&gt;Commands&lt;a class="anchor" href="#commands"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Running &lt;strong&gt;&lt;code&gt;gh sr&lt;/code&gt; with no subcommand&lt;/strong&gt; opens the interactive dashboard on a &lt;strong&gt;TTY&lt;/strong&gt; (same as &lt;code&gt;gh sr dashboard&lt;/code&gt;). If stdout is not a terminal (for example in a pipe or CI), gh sr prints a short hint to stderr and exits successfully; use &lt;code&gt;gh sr status&lt;/code&gt; or &lt;code&gt;gh sr --help&lt;/code&gt; in those environments.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr &lt;span style="color:#75715e"&gt;# Open dashboard (TTY only; see above)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr init &lt;span style="color:#f92672"&gt;[&lt;/span&gt;--force&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#75715e"&gt;# Create ~/.gh-sr with template runners.yml and env file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr doctor &lt;span style="color:#f92672"&gt;[&lt;/span&gt;--strict&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#75715e"&gt;# Check config, GitHub API, and host prerequisites&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr setup &lt;span style="color:#f92672"&gt;[&lt;/span&gt;names...&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#75715e"&gt;# Install runner binary and configure on hosts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr up &lt;span style="color:#f92672"&gt;[&lt;/span&gt;names...&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#75715e"&gt;# Start runners&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr down &lt;span style="color:#f92672"&gt;[&lt;/span&gt;names...&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#75715e"&gt;# Stop runners&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr restart &lt;span style="color:#f92672"&gt;[&lt;/span&gt;names...&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#75715e"&gt;# Stop then start&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr status &lt;span style="color:#75715e"&gt;# Show status table&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr hosts &lt;span style="color:#75715e"&gt;# Show host resource usage (CPU, memory, disk, load, uptime)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr logs &amp;lt;name&amp;gt; &lt;span style="color:#75715e"&gt;# Show recent logs from a runner&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr cleanup &lt;span style="color:#75715e"&gt;# Remove offline/ghost runners from GitHub&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr update &lt;span style="color:#f92672"&gt;[&lt;/span&gt;names...&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#75715e"&gt;# Update runner binary (remove + setup + start)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr service install &lt;span style="color:#f92672"&gt;[&lt;/span&gt;--system&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;names...&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#75715e"&gt;# Native: OS autostart (systemd / launchd / task)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr service uninstall &lt;span style="color:#f92672"&gt;[&lt;/span&gt;names...&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#75715e"&gt;# Remove gh sr-installed autostart&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr service status &lt;span style="color:#f92672"&gt;[&lt;/span&gt;names...&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#75715e"&gt;# Autostart + unit state (docker: policy note)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr config path &lt;span style="color:#75715e"&gt;# Print resolved config and ~/.gh-sr/env paths&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr config show &lt;span style="color:#75715e"&gt;# Print resolved configuration (token source summarized)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr config edit &lt;span style="color:#75715e"&gt;# Edit resolved runners.yml in $VISUAL / $EDITOR&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr config edit-env &lt;span style="color:#75715e"&gt;# Edit ~/.gh-sr/env in $VISUAL / $EDITOR&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr config validate &lt;span style="color:#75715e"&gt;# Validate config (exit 0 if OK)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh sr dashboard &lt;span style="color:#75715e"&gt;# Same as bare gh sr: launch interactive TUI dashboard&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The dashboard includes live status, per-runner actions (setup, up, down, restart, update, logs), global actions (doctor, cleanup, show/validate/edit config and env), and host/repo filters. Press &lt;code&gt;h&lt;/code&gt; to open the host metrics panel (CPU, memory, disk, load, uptime) or &lt;code&gt;?&lt;/code&gt; for the full key map.&lt;/p&gt;</description></item><item><title>Linux on macOS</title><link>https://an-lee.github.io/gh-sr/guides/linux-on-macos/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://an-lee.github.io/gh-sr/guides/linux-on-macos/</guid><description>&lt;h1 id="linux-runners-on-a-macos-host"&gt;Linux runners on a macOS host&lt;a class="anchor" href="#linux-runners-on-a-macos-host"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Set &lt;code&gt;mode: docker&lt;/code&gt; on a runner that targets an &lt;code&gt;os: darwin&lt;/code&gt; host to run the same Linux container image as on Linux. &lt;strong&gt;gh sr&lt;/strong&gt; does &lt;strong&gt;not&lt;/strong&gt; run the Linux Docker install script on macOS; install a Docker runtime yourself.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Requirements on the Mac:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Docker Desktop, OrbStack, or Colima installed, with &lt;code&gt;docker&lt;/code&gt; working in the environment where &lt;strong&gt;gh sr&lt;/strong&gt; runs commands (for example the same user over SSH).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Docker socket permissions:&lt;/strong&gt; macOS runtimes (Docker Desktop, OrbStack, Colima) expose a socket that is accessible to all processes — there is no host &lt;code&gt;docker&lt;/code&gt; group GID issue. gh sr skips &lt;code&gt;--group-add&lt;/code&gt; on macOS hosts. gh sr bind-mounts the Docker socket into the container at &lt;code&gt;/var/run/docker.sock&lt;/code&gt; so jobs can reach the Docker daemon. If &lt;code&gt;docker_socket&lt;/code&gt; is unset, gh sr picks &lt;code&gt;/var/run/docker.sock&lt;/code&gt; when present, otherwise the &lt;code&gt;unix://&lt;/code&gt; path from your default Docker context (typical for Colima), otherwise &lt;code&gt;~/.colima/default/docker.sock&lt;/code&gt; on macOS. &lt;strong&gt;Colima + virtiofs:&lt;/strong&gt; when the resolved path is under &lt;code&gt;~/.colima/…&lt;/code&gt;, gh sr uses &lt;code&gt;/var/run/docker.sock&lt;/code&gt; as the bind-mount source for the runner container (VM path), not the macOS host socket file, to avoid &lt;code&gt;docker run&lt;/code&gt; failing with &lt;code&gt;operation not supported&lt;/code&gt; (&lt;a href="https://github.com/abiosoft/colima/issues/997"&gt;Colima #997&lt;/a&gt;); you can also use &lt;code&gt;colima start --mount-type sshfs&lt;/code&gt; if needed. Set &lt;code&gt;docker_socket&lt;/code&gt; only when the default Docker context does not match the engine you want (e.g. a named Colima profile):&lt;/p&gt;</description></item><item><title>Architecture</title><link>https://an-lee.github.io/gh-sr/architecture/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://an-lee.github.io/gh-sr/architecture/</guid><description>&lt;h1 id="architecture"&gt;Architecture&lt;a class="anchor" href="#architecture"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This page explains where runners run, how &lt;strong&gt;gh sr&lt;/strong&gt; reaches each host, and how &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;dashboard&lt;/code&gt;, and &lt;code&gt;logs&lt;/code&gt; collect information.&lt;/p&gt;
&lt;h2 id="control-plane-vs-execution-plane"&gt;Control plane vs execution plane&lt;a class="anchor" href="#control-plane-vs-execution-plane"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;gh sr&lt;/strong&gt; is a &lt;strong&gt;control plane&lt;/strong&gt; only: it runs on your machine and issues commands. The &lt;strong&gt;GitHub Actions runner&lt;/strong&gt; (native process or Docker container) always runs on the &lt;strong&gt;target host&lt;/strong&gt; from your config—either the same machine as &lt;strong&gt;gh sr&lt;/strong&gt; when &lt;code&gt;addr: local&lt;/code&gt;, or a remote machine over SSH.&lt;/p&gt;</description></item></channel></rss>