Guide · GitHub Actions on bare metal · docs read 1 November 2026
How do I set up a self-hosted GitHub Actions runner on a rented dedicated server?
Register a runner on a rented Linux machine, run it as a service under its own user, and keep untrusted code away from it. Every command and rule below comes from GitHub's documentation.
How do I set up a self-hosted GitHub Actions runner on a rented dedicated server?
To set up a self-hosted GitHub Actions runner on a rented dedicated server, create a non-root user first. Then open Settings → Actions → Runners → New self-hosted runner and run the commands GitHub prints, then sudo ./svc.sh install to keep it running. Use it on private repositories only. Lumenfer servers start at $91.65 per 30 days, paid in crypto with no KYC.
What the runner needs, per GitHub's reference
Network
Outbound HTTPS on port 443 to github.com, api.github.com and *.actions.githubusercontent.com; at least 70 kbit/s each way
Linux systems
Ubuntu 20.04 or later and Red Hat Enterprise Linux 8 or later, among others, on x64
Container jobs
A Linux machine with Docker installed
Runner updates
Automatic when a job is assigned; you must update within 30 days of a new release
Job limits
Up to 5 days per job; a job queued for 24 hours is cancelled
Offline runners
Removed after 14 days without connecting; ephemeral runners after 1 day
Images at Lumenfer
Debian 13, Debian 12, Ubuntu 24.04 LTS, AlmaLinux 10, Rocky Linux 10 and Proxmox VE 9
Login
You log in as root over SSH. Paste a public key when ordering and password logins stay disabled, or skip it and receive a temporary root password with the server, to replace on your first login
Setup
Up to 72 hours from the moment your payment is confirmed
What do I need before installing the runner?
You need admin rights in GitHub and root on a Linux machine. For a repository runner, GitHub asks you to be the repository owner, an organization owner, or a repository admin. An organization-wide runner needs an organization owner.
On the server side, order an Ubuntu 24.04 LTS or Debian image with your SSH public key. Servers are prepared by a person once your payment is confirmed, within 72 hours rather than instantly; the dashboard shows progress and then the IP address when the machine is ready. The IP address appears in your dashboard when the machine is ready.
Pick the size from your heaviest job, not your average one. Our build server hardware guide explains how compilers and linkers use cores and memory.
Can I use a self-hosted runner on a public repository?
Avoid it: GitHub recommends self-hosted runners for private repositories only. Anyone can fork a public repository and open a pull request. That pull request can run code on your machine.
GitHub's security reference spells out the stakes. A runner can be persistently compromised by untrusted workflow code. That code can then reach secrets and the GITHUB_TOKEN. Environment secrets and required reviewers do not isolate the machine itself.
Restrict the token. Set the default GITHUB_TOKEN permission to read-only for repository contents, and grant more per job.
Avoid privileged triggers. Never combine pull_request_target or workflow_run with a checkout of untrusted pull-request code.
Group your runners. Organization runners can take jobs from many repositories. Runner groups keep a compromise inside one boundary.
Keep secrets off the disk. GitHub asks you to minimise sensitive material stored on the runner.
How do I install the runner, step by step?
These steps follow three GitHub Docs pages, on adding runners, running them as a service and using them in workflows, read on 1 November 2026. Each one runs over SSH.
Order the server with your SSH key
Choose Ubuntu 24.04 LTS or Debian at checkout and paste your public key. Password logins then stay disabled.
Update the system and add a runner user
Run apt update && apt full-upgrade, then create an unprivileged user such as gh-runner. Jobs should never run as root.
Install Docker only if jobs use containers
GitHub needs Docker on Linux for container actions and service containers. Docker's docs warn that the docker group grants root-level privileges.
Open the New self-hosted runner page
In the repository, go to Settings → Actions → Runners → New self-hosted runner, then pick Linux and x64. Organizations use New runner first.
Run GitHub's commands as the runner user
Paste the download, checksum and ./config.sh --url … --token … lines in the order shown. The registration token expires after one hour.
Install the runner as a service
From the runner folder, run sudo ./svc.sh install gh-runner, then sudo ./svc.sh start and sudo ./svc.sh status. It now survives reboots.
Point a workflow at it
Set runs-on: [self-hosted, linux, x64]. A runner must carry every listed label to take the job.
Lock down the repository settings
Make the GITHUB_TOKEN read-only by default and limit which repositories may use the runner. Then run a test job.
Steps 2, 5 and 6 on Ubuntu or Debian (URL and token come from your New runner page)
# step 2, as root: update and create the runner user
apt update && apt full-upgrade -y
adduser --disabled-password --gecos "" gh-runner
# step 5, as gh-runner, in the folder where you ran GitHub's download lines
./config.sh --url https://github.com/OWNER/REPO --token TOKEN
# for a runner that takes one job, then de-registers:
# ./config.sh --url https://github.com/OWNER/REPO --token TOKEN --ephemeral
# step 6, from the same folder, with sudo rights
sudo ./svc.sh install gh-runner
sudo ./svc.sh start
sudo ./svc.sh status
Step 7: a job that runs on the rented server
permissions:
contents: read
jobs:
build:
runs-on: [self-hosted, linux, x64]
steps:
- uses: actions/checkout@v7
- run: make -j"$(nproc)" test
Should I use ephemeral runners on one rented server?
Yes, for anything beyond trusted internal code: GitHub recommends ephemeral runners, which take one job and then de-register. Add --ephemeral when you run config.sh. Your own automation then wipes the workspace and registers a fresh runner.
GitHub also offers just-in-time runners. The REST endpoint POST /repos/{owner}/{repo}/actions/runners/generate-jitconfig returns a one-job configuration. For classic registration, POST /repos/{owner}/{repo}/actions/runners/registration-token returns a token valid for one hour.
One-job runners on the same physical host are not a clean slate. GitHub warns that re-using hardware for just-in-time runners can expose information from the environment. On bare metal, give each job a throwaway virtual machine or container instead.
Kubernetes. GitHub's Actions Runner Controller is a Kubernetes operator that scales self-hosted runners. See how to run Kubernetes on bare metal.
Logs. A one-job runner leaves nothing to inspect later, so GitHub asks you to forward its logs to external storage first.
How many runners can one server carry?
One runner process takes one job, so register as many runners as you want parallel jobs, each in its own folder with its own service. Divide the machine by your heaviest job. A common split is one runner per 4 to 8 threads, with RAM for the worst link step.
The table maps each plan to a sensible starting point. Adjust after a week of watching htop and job times.
Lumenfer plans as CI runner hosts
Swipe to see every column
Plan
CPU
Cores
Memory
Disks
Per 30 days
Good start
Lumen 6
AMD EPYC 4244P
6 cores / 12 threads
32 GB DDR5 ECC
2 × 960 GB NVMe
$91.65
1 to 2 runners: lint, unit tests, small services
Lumen 8
AMD Ryzen 7 9700X
8 cores / 16 threads
64 GB DDR5
2 × 1 TB NVMe
$109.37
2 to 4 runners: Go, Rust or Java builds
Lumen 16
AMD Ryzen 9 9950X
16 cores / 32 threads
128 GB DDR5
2 × 1.92 TB NVMe
$205.27
4 to 8 runners, or one large C++ build
Lumen 24
AMD EPYC 9254
24 cores / 48 threads
256 GB DDR5 ECC
2 × 1.92 TB NVMe
$356.25
Runner VMs under Proxmox, with ECC memory
Lumen 32
AMD EPYC 9354
32 cores / 64 threads
384 GB DDR5 ECC
2 × 3.84 TB NVMe
$749.67
A runner pool for a whole organization
What do GitHub-hosted runners handle that I now handle myself?
The clean machine, the updates and the recovery: GitHub makes you responsible for the operating system and all other software.
Disk growth. Workspaces, Docker images and caches pile up between jobs. Schedule a cleanup, or the NVMe fills during a release.
Runner updates. The runner updates itself when it gets a job. If you register with --disableupdate, you must still update within 30 days.
Lock-outs. There is no IPMI or KVM-over-IP console for customers: you request reboots and reinstalls in the dashboard and the team performs them. Test firewall changes with a second SSH session open.
Mail from builds. Outbound SMTP on port 25 is blocked on every server and is never unblocked; submission ports 465 and 587 to mail providers remain open.
Data. Backups are not included: keep copies of your data somewhere else.
In Lumenfer's check of 30 October 2026, dedicated-server sellers stated setup times from 30 minutes to 10 business days, with a median of 24 hours. Lumenfer is slower to start, with a person preparing each machine. Order before you need the capacity. Costs are compared minute by minute in self-hosted runner vs GitHub-hosted cost, and every plan is on the Lumenfer pricing page.
Which plan should host my runners?
Whole machines, one customer each, billed from a crypto balance. Amsterdam (Netherlands), Reykjavik (Iceland), Zurich (Switzerland) and Bucharest (Romania): all five plans in all four cities, one price everywhere.
In every plan: 2022+ CPU · DDR5 · NVMe only · RAID 1 · Dedicated IPv4 · No KYC
Self-hosted GitHub runner on a rented server: FAQ
Can I run the GitHub runner as root?
Do not. Create a dedicated user and install the service for it with sudo ./svc.sh install USERNAME, as GitHub's service page shows. A job running as root can change the host for every job after it, and for you.
Does the runner need any inbound ports?
GitHub's communication requirements list outbound HTTPS on port 443 to its domains, plus at least 70 kbit/s each way. Inbound, you can close everything except SSH. The runner opens every connection itself, outbound.
Can one server serve several repositories?
Yes, register the runner at organization level and assign it to a runner group. GitHub warns that organization runners can take jobs from many repositories, so a group limits how far a bad job reaches.
What happens if my server reboots or goes offline?
The service starts again after a reboot. Jobs wait in the queue and are cancelled after 24 hours. A runner that stays disconnected for more than 14 days is removed from GitHub and must be registered again.
Can I host GitLab runners or Jenkins agents the same way?
Yes. Any Linux CI agent runs on the server with root access. The security rules carry over: untrusted code gets a throwaway VM or container, never the host itself.
How do I pay, and do you need my identity?
No KYC: we never ask for an ID, a selfie, documents, a card or a phone number. Top up a balance in BTC, USDT, USDC, ETH, SOL, LTC (minimum $25) and order from it for 30 days, 3 months, 6 months or 12 months.