Configurar GitLab CI runner self‑hosted com Docker e cache remoto para acelerar builds: tutorial prático

Deploy & DevOps · Por · Publicado em · Atualizado em · 8 min de leitura

Contêineres marítimos coloridos empilhados sob céu azul
Metáfora visual para contêineres Docker e registros de imagem Foto: Jan van der Wolf / Pexels

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.

# 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/CD

Veja também