“Mandei a ordem de serviço, mas por que ninguém responde?”
Da última vez, escrevi com toda a empolgação meu arquivo .gitlab-ci.yml e dei push. “Agora o deploy vai rolar automaticamente, né?”, pensei animado, e cliquei no menu ‘CI/CD > Pipelines’ do GitLab.
Mas o que apareceu na tela não foi nenhum sinal verde de sucesso, e sim aquela barra de loading girando sem parar e a mensagem ‘Pending (Em espera)’. Cliquei na mensagem e vi este aviso:
This job is stuck because the project doesn't have any runners online assigned to it.
Traduzindo: “Chegou trabalho aqui, mas o funcionário (Runner) que ia executar não bateu o ponto”. Putz, eu joguei a ordem de serviço para o gerente da fábrica (servidor GitLab), mas esqueci de contratar o funcionário (Runner) que ia trabalhar de fato na fábrica.

GitLab Runner: as mãos e os pés do pipeline
O GitLab se divide basicamente em dois componentes.
- GitLab Server (matriz/gerente da fábrica): guarda o código, gerencia o estado do pipeline e dá as ordens.
- GitLab Runner (filial/funcionário de campo): fica instalado no servidor de verdade, recebe as ordens da matriz, busca o código, faz o build e executa os comandos de deploy.
“Mas e se o GitLab simplesmente acessasse meu servidor e fizesse o deploy sozinho?” Pensa bem, isso seria um perigo enorme. Se um site na internet (GitLab) pudesse, com um clique, entrar no computador (servidor) que está no meu quarto e executar comandos à vontade? Isso seria praticamente um ‘hack’. Se alguém invadisse minha conta no GitLab, poderia transformar meu servidor em uma máquina de minerar bitcoin.
Por isso, o GitLab não acessa meu servidor diretamente. Em vez disso, ele coloca um ‘representante de identidade verificada (Runner)’ que só funciona dentro do meu servidor, e só passa o trabalho por meio desse representante. Todo esse processo complicado de instalação e registro que vamos fazer é justamente o ‘procedimento de segurança’ para autenticar esse representante.
Etapa 1: conferir a vaga de emprego (emissão do token)
Antes de instalar o runner, primeiro precisamos abrir uma ‘vaga de emprego’ na matriz (GitLab) dizendo “precisamos de um funcionário para o nosso projeto” e receber a ‘carteira de registro (Token)’.
Nas versões mais recentes do GitLab, por questões de segurança, o jeito de ver o token está meio escondido.
- Acesse o projeto no GitLab
- Menu à esquerda: Settings > CI/CD
- Na seção Runners, clique em
Expand - Na seção Project runners, clique no botão de três pontinhos (⋮) no canto superior direito
Quando você clica nesse botão, abre um menu pop-up com a informação que estamos procurando. Confira e copie a URL e o Registration token.
(Obs.: pode aparecer aquele aviso assustador ‘Support for registration tokens is deprecated’. Significa que esse método vai ser descontinuado em breve, mas ainda é suportado por compatibilidade, então não se assuste e copie o token.)
[Dica] Tem vários projetos? (Group Runner) Se você, igual eu, gerencia vários projetos (frontend, backend, etc.) agrupados, registrar um runner para cada projeto é ineficiente. Nesse caso, em vez de configurar no projeto, registre o runner no menu Group Settings > CI/CD. Esse ‘Group Runner’ consegue dar conta sozinho de todos os jobs dos projetos pertencentes ao grupo. (Eu tenho muitos projetos, então fui por esse caminho.)

Etapa 2: contratar o funcionário (instalação do Runner)
Agora vamos instalar de verdade o runner em um servidor Linux (ou no seu PC). O jeito mais limpo é, claro, usar nosso querido ‘Docker’.
# 1. Rodar o container do GitLab Runner
docker run -d --name gitlab-runner --restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v gitlab-runner-config:/etc/gitlab-runner \
gitlab/gitlab-runner:latest
-v /var/run/docker.sock:/var/run/docker.sock: essa parte é importante. Como o runner precisa subir outros containers Docker (para o build), estamos compartilhando com ele o socket do Docker do host. (Método Docker in Docker)
Etapa 3: assinar o contrato de trabalho (registro do Runner)
Instalar o runner ainda não é o fim. Falta o procedimento de registrar (Register) esse runner no servidor GitLab dizendo “sou um funcionário do projeto A”.
Vamos entrar no container do runner que acabamos de subir e executar o comando de registro.
# Executar o comando de registro dentro do container do runner
docker exec -it gitlab-runner gitlab-runner register
Agora, no terminal, começa um joguinho de perguntas e respostas. É só preencher com as informações que vimos na Etapa 1.
- Enter the GitLab instance URL:
https://gitlab.com/(ou o endereço do seu GitLab privado)
- Enter the registration token:
- (cole o token que você copiou antes)
- Enter a description for the runner:
my-runner-01(qualquer um, um nome fácil de reconhecer)
- Enter tags for the runner:
- (dá para pular apertando Enter. Serve para quando você quer que ele execute só os jobs com uma tag específica.)
- Enter an executor:
docker(como vamos fazer o build em cima do Docker, digite docker.)
- Enter the default Docker image:
docker:latest(a imagem usada por padrão)
“Runner registered successfully.” Quando essa mensagem aparece, contratação concluída! Agora, atualize a tela do GitLab e você vai ver o runner com a luz verde acesa, gritando “Estou pronto (Online)”.

Etapa 4: pipeline ligado!
No instante em que o runner é registrado, o pipeline que estava parado (Pending) começa a se mover automaticamente. Running… e, pouco depois, Passed!
Eu não fiz nada, e a máquina rodou os testes, fez o build, gerou a imagem e subiu para o repositório sozinha. Abri o terminal para conferir os logs e vi que tudo terminou muito mais rápido e preciso do que quando eu fazia na mão.
“Caramba… realmente funciona!”
O deploy manual que demorava 10 minutos agora termina com um único git push. Agora consigo deixar o deploy rolando e ir tomar um cafezinho.
Dica prática: problema de permissão do Docker (Permission Denied)
Tem um erro que aparece em 99% das vezes na primeira configuração do runner: dial unix /var/run/docker.sock: connect: permission denied
É um problema que acontece porque o runner tenta usar comandos Docker, mas não tem permissão. Nesse caso, abra o arquivo de configuração do gitlab-runner (config.toml) e ative a opção privileged = true.
# /etc/gitlab-runner/config.toml (arquivo de config do runner)
[[runners]]
name = "my-runner-01"
executor = "docker"
[runners.docker]
privileged = true # Precisa mudar essa parte para true para o Docker-in-Docker funcionar bem. # …
Encerrando: agora dá para ir para casa
Finalmente tenho o meu próprio ‘robô de deploy’. Agora basta focar em escrever código. As tarefas chatas e repetitivas de validação e deploy o meu fiel robô (Runner) faz por mim.
Mas ainda falta aquele 2%. Hoje em dia o pipeline roda toda vez que eu dou push na branch master. “E se eu quisesse fazer deploy automático no servidor de desenvolvimento (dev), mas só fizer deploy no servidor de produção (prod) quando eu apertar o ‘botão de aprovação’?”
Na próxima, vamos ver como controlar o pipeline de forma mais inteligente, com ‘estratégia de deploy por branch’ e o ‘procedimento de aprovação manual (Manual)’.


