Skip to main content

Managing Self-Hosted Runners

1. Installing Runner Application

Example: Install GitHub Actions Runner on Linux

# Download the latest runner package
curl -O -L https://github.com/actions/runner/releases/latest/download/runner-linux-x64-2.300.1.tar.gz

# Extract the package
tar xzf ./runner-linux-x64-2.300.1.tar.gz

# Configure the runner
./config.sh --url https://github.com/OWNER/REPO --token TOKEN

# Run the runner in the background
nohup ./run.sh && echo $! > pid.txt
Step Description Notes
Download Package curl -O -L https://github.com/actions/runner/releases/latest/download/runner-linux-x64-2.300.1.tar.gz Use the latest stable version for security
Extract Package tar xzf ./runner-linux-x64-2.300.1.tar.gz Ensure sufficient disk space for extraction
Configure Runner ./config.sh --url https://github.com/OWNER/REPO --token TOKEN Token must be generated from repo settings or organization
Run Runner nohup ./run.sh && echo $! > pid.txt Background process ensures continuous operation
Note: Ensure the runner has appropriate permissions and network access to communicate with GitHub.

2. Configuring Runner

Example: Runner Configuration File

name: my-runner
labels:
  - linux
  - x64
  - self-hosted
workflows: /home/user/actions-runner/_work
Property Description Default Value
name Unique identifier for the runner None
labels List of labels to assign to the runner None
workflows Path to the workflows directory /home/user/actions-runner/_work
Note: Runner labels must match the runs-on values in your workflow YAML files.
Warning: Ensure the runner has sufficient permissions to access required resources and execute workflows.

3. Running as Service

GitHub Actions self-hosted runners can be configured to run as a service on Linux systems, allowing them to start automatically when the system boots and manage their lifecycle without requiring manual intervention.

Configuration Description Notes
service name github-runner Name of the systemd service unit file
service file location /etc/systemd/system/github-runner.service Path where the service unit file is created
runner executable /home/runner/runners/2.300.0/run.sh Path to the runner executable (version may vary)

Example: systemd service configuration

[Unit]
Description=GitHub Actions Runner
After=network.target

[Service]
Type=simple
User=runner
WorkingDirectory=/home/runner/runners/<runner-name>
ExecStart=/home/runner/runners/<runner-name>/run.sh
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
Note: Ensure the runner user has appropriate permissions to execute the runner binary and access required resources.
Warning: The service must be configured to run as the same user that installed and registered the runner.

Service Management Commands

  • sudo systemctl daemon-reload — Reload systemd configuration after changes
  • sudo systemctl enable github-runner — Enable the service to start at boot
  • sudo systemctl start github-runner — Start the service manually
  • sudo systemctl status github-runner — Check current status of the service

4. Using Runner Labels

Label Description Usage
runner.label Assigns a label to a self-hosted runner
name: my-runner
runs-on: [self-hosted, my-label]
runner.group Groups runners under a label for organization
name: group-runner
runs-on: [self-hosted, group-label]

Example: Assigning Labels to Runners

name: Label Runner Example
on:
  push:
    branches: [ main ]
jobs:
  setup:
    runs-on: [ self-hosted, linux, x64 ]
    steps:
      - name: Setup Runner
        run: |
          echo "Runner configured with labels"
Note: Labels must be unique within a runner group and can include alphanumeric characters, hyphens, underscores, and periods.

5. Setting Up Runner Groups

Example: Create a Runner Group

gh runner-group create "my-runner-group" \
  --organization "my-org" \
  --labels "linux,ubuntu" \
  --visibility "all"
Option Values Description
--name runner-group-name Name of the runner group to create
--organization org-name Organization name to associate the group with
--labels label1,label2 Comma-separated list of labels for runners in this group
--visibility all | selected Who can use this runner group: all or selected
Note: Runner groups are scoped to organizations and can contain multiple runners. Labels help categorize runners for job assignment.

Example: Add a Runner to a Group

gh runner add-to-group "my-runner" \
  --runner-group "my-runner-group" \
  --organization "my-org"

Runner Group Management

  • Runner groups allow you to organize runners by labels and visibility.
  • Groups can be assigned to specific repositories or made available organization-wide.
  • Use gh runner-group commands to manage groups via CLI.

6. Configuring Proxy

Property Value Description
http_proxy http://proxy.example.com:8080 HTTP proxy URL for outbound requests
https_proxy http://proxy.example.com:8080 HTTPS proxy URL for outbound requests
no_proxy localhost,127.0.0.1,.local Comma-separated list of hosts to bypass proxy

Example: Setting proxy in runner configuration

runner:
  http_proxy: http://proxy.example.com:8080
  https_proxy: http://proxy.example.com:8080
  no_proxy: localhost,127.0.0.1,.local
Note: Proxy settings must be configured before starting the runner process.

7. Using Ephemeral Runners

Ephemeral runners are self-hosted runners that are automatically provisioned and destroyed for each job. They provide a clean, isolated environment for each workflow execution.

Property Description Default
runner.name Name of the runner instance Generated automatically
runner.id Unique identifier for the runner Generated automatically
runner.tags Tags to identify the runner in workflows None

Example: Configuring Ephemeral Runner

name: Ephemeral Runner Example
on:
  workflow_dispatch:

jobs:
  test:
    runs-on: [self-hosted, ephemeral]
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Run Test
        run: |
          echo "Running test on ephemeral runner"
Note: Ephemeral runners are ideal for CI/CD pipelines where each job requires a clean environment and no state persistence.
Warning: Ephemeral runners are not suitable for long-running jobs or those requiring persistent storage.

8. Setting Runner Work Directory

Property Value Description
work ./_work Directory where jobs are executed and artifacts are stored

Example: Configuring Work Directory

name: Example Workflow
on: [push]
jobs:
  build:
    runs-on: self-hosted
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          repository: my-repo
          path: ./custom-work-dir
Note: The work directory can be customized via the ACTIONS_RUNNER_WORK_DIRECTORY environment variable or by setting the work property in the runner configuration file.

9. Managing Runner Updates

Update Method Description Notes
Runner Version 2.300.0 Latest stable version as of 2026
Update Command ./config.sh --update Run from runner directory
Update Frequency As needed Recommended to update runners regularly for security

Example: Update Runner

# Navigate to runner directory
cd /home/user/runner

# Run update command
./config.sh --update
Note: Ensure runner is stopped before updating to prevent conflicts.
Warning: Updating runners may require reconfiguration if major version changes.
Update Type Impact Requirements
Minor Update Backward compatible Restart runner after update
Major Update May require config changes Reconfigure runner settings

10. Removing Runners

Runner Status Action
runner.name self-hosted-runner-01 Identifier for the runner instance
runner.id 12345 Unique ID assigned by GitHub
runner.status online Current operational state

Example: Remove a Self-Hosted Runner via API

curl -X DELETE \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer <token>" \
  https://api.github.com/actions/runners/12345
Note: The runner must be offline before deletion. If it's currently running a job, wait for the job to complete or cancel it first.
Warning: Deleting a runner permanently removes it from the organization or repository. Ensure all necessary data is backed up before proceeding.

11. Monitoring Runner Status

Example: Check runner status via API

curl -H "Authorization: Bearer <TOKEN>" \
  https://api.github.com/actions/runners?per_page=100
Field Description Example Value
id Unique identifier for the runner 12345
name Name of the runner my-runner-1
status Current status of the runner (online/offline) online
busy Whether the runner is currently executing a job false
os Operating system of the runner linux
Note: Runners must be registered with a valid token to appear in the API response.

Workflow: Monitor runner health

  1. Use curl to fetch runner list from GitHub API
  2. Parse JSON response for status and busy fields
  3. Alert if any runner is offline or stuck on a job longer than threshold

12. Cleaning Up After Jobs

Example: Using cleanup scripts in workflow

name: Cleanup Example
on: [push]

jobs:
  build:
    runs-on: self-hosted
    steps:
      - name: Setup
        run: echo "Setting up environment"
      
      - name: Run Job
        run: |
          echo "Running job tasks"
          # Simulate some work
      
      - name: Cleanup
        run: |
          echo "Cleaning up temporary files"
          rm -rf /tmp/temp-files
Step Description Action
Post-job cleanup Automatically clean up after each job completes rm -rf /tmp/*
Manual cleanup Explicitly define cleanup steps in workflow echo "Cleanup complete"
Note: Self-hosted runners may require additional permissions to clean up files in system directories.
Warning: Ensure cleanup steps do not interfere with other jobs running on the same runner.

Was this article helpful?