GitLab Runner: Construção de imagens Docker

Construa e envie imagens Docker a partir dos seus pipelines GitLab CI/CD utilizando o seu runner Stackhero e Docker-in-Docker

👋 Bem-vindo à documentação da Stackhero!

A Stackhero oferece-lhe uma solução GitLab Runner cloud fácil de utilizar, concebida para executar os seus jobs GitLab CI/CD de forma eficiente. Eis o que pode esperar:

  • Minutos CI/CD ilimitados: não existe faturação por minuto, por isso os seus pipelines podem correr sempre que precisar.
  • Vários jobs em simultâneo: execute vários jobs ao mesmo tempo para acelerar todo o seu pipeline.
  • Docker executor com suporte para Docker-in-Docker: simplifique a criação e o envio das suas imagens de containers.
  • Compatível com GitLab.com e também com qualquer instância GitLab self-managed.
  • Uma VM privada e dedicada alimentada por discos NVMe/SSD rápidos para builds consistentes e fiáveis.
  • Disponível nas regiões 🇪🇺 Europa e 🇺🇸 USA.

Poupe tempo: pode ligar o seu primeiro GitLab Runner e começar a executar pipelines em apenas alguns minutos!

Quando utiliza um Stackhero GitLab Runner, os jobs são executados com o executor Docker. Isto significa que cada job inicia num novo contentor baseado na image que especificar. Se pretende construir as suas próprias imagens Docker como parte do pipeline, pode tirar partido do Docker-in-Docker (DinD). Esta configuração permite que um daemon Docker seja executado em paralelo com o seu job, possibilitando a execução de comandos como docker build e docker push diretamente no pipeline.

Uma das grandes vantagens é que o seu runner inclui minutos CI/CD ilimitados. Pode construir imagens quantas vezes quiser. Além disso, como o cache de build reside no disco dedicado do runner, builds repetidos podem reutilizar camadas anteriores, acelerando significativamente a execução dos pipelines.

Aqui tem um exemplo de .gitlab-ci.yml que pode adicionar ao seu repositório. Esta configuração constrói o Dockerfile localizado na raiz do seu projeto:

build-image:
  stage: build
  image: docker:27
  services:
    - docker:27-dind
  variables:
    DOCKER_TLS_CERTDIR: "/certs"
  before_script:
    - docker info
  script:
    # Substitua "my-image" pelo nome pretendido:
    - docker build -t my-image .
    # Opcionalmente, pode executar um teste rápido na imagem construída:
    # - docker run --rm my-image /path/to/tests

Nesta configuração, o serviço docker:27-dind inicia o daemon Docker. A variável DOCKER_TLS_CERTDIR: "/certs" ativa uma ligação TLS segura entre o seu job e o daemon Docker.

O GitLab disponibiliza várias variáveis predefinidas (CI_REGISTRY, CI_REGISTRY_USER, CI_REGISTRY_PASSWORD, CI_REGISTRY_IMAGE) para que o seu pipeline possa autenticar-se e enviar imagens para o registo de contentores do projeto sem necessidade de segredos adicionais.

Aqui está um exemplo de job que constrói e envia a sua imagem:

build-and-push:
  stage: build
  image: docker:27
  services:
    - docker:27-dind
  variables:
    DOCKER_TLS_CERTDIR: "/certs"
  before_script:
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
  script:
    - docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" .
    - docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
    # Se estiver na branch principal, pode também marcar e enviar "latest":
    - |
      if [ "$CI_COMMIT_BRANCH" = "$CI_DEFAULT_BRANCH" ]; then
        docker tag "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" "$CI_REGISTRY_IMAGE:latest"
        docker push "$CI_REGISTRY_IMAGE:latest"
      fi

Se pretender enviar as suas imagens para outro registo (como o Docker Hub ou um registo privado), pode guardar essas credenciais como variáveis CI/CD e utilizá-las com o docker login da mesma forma.

Como o disco do seu runner é persistente entre pipelines, pode acelerar os builds reutilizando camadas de imagens anteriores como cache. Veja como pode configurar:

build-cached:
  stage: build
  image: docker:27
  services:
    - docker:27-dind
  variables:
    DOCKER_TLS_CERTDIR: "/certs"
  before_script:
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
  script:
    # Tente obter a imagem mais recente para alimentar o cache (não há problema se ainda não existir):
    - docker pull "$CI_REGISTRY_IMAGE:latest" || true
    - docker build --cache-from "$CI_REGISTRY_IMAGE:latest" -t "$CI_REGISTRY_IMAGE:latest" .
    - docker push "$CI_REGISTRY_IMAGE:latest"

Esta abordagem permite que os seus pipelines terminem mais rapidamente ao longo do tempo, aproveitando o cache de camadas do Docker.

O seu plano define quantos jobs podem ser executados em simultâneo. Jobs dentro da mesma etapa iniciam-se juntos, até ao limite de concorrência definido. Isto significa que uma etapa com vários jobs independentes termina assim que o job mais lento concluir, em vez de executar todos sequencialmente.

Aqui está um exemplo simples:

stages:
  - test

unit:
  stage: test
  image: node:22
  script: npm run test:unit

integration:
  stage: test
  image: node:22
  script: npm run test:integration

e2e:
  stage: test
  image: node:22
  script: npm run test:e2e

Se definir a sua concorrência para 3 ou mais, os jobs unit, integration e e2e serão executados todos em simultâneo.

Se quiser aprofundar mais sobre a construção de imagens Docker em CI, consulte a documentação oficial do GitLab.