Runners hospedados pelo GitHub são um bom padrão. Você para de precisar deles no momento em que um build quer algo que eles não têm — seu registro de pacotes privado, uma versão específica de toolchain que você está cansado de reinstalar a cada rodada, um banco de dados na sua própria rede, ou só mais controle sobre a máquina. É aí que um runner self-hosted num VPS ganha o seu lugar.
Este guia coloca um rodando adequadamente: instalado, registrado, vivo sob systemd e — a parte que as pessoas erram — seguro. Vamos começar por essa última, porque é a parte que morde.
A única regra de segurança
Um workflow do GitHub Actions roda código arbitrário — o que quer que esteja no arquivo de workflow, e o que quer que esse código puxe. No seu próprio repo isso é o seu código, e está bem. Num repo público, um pull request de um estranho pode rodar o código dele no seu runner. Isso não é um bug; é como o CI funciona. A própria documentação do GitHub diz claramente: não use runners self-hosted com repositórios públicos.
Então a regra é simples e inegociável: runners self-hosted são para repos privados. Se o seu repo é público, use runners hospedados pelo GitHub e siga em frente. Tudo abaixo pressupõe um repo privado.
O que um runner precisa da máquina
Depende do build, e você deve dimensionar para o seu em vez de um número de uma página:
- Um job típico de compilar-e-testar — 2 núcleos e 4-8 GB é confortável. Small (US$8, 4 vCPU / 4 GB) ou Medium (US$12, 6 vCPU / 6 GB) cobre a maioria desses.
- Builds mais pesados — grandes compilações nativas, grandes builds de imagem Docker, suítes de teste famintas por memória — querem mais folga. Observe uma rodada de verdade (
htopenquanto compila) e dimensione para o que você de fato vê, não para a esperança.
O disco também importa: caches de build, camadas Docker e repos clonados somam. Fique de olho e faça a poda.
1. Prepare a máquina
Crie um usuário não-root para o runner — o instalador do GitHub se recusa a rodar como root de qualquer forma, e você quer assim:
sudo adduser --disabled-password --gecos "" runner
sudo usermod -aG sudo runner # só se seus builds genuinamente precisam de sudo
Instale o que seus builds precisam — um toolchain de linguagem, Docker, ferramentas de build. Por exemplo, se seus jobs constroem containers:
sudo apt update && sudo apt install -y docker.io
sudo usermod -aG docker runner
2. Baixe e registre o runner
No seu repo (ou org) no GitHub, vá em Settings → Actions → Runners → New self-hosted runner. O GitHub te dá os comandos exatos de download e um token de registro (ele é de curta duração — pegue-o fresco). Como o usuário runner:
sudo -iu runner
mkdir actions-runner && cd actions-runner
# use a URL exata que o GitHub te mostra para o seu SO/arch:
curl -o actions-runner-linux-x64.tar.gz -L "URL_DO_GITHUB"
tar xzf actions-runner-linux-x64.tar.gz
./config.sh --url https://github.com/SEU_ORG/SEU_REPO --token SEU_TOKEN
O config.sh pede um nome de runner, labels e uma pasta de trabalho — os padrões servem para começar. As labels são como o seu workflow mira este runner (runs-on: self-hosted).
3. Rode-o como um serviço systemd
O runner vem com um helper que instala um serviço systemd para você — use-o, para que o runner sobreviva a reboots e reinicie em falha. Ainda pela instalação do usuário runner, mas os comandos de serviço precisam de root:
sudo ./svc.sh install runner
sudo ./svc.sh start
sudo ./svc.sh status
Isso registra actions.runner.* como uma unit systemd rodando como o usuário runner, iniciando no boot. Os logs vão para o journald:
sudo journalctl -u 'actions.runner.*' -f
De volta à página de Runners do GitHub, seu runner agora mostra Idle — ponto verde. Aponte um workflow para ele:
jobs:
build:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4
- run: make test
Faça push, e o job roda na sua máquina.
4. Mantenha-o limpo
Um runner self-hosted reutiliza o próprio sistema de arquivos entre jobs — essa é a vitória de velocidade (caches quentes) e a armadilha (estado remanescente). Dois hábitos o mantêm saudável:
- Faça a poda regularmente. Docker especialmente —
docker system prunenum cron, ou o disco enche silenciosamente com camadas mortas. - Não guarde segredos na máquina. Use os secrets do GitHub Actions, injetados por rodada, não arquivos na home do runner. Se o runner for comprometido, qualquer coisa no disco vai junto.
Se você precisa de um ambiente realmente limpo por job, rode cada job dentro de um step de container — o runner fica, a bagunça do job não.
Quando auto-hospedar, honestamente
Auto-hospede quando você precisa do próprio toolchain embutido, acesso a recursos de rede privados, ou controle sobre a máquina. Fique nos runners hospedados pelo GitHub quando um ambiente limpo e descartável e os minutos deles te servem — isso é genuinamente mais simples, e mais simples vale algo. E nunca, num repo público, auto-hospede. Essa não é uma preferência.
Se um runner de repo privado é o que você precisa: escolha um plano — Small (US$8) para builds mais leves, Medium (US$12) quando ficam mais pesados — pague em USDC ou USDT (sem KYC, sem documentos), e você terá root em cerca de 60 segundos. Depois desça por esta página e você terá um runner pegando jobs poucos minutos depois.
Comentários
Nenhum comentário ainda. Seja o primeiro.