TL;DR — Resumo Rápido

GitLab CI/CD automatiza build, testes e deploy com .gitlab-ci.yml. Domine estágios, runners, artefatos e estratégias de implantação em produção.

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

Executor Isolamento Velocidade Caso de Uso
Docker Alto (container por job) Rápido Escolha padrão para a maioria dos projetos
Shell Nenhum (roda no host) Mais rápido Scripts simples, apps legados
Docker Machine Alto + autoscaling Variável Runners com autoscaling em nuvem
Kubernetes Alto (pod por job) Médio Deployments nativos em Kubernetes
VirtualBox VM completa Lento Necessidade 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

Escopo Configurado Em Disponível Para
Projeto Settings → CI/CD → Variables Todos os pipelines do projeto
Grupo Group → Settings → CI/CD Todos os projetos do grupo
Instância Admin → CI/CD → Variables Todos os projetos da instância
Environment Settings → CI/CD → Variables (filtro de env) Jobs direcionados a esse environment
Job variables: no .gitlab-ci.yml Apenas 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

Recurso GitLab CI/CD GitHub Actions Jenkins CircleCI
Arquivo de Config .gitlab-ci.yml .github/workflows/*.yml Jenkinsfile .circleci/config.yml
Registry Embutido Sim (container + pacotes) Sim (container) Não Não
Opção Self-hosted Sim (GitLab completo) Sim (apenas runners) Sim Não
Review Apps Nativo Configuração manual Manual Manual
Pipelines DAG Sim (keyword needs) Sim (nativo) Sim Sim
Auto DevOps Sim Não Não Não
Minutos Gratuitos de CI 400 min/mês 2.000 min/mês Ilimitado (self-host) 6.000 min/mês
Curva de Aprendizado Média Baixa Alta Baixa

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

Problema Causa Solução
Pipeline travado em “Pending” Nenhum runner disponível com as tags correspondentes Verifique as tags do runner ou defina tags: [] para usar qualquer runner
“Cache not found” na primeira execução O cache ainda não foi criado A primeira execução baixa tudo; o cache é populado para a próxima
Services inacessíveis Hostname errado na string de conexão Use o nome da imagem do service como hostname (ex.: postgres, não localhost)
“Variable is not set” nos jobs Variável é protegida, branch não é Desmarque “Protected” ou faça push para branch protegida
Artefatos ausentes no próximo stage artifacts.paths não corresponde ao output Verifique 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