Migrate from Docker-Based Self-Hosted Runners to Managed Runners
Docker-based self-hosted runners give you clean, ephemeral builds - but you still own the Docker hosts, scaling, and image upkeep. Managed runners give you the same without the hosts.
A common self-hosted setup runs the GitHub runner inside a container on VMs you manage, often with docker-in-docker for builds. Managed runners are already ephemeral and isolated per job, so you keep the clean-build property and drop the host fleet.
What changes
| Docker self-hosted | Managed (Latchkey) |
|---|---|
runs-on: [self-hosted, docker] | runs-on: latchkey-medium |
| You run docker-in-docker on hosts | Container/Docker builds supported |
| You rebuild and ship runner images | Images maintained for you |
| You scale and clean up hosts | Warm pools + ephemeral cleanup |
Before and after
Before: .github/workflows/ci.yml
jobs:
build:
runs-on: [self-hosted, docker] # dind on your hosts
steps:
- uses: actions/checkout@v4
- run: docker build -t app .Managed equivalent
After: .github/workflows/ci.yml
jobs:
build:
runs-on: latchkey-medium # ephemeral, Docker-ready
steps:
- uses: actions/checkout@v4
- run: docker build -t app .Migration steps
- Identify workflows pinned to your Docker self-hosted labels.
- Swap
runs-on:to a managed label that supports Docker builds. - Confirm
docker build/ compose steps work, using Docker layer caching for speed. - Roll out, then decommission the Docker hosts.
Gotchas
- Replace host-shared Docker caches with the runner cache so builds stay fast.
- Privileged dind tricks may differ on managed runners - prefer standard
docker build. - Confirm registry auth uses GitHub secrets or OIDC, not a host-baked credential.
What you gain
- Roughly 69% lower per-minute cost than GitHub-hosted runners.
- Warm pools remove queue time - jobs start almost immediately.
- Self-healing detects, fixes, and auto-retries transient and mechanical failures.
- Zero ops: no agents, autoscalers, or controllers to patch and babysit.
Key takeaways
- Managed runners are already ephemeral and isolated per job.
- You keep clean Docker builds and drop the host fleet.
- Docker layer caching keeps build times fast.
Related guides
Migrate to Latchkey in 10 MinutesMove your GitHub Actions to Latchkey managed runners in about 10 minutes: connect the app, swap a label, and…
Migrate from Self-Hosted to Managed Runners (Drop the Ops)Retire self-hosted GitHub Actions runners for managed runners: keep the same workflows, drop the autoscaler a…
GitHub Actions Cost Calculator - Estimate & Cut Your CI BillFree GitHub Actions cost calculator: enter your monthly CI minutes and runner size to see your current bill a…
GitHub-Hosted vs Self-Hosted vs Managed Runners (2026)GitHub-hosted vs self-hosted vs managed GitHub Actions runners compared on cost, speed, maintenance, and reli…