Configurar GitLab CI runner self‑hosted com Docker e cache remoto para acelerar builds: tutorial prático
Deploy & DevOps · Por Kevin Marcondes · Publicado em · Atualizado em · 8 min de leitura
Este tutorial: configurar GitLab CI runner self‑hosted com Docker e cache remoto para acelerar builds mostra, passo a passo, como subir o runner em Docker, registrar no GitLab, habilitar cache S3/MinIO e usar BuildKit com cache no registry. Inclui um .gitlab-ci.yml de exemplo e comandos para verificar que tudo funcionou.
Arquitetura e escolhas de cache
Você vai rodar o GitLab Runner em um container usando o executor Docker, que isola os jobs em containers. Usaremos dois mecanismos de cache para reduzir tempo de pipeline e tráfego: cache de arquivos do runner e cache de camadas de imagem via BuildKit no registry. A combinação cobre dependências da aplicação e camadas do Dockerfile.
- Cache do Runner (S3/MinIO): guarda dependências e diretórios temporários (node_modules, vendor, .m2) entre jobs.
- Cache de camadas do Docker (BuildKit para registry): reaproveita camadas de imagem entre builds no Container Registry.
| Recurso | Cache do Runner (S3/MinIO) | Cache Docker registry (BuildKit) |
|---|---|---|
| O que armazena | Dependências e diretórios temporários | Camadas de imagem do Dockerfile |
| Escopo | Por job/projeto; pode ser compartilhado | Por Dockerfile/tag; compartilhado por refs |
| Quando atua | Antes/depois do job (restore/save) | Durante o docker buildx build |
| Infra necessária | Bucket S3/compatível (ex.: MinIO) | Registry (ex.: GitLab Container Registry) |
| Benefício típico | Acelera gestores de pacotes e builds de apps | Acelera rebuilds de imagens e push/pull de camadas |
Pré-requisitos
Garanta estes itens antes de começar. Você precisará de privilégios administrativos no servidor do runner.
- Instância do GitLab acessível e token de registro do runner.
- Um servidor Linux com acesso root e saída para internet.
- Docker instalado no host. Se preferir, siga: como instalar Docker e Docker Compose no Linux.
- Opcional para cache do runner: bucket S3/MinIO acessível pelo servidor.
- Acesso ao GitLab Container Registry do projeto para cache de camadas via BuildKit.
Subir e registrar o GitLab Runner (executor Docker)
Vamos criar o volume de configuração, subir o container do Runner e registrá‑lo. O executor será Docker, com acesso ao socket para criar containers de jobs. Guarde o token de registro com segurança. O registro abaixo é não interativo; ajuste URL do GitLab, token, nome do runner e versões conforme seu ambiente.
# 1) Preparar diretório de configuração
sudo mkdir -p /srv/gitlab-runner/config
# 2) Subir o container do GitLab Runner
sudo docker run -d --name gitlab-runner \
--restart always \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:alpine
# 3) Registrar o runner (ajuste URL e token)
sudo docker run --rm -it \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:alpine register \
--non-interactive \
--url "https://gitlab.example.com/" \
--registration-token "REG_TOKEN" \
--name "runner-docker" \
--executor "docker" \
--docker-image "docker:24.0" \
--docker-privileged \
--docker-volumes "/cache"
Ajustar config.toml para Docker e BuildKit
Após o registro, edite o config.toml para habilitar BuildKit e definir volumes. O BuildKit acelera builds e melhora o cache de camadas. Mantemos o executor em modo privilegiado para cenários que exigem DinD. Para otimizar camadas da sua imagem, veja como criar imagens Docker leves e estratégias de cache em BuildKit e cache remoto no CI.
concurrent = 2
check_interval = 0
[session_server]
session_timeout = 1800
[[runners]]
name = "runner-docker"
url = "https://gitlab.example.com/"
token = "TOKEN_GERADO_NO_REGISTRO"
executor = "docker"
environment = [
"DOCKER_DRIVER=overlay2",
"DOCKER_TLS_CERTDIR=",
"DOCKER_BUILDKIT=1",
"BUILDKIT_PROGRESS=plain"
]
[runners.docker]
image = "docker:24.0"
privileged = true
tls_verify = false
disable_cache = false
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
Habilitar cache remoto S3/MinIO para o Runner
Agora, configure o cache remoto para restaurar e salvar dependências mais rápido. Se usar MinIO, habilite Insecure se não houver TLS no endpoint interno. Restrinja o acesso do bucket a um usuário dedicado. Coloque o bloco abaixo dentro do seu [[runners]] no config.toml e ajuste endpoint, região, bucket e credenciais conforme o provedor.
[runners.cache]
Type = "s3"
Shared = true
[runners.cache.s3]
ServerAddress = "minio.internal:9000"
BucketName = "gitlab-cache"
BucketLocation = "us-east-1"
AccessKey = "MINIO_ACCESS_KEY"
SecretKey = "MINIO_SECRET_KEY"
Insecure = true
Pipeline (.gitlab-ci.yml) com BuildKit e cache no registry
Este exemplo produz e publica a imagem no GitLab Container Registry usando BuildKit com cache no próprio registry. Isso reaproveita camadas entre builds, reduzindo tempo em passos repetidos do Dockerfile. O serviço docker:dind expõe o daemon em 2375 sem TLS. Use apenas em ambientes controlados. As credenciais do registry vêm de variáveis padrão do GitLab CI.
image: docker:24.0
services:
- name: docker:24.0-dind
command: ["--registry-mirror=", "--mtu=1460"]
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
DOCKER_DRIVER: overlay2
DOCKER_BUILDKIT: "1"
BUILDKIT_PROGRESS: plain
IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
CACHE_REF: $CI_REGISTRY_IMAGE:buildcache
stages: [build]
build-image:
stage: build
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
- docker buildx create --use --name builder || docker buildx use builder
script:
- docker buildx build \
--push -t "$IMAGE" \
--cache-from type=registry,ref="$CACHE_REF" \
--cache-to type=registry,ref="$CACHE_REF",mode=max \
-f Dockerfile .
rules:
- if: $CI_COMMIT_BRANCH
Verificação e solução de problemas comuns
Execute os comandos para validar logs e conectividade. O primeiro build pode demorar mais; os seguintes devem baixar menos dependências e pular etapas do Dockerfile.
- Se o runner não aparece no GitLab, confira token e URL.
- Se o cache S3 não funciona, valide endpoint, chaves e política do bucket.
- Se o buildx falha, cheque a versão do Docker e do serviço dind.
# Ver logs do runner
sudo docker logs --tail=200 gitlab-runner
# Verificar conectividade e estado do runner
sudo docker exec -it gitlab-runner gitlab-runner verify --delete
# Conferir se o bloco de cache está ativo no config
echo "--- cache config ---" && \
sudo docker exec -it gitlab-runner \
grep -A4 "\[runners.cache\]" /etc/gitlab-runner/config.toml
Operação, segurança e manutenção
Mantenha o runner atualizado e dimensionado à sua infraestrutura. Limpezas agressivas podem apagar camadas e caches úteis — programe‑as com cuidado. Para dimensionar e observar o host, veja materiais práticos já publicados.
- Atualize o container do runner periodicamente e re‑suba com o mesmo volume.
- Limite a concorrência (concurrent) ao que o host suporta. Critérios em como escolher o tamanho certo de VPS.
- Monitore CPU, RAM e disco. Instrumente com Prometheus e Grafana via Docker Compose.
- Cuidado ao rodar prune: pode apagar imagens e caches úteis; rode fora do horário de pico.
# Atualizar imagem do runner e inspecionar estado
sudo docker pull gitlab/gitlab-runner:alpine
sudo docker exec -it gitlab-runner gitlab-runner list
sudo docker exec -it gitlab-runner gitlab-runner status
# Limpeza com cautela (pode remover camadas e caches)
sudo docker system prune -af --volumes
Perguntas frequentes
Preciso usar Docker-in-Docker ou o socket do host?
Para o executor Docker, é comum montar o socket do host no container do runner. Isso evita overhead do DinD e costuma ser mais simples. Use DinD quando você quer isolar totalmente o daemon de Docker por job, aceitando maior consumo de recursos.
Qual a diferença entre cache do Runner e cache do Docker (BuildKit)?
O cache do Runner guarda arquivos do job, como dependências de linguagens. O cache do Docker guarda camadas de imagem criadas no build. Eles se complementam: o primeiro acelera tarefas da aplicação, o segundo acelera rebuilds do Dockerfile.
Onde ficam os arquivos de cache do Runner?
Com S3/MinIO configurado, os artefatos de cache são enviados ao bucket definido. Sem S3, o cache fica local no host do runner, o que dificulta compartilhamento e pode ser perdido em recriações do container.
Como limitar a quantidade de jobs concorrentes?
No config.toml, ajuste a chave concurrent para definir o número máximo de jobs simultâneos por serviço de runner. Balanceie com a capacidade do servidor. Observe CPU, memória e I/O para encontrar o ponto ideal sem gerar contenção.
Posso usar o mesmo cache entre projetos diferentes?
Sim, se marcar Shared = true no bloco do cache do Runner e usar chaves de cache compatíveis nos jobs. Evite chaves genéricas para não vazar dados. Buckets separados e prefixos de chave ajudam a isolar projetos.
Como rolar credenciais do S3/MinIO com segurança?
Crie um usuário dedicado com permissões mínimas para o bucket e troque as chaves periodicamente. Evite commitar credenciais. Prefira variáveis de ambiente no container do runner ou mecanismos de segredos do seu ambiente.
Quer acelerar seu CI com segurança?
Se precisa de ajuda para desenhar o runner self‑hosted, configurar cache remoto e otimizar Dockerfiles e pipelines, podemos conversar e avaliar seu caso.
Conversar sobre seu CI/CDVeja também
- tutorial: implementar Canary releases com Traefik em Docker Compose usando headers e weight routing para deploys graduais de aplicações PHP
- Tutorial: configurar HAProxy com Let's Encrypt e healthchecks para balanceamento de tráfego entre containers Docker em VPS (passo a passo)
- Tutorial prático: implementar mTLS entre Nginx e microserviços usando smallstep CA em Docker Compose
- Tutorial: configurar cgroup v2 e systemd ResourceControl para limitar CPU, memória e I/O de containers Docker no Debian