Skip to main content

Migrating from self-hosted runners to GitHub-hosted runners

Learn how to assess your current CI infrastructure and migrate workflows from self-hosted runners to GitHub-hosted runners.

You can run workflows on GitHub-hosted or self-hosted runners, or use a mixture of runner types.

This tutorial shows you how to assess your current use of runners, then migrate workflows from self-hosted runners to GitHub-hosted runners efficiently.

1. Assess your current CI infrastructure

Migrating from self-hosted runners to GitHub-hosted larger runners begins with a thorough assessment of your current CI infrastructure. If you take the time to match specifications and environments carefully, you will minimize the time spent fixing problems when you start running workflows on different runners.

  1. Create an inventory of each machine specification used to run workflows, including CPU cores, RAM, storage, chip architecture, and operating system.
  2. Note if any of the runners are part of a runner group or have a label. You can use this information to simplify migration of workflows to new runners.
  3. Document any custom images and pre-installed dependencies that workflows rely on, as these will influence your migration strategy.
  4. Identify which workflows currently target self-hosted runners, and why. For example, in GitHub Actions usage metrics, use the Jobs tab and filter by runner label (such as self-hosted or a custom label) to see which repositories and jobs are using that label. If you need to validate specific workflow files, you can also use code search to find workflow files that reference runs-on: self-hosted or other self-hosted labels.
  5. Identify workflows that access private network resources (for example, internal package registries, private APIs, databases, or on-premises services), since these may require additional networking configuration.

2. Map your processing requirements to GitHub-hosted runner types

GitHub offers managed runners in multiple operating systems—Linux, Windows, and macOS—with options for GPU-enabled machines. See Referencia de ejecutores de mayor capacidad.

  1. Map each distinct machine specification in your inventory to a suitable GitHub-hosted runner specification.
  2. Make a note of any self-hosted runners where there is no suitable GitHub-hosted runner.
  3. Exclude any workflows that must continue to run on self-hosted runners from your migration plans.

3. Estimate capacity requirements

Before you provision GitHub-hosted runners, estimate how much compute capacity your workflows will need. Reviewing your current self-hosted runner usage helps you choose appropriate runner sizes, set concurrency limits, and forecast potential cost changes.

  1. En la esquina superior derecha de GitHub, haz clic en la foto del perfil y luego en Your organizations.

  2. Haz clic en el nombre de tu organización.

  3. Debajo del nombre de la organización, haz clic en Insights.

    Captura de pantalla de la barra de navegación horizontal de una organización. Una pestaña, etiquetada con un icono de grafo e "Información", está resaltada en naranja oscuro.

  4. In the "Insights" navigation menu, click Actions Usage Metrics.

  5. Click on the tab that contains the metrics you would like to view. See Acerca de las métricas de GitHub Actions.

  6. Review the following data points to estimate hosted runner capacity:

    • Total minutes consumed: Helps you estimate baseline compute demand.
    • Number of workflow runs: Identifies peak activity times that may require more concurrency.
    • Job distribution across OS types: Ensures you provision the right mix of Linux, Windows, and macOS runners.
    • Runner labels (Jobs tab): Filter by a runner label to understand where a label is used.
  7. Convert your findings into a capacity plan:

    • Match high-usage workflows to larger runner sizes where appropriate.
    • Identify workflows that may benefit from pre-built or custom images to reduce runtime.
    • Estimate concurrency by determining how many jobs typically run simultaneously.
  8. Make a note of any gaps:

    • Workflows with hard dependencies your current hosted runner images do not support.
    • Jobs with unusually long runtimes or bespoke environment needs. (You may need custom images for these.)

Your capacity plan will guide how many runners to provision, which machine types to use, and how to configure runner groups and policies in the next steps.

4. Configure runner groups and policies

After estimating your capacity needs, configure runner groups and access policies so your GitHub-hosted runners are available to the right organizations and workflows.

Configuring runner groups before provisioning runners helps ensure that migration doesn’t accidentally open access too broadly or create unexpected cost increases.

  1. Create runner groups at the enterprise level to define who can use your hosted runners. See Control del acceso a los ejecutores más grandes.

    Use runner groups to scope access by organization, repository, or workflow. If you are migrating from self-hosted runners, consider reusing existing runner group names or labels where possible. This allows workflows to continue working without changes when you switch to GitHub-hosted runners.

  2. Add new GitHub-hosted runners to the appropriate group and set concurrency limits based on the usage patterns you identified in step 3. For details on automatic scaling, see Administración de ejecutores más grandes.

  3. Review policy settings to ensure runners are only used by the intended workflows. For example, restricting use to specific repositories or preventing untrusted workflows from accessing more powerful machine types.

Nota:

macOS larger runners cannot be added to runner groups and must be referenced directly in your workflow files.

5. Set up GitHub-hosted runners

Next, provision your GitHub-hosted runners based on the machine types and capacity you identified earlier.

  1. Choose the machine size and operating system that match your workflow requirements. For available images and specifications, see Referencia de ejecutores de mayor capacidad.

  2. Assign each runner to a runner group and configure concurrency limits to control how many jobs can run at the same time.

  3. Select an image type:

    • Use GitHub-managed images for a maintained, frequently updated environment.
    • Use custom images when you need pre-installed dependencies to reduce setup time. See Uso de imágenes personalizadas.
  4. Apply any required customizations, such as environment variables, software installation, or startup scripts. For more examples, see Personalizar los ejecutores hospedados en GitHub.

  5. Optionally, configure private networking if runners must access internal resources. See Redes privadas con ejecutores hospedados en GitHub.

Configure private connectivity options

If your workflows need access to private resources (for example, internal package registries, private APIs, databases, or on-premises services), choose an approach that fits your network and security requirements.

Configure Azure Private Networking

Run GitHub-hosted runners inside an Azure Virtual Network (VNET) for secure access to internal resources.

  1. Create an Azure Virtual Network (VNET) and configure subnets and network security groups for your runners.
  2. Enable Azure private networking for your runner group. See Configuración de redes privadas para los ejecutores hospedados en GitHub en su empresa
  3. Apply network configuration, such as NSGs and firewall rules, to control ingress and egress traffic.
  4. Update workflow targeting to use the runner group that is configured for private networking.

For detailed instructions, see:

Connect using a WireGuard overlay network

If Azure private networking is not applicable (for example, because your target network is on-premises or in another cloud), you can use a VPN overlay such as WireGuard to provide network-level access to private resources.

For detailed instructions and examples, see Uso de WireGuard para crear una superposición de red.

Use OIDC with an API gateway for trusted access to private resources

If you don’t need the runner to join your private network, you can use OIDC to establish trusted, short-lived access to a service you expose via an API gateway. This approach can reduce the need for long-lived secrets and limits network access to the specific endpoints your workflow needs.

For detailed instructions and examples, see Usar una puerta de enlace de API con OIDC.

6. Update workflows to use the new runners

After your GitHub-hosted runners are configured, update your workflow files to target them.

  1. Reuse existing labels if you assigned your new runners to the same runner group names your self-hosted runners used. In this case, workflows will automatically use the new runners without changes.

  2. If you created new runner groups or labels, update the runs-on field in your workflow YAML files. For example:

    jobs:
      build:
        runs-on: [github-larger-runner, linux-x64]
        steps:
          - name: Checkout code
            uses: actions/checkout@v5
          - name: Build project
            run: make build
    
  3. Check for hard-coded references to self-hosted labels (such as self-hosted, linux-x64, or custom labels) and replace them with the appropriate GitHub-hosted runner labels.

  4. Test each updated workflow to ensure it runs correctly on the new runners. Monitor for any issues related to environment differences or missing dependencies.

7. Remove unused self-hosted runners

After your workflows have been updated and tested on GitHub-hosted runners, remove any self-hosted runners that are no longer needed. This prevents jobs from accidentally targeting outdated infrastructure. See Eliminar ejecutores autoalojados.

Before you remove self-hosted runners, verify that you have fully migrated:

  • In GitHub Actions usage metrics, use the Jobs tab and filter by runner label (for example, self-hosted or your custom labels) to confirm no repositories or jobs are still using self-hosted runners.