Video Thumbnail for Lesson
4.1: Runner Types and Execution Environments

Runner types and execution environments

Every job must declare where it runs. The runs-on key determines the operating system, architecture, CPU, and memory available to your job, and you can layer on containers or custom labels to shape the environment further.

You have three broad options:

  • GitHub-hosted runners: turnkey Ubuntu, Windows, and macOS machines that are perfect for getting started or running open-source workloads that qualify for free minutes.
  • Third-party hosted runners: companies such as Namespace host high-performance runners that often deliver faster builds at a lower cost. They frequently add quality-of-life features like fleet observability and built-in caching.
  • Self-hosted runners: you operate the underlying compute yourself (for example with the Actions Runner Controller on Kubernetes or tools like RunsOn). This unlocks private-network execution at the cost of managing the infrastructure.

You can also run a job inside a container image while still using a hosted runner. That lets you layer in bespoke dependencies that aren't present on the stock images.

jobs:
  github-hosted-ubuntu-vm:
    name: Ubuntu 24.04 VM
    runs-on: ubuntu-24.04
    steps:
      - name: Show runner info
        run: |
          echo "Hello from ${{ runner.os }}-${{ runner.arch }}"
          echo "Runner name (type): ${{ runner.name }}"

  github-hosted-windows-vm:
    name: Windows 2022 VM
    runs-on: windows-2022
    steps:
      - name: Show runner info
        shell: pwsh
        run: |
          echo "Hello from ${{ runner.os }}-${{ runner.arch }}"
          echo "Runner name (type): ${{ runner.name }}"

  github-hosted-macos-vm:
    name: macOS 14 VM
    runs-on: macos-14
    steps:
      - name: Show runner info
        run: |
          echo "Hello from ${{ runner.os }}-${{ runner.arch }}"
          echo "Runner name (type): ${{ runner.name }}"

  alpine-container-on-github-hosted-ubuntu-vm:
    name: Alpine container on Ubuntu VM
    runs-on: ubuntu-24.04
    container:
      image: alpine:3.20
    steps:
      - name: Show runner info
        run: |
          echo "Hello from ${{ runner.os }}-${{ runner.arch }}"
          echo "Runner name (type): ${{ runner.name }}"
          echo "Container image:   $(grep PRETTY_NAME /etc/os-release)"

  ######################################
  #  3RD PARTY HOSTED RUNNERS
  ######################################
  #  There are companies which host GitHub Action runners that provide increased performance for less $$$
  # 
  #  One such company happens to be the sponsor of the course! 🙏
  # 
  #  ✨ Namespace ✨
  #
  #  You can likely cut your build times (and your CI bill) signiticantly by using their runners
  #  and it only takes changing a single line of yaml:
  #  
  #  - runs-on: ubuntu-24.04 
  #  + runs-on: namespace-profile-default # The default as of July 2025 is Ubuntu 22.04
  #
  #  (They also offer MacOS and Windows runners!)
  ######################################
  namespace-ubuntu-vm:
    name: Namespace Ubuntu VM
    runs-on: namespace-profile-default
    steps:
      - name: Show runner info
        run: |
          echo "Hello from ${{ runner.os }}-${{ runner.arch }}"
          echo "Runner name (type): ${{ runner.name }}"