---
title: "Deploy Github Actions Runner"
description: "Runs your GitHub Actions workflow jobs on your own server"
category: "Other"
url: https://railway.com/deploy/github-actions-runner
---

# Deploy Github Actions Runner

Runs your GitHub Actions workflow jobs on your own server

**[Deploy Github Actions Runner on Railway](https://railway.com/template/github-actions-runner)**

- **Creator:** A3A
- **Category:** Other

## Template content

### runner https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/github-light.svg

- **Source:** https://github.com/gridalpha/github-actions-runner-railway

## Documentation

# Deploy and Host a GitHub Actions Self-Hosted Runner on Railway

Self-host GitHub Actions runners when hosted minutes stop being a good fit. A self-hosted runner is the same official agent GitHub ships, running on machines you control — you pick the CPU and memory, and jobs can reach private services a GitHub-hosted machine cannot. Teams reach for this when builds outgrow the minute allowance, when a job needs more RAM than a hosted runner offers, or when a deployment step must reach infrastructure that never touches the public internet.

Deploy GitHub Actions runners on Railway and the agent registers itself. This template runs GitHub's own `ghcr.io/actions/actions-runner` image with a startup script that fetches its registration from the GitHub API, so there is no expiring token to paste in. You supply a token and the repository or organisation to join; the container re-registers before each job and serves a private health endpoint reporting whether GitHub sees the runner online.

![Diagram of the single runner service on Railway](https://res.cloudinary.com/rroe4rtk/image/upload/v1787241234/github-actions-runner-architecture.png)

## Getting Started with GitHub Actions Runners on Railway

Before deploying, create the token. For a single repository, a classic token with `repo` scope works, or a fine-grained one with **Administration: read & write**. For an organisation runner, use `admin:org` or **Self-hosted runners: read & write**. Set it as `GITHUB_PAT` and `GITHUB_SCOPE` to `owner/repository` or just `owner` — a pasted GitHub URL also works.

There is no web interface to open, because a runner dials out to GitHub rather than accepting traffic. Confirm it on GitHub: open **Settings → Actions → Runners** on the repository or organisation you targeted and, within a minute, a runner named `railway-` plus a short identifier appears as **Idle** with the labels `self-hosted`, `linux`, `x64` and `railway`. If it never appears, read the deployment logs — a rejected token is reported plainly there, and the health check fails rather than reporting a healthy service doing nothing.

Once the runner is idle, point a workflow at it by setting `runs-on` to `self-hosted` or any label you configured. The quickest check is the **Runner self-test** workflow in the source repository: dispatch it from the Actions tab and it prints the runner name, operating system and the CPU and memory limits it sees, then checks out a repository and runs a build step. A green run whose log opens with `Runner name: 'railway-…'` proves the job ran on your Railway container.

![Three successful GitHub Actions runs on the self-hosted runner](https://res.cloudinary.com/rroe4rtk/image/upload/v1787241235/github-actions-runner-workflow-runs.png)
![Completed job steps including checkout and a build step](https://res.cloudinary.com/rroe4rtk/image/upload/v1787241235/github-actions-runner-job-summary.png)

## About Hosting GitHub Actions Runners

GitHub Actions runs workflows on machines called runners, and GitHub's own are metered by the minute. A self-hosted runner is the same agent — the open-source project at [github.com/actions/runner](https://github.com/actions/runner) — connected to your repository from hardware you provide. GitHub still queues jobs, matches them by label, streams logs and enforces permissions; only execution moves, and GitHub bills no minutes for it.

Key characteristics of this deployment:

- **Registers itself** by calling GitHub's API at startup for a just-in-time configuration.
- **Ephemeral by default** — a fresh registration per job and a cleared workspace, GitHub's recommended posture. Set `RUNNER_EPHEMERAL=false` for one long-lived registration.
- **Honest health reporting** — `/healthz` succeeds only while GitHub reports the runner online.
- **Finishes work before restarting**, so a redeploy does not kill a build mid-run.

The architecture is deliberately one service: a runner keeps no durable state, since `actions/cache` stores to GitHub rather than local disk.

## Why Deploy GitHub Actions Runners on Railway

Railway suits this workload well:

- No GitHub Actions minutes are consumed by jobs that run here
- More CPU and memory than the standard hosted runner, with a slider instead of a plan change
- Jobs can reach other Railway services over the private network
- Deploys straight from the source repository, so the runner image is yours to modify
- No servers to patch, and no runner agent to upgrade by hand

## Common Use Cases

- **Escaping minute limits** where a test suite runs on every push and burns the allowance.
- **Memory-hungry builds** — monorepo type-checking, Rust or C++ compiles, bundling that fails on a hosted runner.
- **Deployment jobs touching private infrastructure**, such as migrations against a private database.
- **Keeping source off third-party machines** where policy requires builds you control.

## Dependencies for GitHub Actions Runners

- `ghcr.io/actions/actions-runner:latest` — GitHub's official runner image, built on Ubuntu 24.04, shipping `git`, `curl`, `jq` and the agent.

No other services: job state lives on GitHub and artifacts upload there, so no database, cache or object storage is needed.

### Environment Variables Reference

| Variable | Required | Default | Description |
|---|---|---|---|
| `GITHUB_PAT` | Yes | — | Token used to register the runner |
| `GITHUB_SCOPE` | Yes | — | `owner/repository` or `owner` |
| `RUNNER_LABELS` | No | `self-hosted,linux,x64,railway` | Labels `runs-on` matches |
| `RUNNER_NAME_PREFIX` | No | `railway` | Prefix for the runner name |
| `RUNNER_EPHEMERAL` | No | `true` | Re-register before every job |
| `RUNNER_GROUP_ID` | No | `1` | Runner group ID; `1` is Default |
| `RUNNER_WORK` | No | `/home/runner/_work` | Working directory for jobs |
| `PORT` | No | `8080` | Port serving the health endpoint |

### Deployment Dependencies

- Source: [github.com/actions/runner](https://github.com/actions/runner)
- Docs: [docs.github.com — self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners)

## Hardware Requirements for Self-Hosting GitHub Actions Runners

The agent is light; your jobs decide the requirement. Size the service to the heaviest workflow you run.

| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 1 vCPU | 4–8 vCPU |
| RAM | 1 GB | 4–8 GB |
| Storage | Ephemeral | Ephemeral |
| Runtime | Ubuntu 24.04 container | Ubuntu 24.04 container |

An idle runner uses a few hundred megabytes, but a monorepo build or Rust compile can use several gigabytes. A job killed for running out of memory appears as an abruptly cancelled workflow rather than a clear error, so leave headroom.

## Self-Hosting GitHub Actions Runners

To run the agent yourself, download the release, register it and start it. These commands launch a runner on Linux:

```
mkdir actions-runner && cd actions-runner
curl -o runner.tar.gz -L https://github.com/actions/runner/releases/latest/download/actions-runner-linux-x64.tar.gz
tar xzf runner.tar.gz
./config.sh --url https://github.com/OWNER/REPOSITORY --token REGISTRATION_TOKEN
./run.sh
```

That registration token comes from **Settings → Actions → Runners → New self-hosted runner** and expires after an hour — the step this template removes.

To run the official image with Docker instead:

```
docker run -d --name gh-runner \
  -e RUNNER_NAME=local-runner \
  ghcr.io/actions/actions-runner:latest \
  ./run.sh --jitconfig ENCODED_JIT_CONFIG
```

## Is Self-Hosting GitHub Actions Free?

The agent is open source under the MIT licence, and GitHub charges nothing for jobs on self-hosted runners on any plan, including free accounts. You pay only infrastructure — on Railway, the compute and memory the service uses, billed by usage rather than build minute.

## Limitations of Running GitHub Actions on Railway

Railway containers run no Docker daemon and nothing privileged, so jobs using the `container:` or `services:` keys, or any `docker build` step, will fail. Language toolchain work — Node, Python, Go, Rust, Java, shell — runs normally, and `actions/checkout` and `actions/cache` work because both talk to GitHub.

GitHub advises attaching self-hosted runners to **private repositories only**: a pull request from a fork of a public repository can run its author's code on your runner. Ephemeral mode clears the workspace between jobs, but jobs share one filesystem, so untrusted code belongs on GitHub-hosted runners.

## FAQ

**What is a GitHub Actions self-hosted runner?**
The official agent that executes GitHub Actions workflow jobs on your own infrastructure instead of GitHub's. GitHub still schedules jobs and streams logs; only execution moves.

**What does this Railway template deploy?**
One service running GitHub's `ghcr.io/actions/actions-runner` image with a startup script that registers the runner automatically. No database and no volume, because a runner keeps no durable state.

**Why is there no database or storage service in this template?**
A runner persists nothing worth keeping — job definitions, logs, caches and artifacts all live on GitHub, so a volume would add no benefit and would block scaling out.

**How do I send a specific workflow to my self-hosted runner?**
Set the job's `runs-on` to `self-hosted`, or any other label in `RUNNER_LABELS`. Jobs left on `ubuntu-latest` keep running on GitHub-hosted machines and consuming minutes.

**Can I run more than one job at a time?**
Each container handles one job at a time. Run more copies of the service for concurrency, giving each a distinct `RUNNER_NAME_PREFIX` so names cannot collide.

## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

Open this page in a browser: https://railway.com/deploy/github-actions-runner
