O GitLab CI/CD é uma plataforma de integração e entrega contínua integrada diretamente ao GitLab. Diferente de ferramentas de CI externas que exigem configuração separada e webhooks, o GitLab CI/CD lê um único arquivo .gitlab-ci.yml do seu repositório e executa pipelines automaticamente a cada push. Essa integração estreita significa que seu código, issues, merge requests e pipelines de deploy vivem em um único lugar.

Este guia percorre a configuração de pipelines do zero — stages, jobs, runners, cache, artefatos, variáveis, environments e estratégias de deploy que funcionam em produção.

Pré-requisitos

  • Uma conta GitLab (gitlab.com ou instância self-hosted)
  • Um repositório Git hospedado no GitLab
  • Conhecimento básico de sintaxe YAML
  • Docker instalado (para runners com executor Docker)
  • Familiaridade com conceitos de CI/CD (build, test, deploy)

Entendendo a Estrutura de Pipeline do GitLab CI/CD

Um pipeline consiste em stages que rodam sequencialmente e jobs dentro de cada stage que rodam em paralelo. Esta é a estrutura fundamental:

# .gitlab-ci.yml
stages:
  - build
  - test
  - deploy

build-app:
  stage: build
  image: node:20
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 hour

unit-tests:
  stage: test
  image: node:20
  script:
    - npm ci
    - npm run test:unit
  coverage: '/Lines\s+:\s+(\d+\.?\d*)%/'

integration-tests:
  stage: test
  image: node:20
  services:
    - postgres:15
  variables:
    POSTGRES_DB: test_db
    POSTGRES_USER: runner
    POSTGRES_PASSWORD: testing
    DATABASE_URL: "postgresql://runner:testing@postgres:5432/test_db"
  script:
    - npm ci
    - npm run test:integration

deploy-staging:
  stage: deploy
  script:
    - ./scripts/deploy.sh staging
  environment:
    name: staging
    url: https://staging.example.com
  rules:
    - if: $CI_COMMIT_BRANCH == "develop"

O stage build roda primeiro. Quando passa, ambos os jobs de teste rodam em paralelo (estão no mesmo stage). Somente se todos os testes passarem o deploy prossegue.

Configurando GitLab Runners

Runners executam os jobs do seu pipeline. Você tem duas opções:

Runners Compartilhados (Início Rápido)

O GitLab.com fornece runners compartilhados gratuitamente. Estão disponíveis imediatamente — sem nenhuma configuração. Navegue até Settings → CI/CD → Runners para verificar se estão habilitados.

Runners Self-Hosted (Produção)

Para melhor desempenho e controle, instale seu próprio runner:

# Instalar GitLab Runner no Ubuntu
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
sudo apt-get install gitlab-runner

# Registrar o runner
sudo gitlab-runner register \
  --url "https://gitlab.com/" \
  --registration-token "YOUR_TOKEN" \
  --executor "docker" \
  --docker-image "alpine:latest" \
  --description "production-runner" \
  --tag-list "docker,linux" \
  --run-untagged="true"

Comparação de Executores de Runner

ExecutorIsolamentoVelocidadeCaso de Uso
DockerAlto (container por job)RápidoEscolha padrão para a maioria dos projetos
ShellNenhum (roda no host)Mais rápidoScripts simples, apps legados
Docker MachineAlto + autoscalingVariávelRunners com autoscaling em nuvem
KubernetesAlto (pod por job)MédioDeployments nativos em Kubernetes
VirtualBoxVM completaLentoNecessidade de isolamento total de OS

Configuração Avançada de Pipeline

Cache de Dependências

O cache evita o download repetido de dependências a cada execução do pipeline:

variables:
  NPM_CONFIG_CACHE: "$CI_PROJECT_DIR/.npm"

cache:
  key:
    files:
      - package-lock.json
  paths:
    - .npm/
    - node_modules/
  policy: pull-push

A diretiva key.files gera uma chave de cache a partir do package-lock.json. Quando as dependências mudam, o cache é invalidado automaticamente.

Artefatos Entre Stages

Passe outputs de build de um stage para o próximo:

build:
  stage: build
  script:
    - npm run build
  artifacts:
    paths:
      - dist/
      - coverage/
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml
    expire_in: 1 week

Regras de Pipeline e Execução Condicional

Controle quando os jobs rodam com rules:

deploy-production:
  stage: deploy
  script:
    - ./deploy.sh production
  environment:
    name: production
    url: https://example.com
  rules:
    - if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
      when: manual
    - when: never

Este job só aparece em tags de versão (v1.2.3) e requer aprovação manual.

Jobs em Matriz Paralela

Teste em múltiplas versões simultaneamente:

test:
  stage: test
  image: node:${NODE_VERSION}
  parallel:
    matrix:
      - NODE_VERSION: ["18", "20", "22"]
        DATABASE: ["postgres", "mysql"]
  script:
    - npm ci
    - npm run test

Isso cria 6 jobs paralelos (3 versões do Node × 2 bancos de dados).

Variáveis de CI/CD e Segredos

Armazene valores sensíveis com segurança:

deploy:
  stage: deploy
  script:
    - echo "$DEPLOY_KEY" > key.pem
    - chmod 600 key.pem
    - scp -i key.pem dist/* user@server:/var/www/
  after_script:
    - rm -f key.pem

Cenário real: Seu time implanta uma aplicação Node.js em três environments — desenvolvimento, staging e produção. Cada environment tem credenciais de banco de dados, chaves de API e endereços de servidor diferentes. Você armazena esses dados como variáveis GitLab CI/CD com escopo por environment. O mesmo YAML do pipeline gerencia todos os deploys; apenas as variáveis diferem. Quando um desenvolvedor faz push para develop, o pipeline faz deploy automático para staging. O deploy de produção só é disparado em tags, com aprovação manual do líder técnico.

Tipos e Escopo de Variáveis

EscopoConfigurado EmDisponível Para
ProjetoSettings → CI/CD → VariablesTodos os pipelines do projeto
GrupoGroup → Settings → CI/CDTodos os projetos do grupo
InstânciaAdmin → CI/CD → VariablesTodos os projetos da instância
EnvironmentSettings → CI/CD → Variables (filtro de env)Jobs direcionados a esse environment
Jobvariables: no .gitlab-ci.ymlApenas aquele job específico

Marque variáveis como Protected (disponíveis apenas em branches/tags protegidas) e Masked (ocultas nos logs de job) para credenciais.

Environments de Deploy e Estratégias

Review Apps (Environments Dinâmicos)

Crie um environment temporário para cada merge request:

review:
  stage: deploy
  script:
    - deploy_review_app "$CI_MERGE_REQUEST_IID"
  environment:
    name: review/$CI_MERGE_REQUEST_IID
    url: https://$CI_MERGE_REQUEST_IID.review.example.com
    on_stop: stop-review
  rules:
    - if: $CI_MERGE_REQUEST_IID

stop-review:
  stage: deploy
  script:
    - teardown_review_app "$CI_MERGE_REQUEST_IID"
  environment:
    name: review/$CI_MERGE_REQUEST_IID
    action: stop
  rules:
    - if: $CI_MERGE_REQUEST_IID
      when: manual

Deploy de Produção com Rollback

deploy-production:
  stage: deploy
  script:
    - ./deploy.sh production
  environment:
    name: production
    url: https://example.com
    auto_stop_in: never
  rules:
    - if: $CI_COMMIT_TAG
      when: manual
  allow_failure: false

GitLab CI/CD vs Outras Plataformas de CI

RecursoGitLab CI/CDGitHub ActionsJenkinsCircleCI
Arquivo de Config.gitlab-ci.yml.github/workflows/*.ymlJenkinsfile.circleci/config.yml
Registry EmbutidoSim (container + pacotes)Sim (container)NãoNão
Opção Self-hostedSim (GitLab completo)Sim (apenas runners)SimNão
Review AppsNativoConfiguração manualManualManual
Pipelines DAGSim (keyword needs)Sim (nativo)SimSim
Auto DevOpsSimNãoNãoNão
Minutos Gratuitos de CI400 min/mês2.000 min/mêsIlimitado (self-host)6.000 min/mês
Curva de AprendizadoMédiaBaixaAltaBaixa

O GitLab CI/CD se destaca quando você quer tudo integrado — código, CI, registry de container, environments e monitoramento em uma única plataforma. O GitHub Actions se sobressai pela amplitude do ecossistema com seu marketplace.

Armadilhas e Casos Especiais

  • Âncoras YAML não funcionam com include: Se você usar âncoras YAML (&anchor/*anchor) em arquivos incluídos, elas não serão resolvidas entre os limites dos arquivos. Use a keyword extends no lugar.

  • O cache não é garantido: Os caches do GitLab são por melhor esforço. Runners podem não compartilhar caches. Sempre projete pipelines que funcionem sem cache (apenas mais lentamente).

  • Rede entre services: Containers de service (como postgres:15) são acessíveis pelo nome da imagem como hostname. Use postgres, não localhost. Isso confunde muitos desenvolvedores.

  • only/except vs rules: A sintaxe legada only/except conflita com rules. Nunca os misture no mesmo job. Prefira rules — é mais poderoso e a abordagem recomendada.

  • Timeout padrão de job é 1 hora: Jobs de longa duração como testes E2E ou builds grandes falham silenciosamente no timeout. Defina timeout: 2h explicitamente para jobs sabidamente longos.

  • Variáveis de branch protegida: Variáveis marcadas como “Protected” não estão disponíveis em feature branches. Se um job precisa de credenciais em branches não protegidas, use uma variável separada sem a flag de proteção.

Solução de Problemas

ProblemaCausaSolução
Pipeline travado em “Pending”Nenhum runner disponível com as tags correspondentesVerifique as tags do runner ou defina tags: [] para usar qualquer runner
”Cache not found” na primeira execuçãoO cache ainda não foi criadoA primeira execução baixa tudo; o cache é populado para a próxima
Services inacessíveisHostname errado na string de conexãoUse o nome da imagem do service como hostname (ex.: postgres, não localhost)
“Variable is not set” nos jobsVariável é protegida, branch não éDesmarque “Protected” ou faça push para branch protegida
Artefatos ausentes no próximo stageartifacts.paths não corresponde ao outputVerifique os caminhos exatos; use ls -la no script para depurar

Resumo

  • GitLab CI/CD.gitlab-ci.yml do seu repositório e executa pipelines automaticamente — sem configuração de ferramenta externa
  • Stages rodam sequencialmente enquanto jobs dentro de um stage rodam em paralelo, oferecendo ordenação e velocidade
  • Runners self-hosted com executor Docker oferecem o melhor desempenho e controle para times em produção
  • Cache de dependências e passagem de artefatos entre stages reduz drasticamente o tempo de execução do pipeline
  • Variáveis de ambiente com mascaramento, proteção e escopo por environment mantêm segredos seguros entre deploys
  • Review apps criam environments temporários por merge request, permitindo revisão visual antes do merge

Artigos Relacionados