GitHub Actions Runner
A self-hosted GitHub Actions runner - your workflows on flat-price compute, zero per-minute billing.
One-click deploy, from $13/mo on a Miget plan.
GitHub Actions minutes are the quiet line item that grows with every push: $0.006/minute for Linux 2-core past the included quota, more for bigger machines. A self-hosted runner removes the meter - and gets you exactly the CPU, RAM, and caching behavior you choose.
This template uses the de-facto env-driven runner image with PAT-based auto-registration: set a token and a repo (or org), deploy, and the runner appears in Settings > Actions. Registration state persists across redeploys; EPHEMERAL mode plus replicas gives clean-slate scale-out.
The honest constraint, documented rather than discovered: run: steps and JS/composite actions work fully; container: jobs and Docker container actions need a daemon a PaaS does not expose - image builds go through kaniko or buildah instead.
Upstream project: actions/runner (via myoung34 image)
#what you get
- PAT-based auto-registration: deploy and it appears in GitHub
- Repo or org scope; custom labels for runs-on targeting
- Ephemeral mode + replicas for clean parallel runners
- Registration survives redeploys (state volume)
- No per-minute billing - the plan is the whole CI bill
- kaniko/buildah path documented for image builds
#topology
| Service | Role | Public |
|---|---|---|
| runner | Actions runner, outbound long-poll to GitHub | no - no ingress needed |
#miget sizing
// this stack needs
2 GiB RAM · 1 GB disk · 1 service
Size to your builds, not the runner (it idles under 100 MB). 2 GiB suits typical Node/Python/Go builds; compile-heavy jobs want the next plan up.
Hobby - recommended fit
$13/mo
1 vCPU · 2 GiB · 50 GiB disk
Headroom for your own apps: 2 GiB at $19/mo
Professional - production
$22/mo
1 vCPU · 2 GiB · 10 GiB disk
Dedicated resources, production SLOs - plan details
One Miget plan is a fixed pool of compute - the whole stack (managed databases included) deploys inside it, and anything left over runs your other apps. No per-service or per-seat math.
#vs. the managed service
What the hosted equivalents charge, against the flat Miget plan this stack fits on. Prices as of June 2026, sources linked.
| Service | Plan | Monthly | What you get |
|---|---|---|---|
| GitHub Actions Runner on Miget ★ | 2 GiB plan | $13 | this whole stack, flat - no usage meters, and room left for your own apps |
| GitHub Actions | hosted runners | usage-based | $0.006/min Linux 2-core past included minutes (2,000-3,000/mo on Free/Team) - 30k monthly minutes ≈ $165 overage |
Self-hosted runners are free on GitHub’s side; the announced per-minute fee for them was retracted in December 2025.
#vs. other PaaS
Estimated monthly cost of running this exact stack (2 GiB RAM, 1 GB disk, 1 container) elsewhere, from published June 2026 rates.
| Platform | Est. monthly | Notes |
|---|---|---|
| Miget ★ | $13 flat | compose stacks first-class: one deploy, dedicated vCPU, managed Postgres/Valkey, volumes and TLS all included in the plan |
| Heroku | ~$100 | no volumes; nothing between 1 GB ($50) and 2.5 GB ($250) dynos - 2 GB containers cost far more than shown |
| DO App Platform | ~$29 | no persistent volumes - stateful containers need managed DBs/Spaces (base $5 Spaces included here) |
| Render | ~$25 | per-service instances (0.5 GB $7, 2 GB $25) - every container is its own paid service |
| Railway | ~$20 | usage-based ($10/GB RAM-mo); vCPU billed separately at $20/vCPU-mo on top |
| Fly.io | ~$12 | cheapest sticker price - but burstable shared CPUs (1/16 core; dedicated vCPUs cost ~2-3×), no compose deploys (one app per container, manual wiring), managed DBs billed extra |
Estimates assume RAM fully allocated at published on-demand rates - and sticker price isn't the whole comparison: the cheaper rows buy burstable shared CPUs, per-service wiring instead of a compose deploy, and managed databases billed separately. Heroku and DO App Platform have no persistent volumes at all - stateful stacks like this one need workarounds there.
#deploy it
On Miget
- Create a Compose Stack in app.miget.com pointing at the templates repository
- Set the stack path to
github-runner -
Set the required variables:
ACCESS_TOKEN, PAT (repo scope for repo runners, admin:org for org runners)REPO_URL or ORG_NAME, where the runner registers (with RUNNER_SCOPE)
- Deploy. Miget layers
compose.miget.yaml(RAM, privacy, volumes, managed services) automatically
Locally first?
Every template is portable, vanilla Docker Compose - the Miget overrides are ignored locally:
git clone https://github.com/deployable-sh/stacks
cd miget-compose-templates/github-runner
docker compose up -d Same files, same behavior. The template README covers connection strings and scaling notes.
#faq
How much does this save vs hosted runners?
GitHub includes 2,000-3,000 minutes/month on Free/Team plans, then bills $0.006/min for Linux 2-core. A team burning 30,000 monthly minutes pays ~$165 in overage; this runner is $13/month flat at any volume - and you can give it more cores than the hosted 2-core default for the same price.
What workflows will NOT work on it?
Anything needing the Docker daemon: container: jobs, services: blocks (Postgres-in-CI style), and Docker container actions. The fixes are standard: native services (your project already runs real databases), kaniko/buildah for image builds, and JS-based actions which all work.
How do I run more jobs in parallel?
Set EPHEMERAL=true and raise replicas - each replica registers itself, takes one job, deregisters, repeats. Clean state per job, parallelism equal to replica count, all inside the same flat plan.
Is a PAT in env safe?
The token only mints runner registration tokens and lives server-side in your stack env. Use a fine-grained PAT scoped to the one repo/org, and rotate it like any credential. GitHub’s JIT-config flow exists for stricter setups; this template favors the simple, durable registration.
Ship GitHub Actions Runner today
One compose stack, 2 GiB of RAM, from $13/month flat, and it runs on your laptop with the same files.