Saltar a contenido
_

GitLab CI/CD Cheatsheet

Instalación

GitLab Runner Instalación

Platform Command
Ubuntu/Debian INLINE_CODE_12
CentOS/RHEL INLINE_CODE_13
macOS INLINE_CODE_14
Windows INLINE_CODE_15
Docker INLINE_CODE_16
Kubernetes (Helm) INLINE_CODE_17

Verification

Command Description
INLINE_CODE_18 Check installed GitLab Runner version
INLINE_CODE_19 Verify runner can connect to GitLab

-...

Comandos básicos

Runner Management

Command Description
INLINE_CODE_20 Register a new runner interactively
INLINE_CODE_21 List all registered runners
INLINE_CODE_22 Start the runner service
INLINE_CODE_23 Stop the runner service
INLINE_CODE_24 Restart the runner service
INLINE_CODE_25 Check current runner status
INLINE_CODE_26 Unregister a specific runner
INLINE_CODE_27 Unregister all runners
INLINE_CODE_28 Run runner in foreground for debugging
INLINE_CODE_29 Execute a single job locally for testing

Pipeline Operations (GitLab CLI)

Command Description
INLINE_CODE_30 Validate INLINE_CODE_31 syntax locally
INLINE_CODE_32 View CI/CD configuration for current project
INLINE_CODE_33 View real-time logs for a specific job
INLINE_CODE_34 List all pipelines for current project
INLINE_CODE_35 Retry a failed pipeline
INLINE_CODE_36 Cancel a running pipeline

API-Based Pipeline Triggers

Command Description
INLINE_CODE_37 Trigger pipeline via API
INLINE_CODE_38 Trigger pipeline with variables
INLINE_CODE_39 Get pipeline status via API

-...

Advanced Usage

Advanced Runner Registration

Command Description
INLINE_CODE_40 Register runner with inline parameters
INLINE_CODE_41 Register Docker-in-Docker (DinD) runner
INLINE_CODE_42 Configure runner with S3 cache
INLINE_CODE_43 Register Kubernetes executor
INLINE_CODE_44 Configure runner with specific Docker network
INLINE_CODE_45 Register runner with specific tags

Advanced Pipeline Operations

Command Description
INLINE_CODE_46 Download job artifacts via API
INLINE_CODE_47 Create pipeline schedule via API
INLINE_CODE_48 Trigger multi-project pipeline
INLINE_CODE_49 Test runner executor locally

Monitoring and Debugging

Command Description
INLINE_CODE_50 View runner logs in real-time (Linux)
INLINE_CODE_51 Run runner with verbose debug logging
INLINE_CODE_52 Access runner Prometheus metrics
INLINE_CODE_53 View Docker runner logs
INLINE_CODE_54 View Kubernetes runner logs

Configuration Management

Command Description
INLINE_CODE_55 Edit runner configuration file (Linux)
INLINE_CODE_56 Remove invalid runners from config
INLINE_CODE_57 Run a single job without registration

-...

Configuración

Basic .gitlab-ci.yml Estructura

# Define pipeline stages
stages:
  - build
  - test
  - deploy

# Global variables
variables:
  DOCKER_DRIVER: overlay2
  DATABASE_URL: "postgres://localhost/db"

# Global scripts executed before each job
before_script:
  - echo "Pipeline started at $(date)"
  - export PATH=$PATH:/custom/bin

# Global scripts executed after each job
after_script:
  - echo "Cleaning up..."

# Basic job definition
build_app:
  stage: build
  image: node:16-alpine
  script:
    - npm install
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 week
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - node_modules/
  only:
    - main
    - merge_requests
  tags:
    - docker

Configuración de tuberías avanzadas

# Include external configurations
include:
  - project: 'my-group/ci-templates'
    ref: main
    file: '/templates/.gitlab-ci-template.yml'
  - remote: 'https://example.com/ci-template.yml'
  - local: '/templates/security-scan.yml'
  - template: Security/SAST.gitlab-ci.yml

# Workflow rules for pipeline execution
workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_COMMIT_BRANCH == "main"'
    - if: '$CI_COMMIT_TAG'
    - when: never

# Job with complex rules
deploy_production:
  stage: deploy
  script:
    - ./deploy.sh production
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
      when: manual
    - if: '$CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/'
      when: on_success
  environment:
    name: production
    url: https://prod.example.com
    on_stop: stop_production

Parallel and Matrix Jobs

# Parallel execution
test:
  stage: test
  parallel: 5
  script:
    - bundle exec rspec

# Matrix builds
test_matrix:
  parallel:
    matrix:
      - NODE_VERSION: ['14', '16', '18']
        OS: ['linux', 'windows']
  image: node:${NODE_VERSION}
  script:
    - npm test

Artifacts and Cache Configuration

build:
  stage: build
  script:
    - make build
  artifacts:
    name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME"
    paths:
      - binaries/
      - build/
    exclude:
      - binaries/**/*.tmp
    reports:
      junit: test-results.xml
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml
    expire_in: 30 days
    when: on_success
  cache:
    key:
      files:
        - package-lock.json
    paths:
      - node_modules/
    policy: pull-push

Docker and Services Configuration

build_docker:
  stage: build
  image: docker:latest
  services:
    - docker: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_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

Dynamic Child Pipelines

generate_config:
  stage: build
  script:
    - ./generate-ci-config.sh > generated-config.yml
  artifacts:
    paths:
      - generated-config.yml

trigger_child:
  stage: deploy
  trigger:
    include:
      - artifact: generated-config.yml
        job: generate_config
    strategy: depend

Runner Configuration File (config.toml)

concurrent = 10
check_interval = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "docker-runner"
  url = "https://gitlab.com/"
  token = "TOKEN"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.cache]
    Type = "s3"
    Path = "cache"
    Shared = true
    [runners.cache.s3]
      ServerAddress = "s3.amazonaws.com"
      BucketName = "runner-cache"
      BucketLocation = "us-east-1"
  [runners.docker]
    tls_verify = false
    image = "alpine:latest"
    privileged = true
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock"]
    shm_size = 0

-...

Common Use Cases

Use Case 1: Build and Test Node.js Application

stages:
  - build
  - test
  - deploy

variables:
  NODE_ENV: production

build:
  stage: build
  image: node:16-alpine
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/
      - node_modules/
    expire_in: 1 hour
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - .npm/

test:unit:
  stage: test
  image: node:16-alpine
  dependencies:
    - build
  script:
    - npm run test:unit
  coverage: '/Lines\s*:\s*(\d+\.\d+)%/'
  artifacts:
    reports:
      junit: junit.xml
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml

test:integration:
  stage: test
  image: node:16-alpine
  services:
    - postgres:13
  variables:
    POSTGRES_DB: test_db
    POSTGRES_USER: test_user
    POSTGRES_PASSWORD: test_password
  script:
    - npm run test:integration

Use Case 2: Docker Build and Push to Registry

stages:
  - build
  - scan
  - deploy

variables:
  DOCKER_DRIVER: overlay2
  IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA

build_image:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build -t $IMAGE_TAG .
    - docker tag $IMAGE_TAG $CI_REGISTRY_IMAGE:latest
    - docker push $IMAGE_TAG
    - docker push $CI_REGISTRY_IMAGE:latest
  only:
    - main
    - tags

scan_image:
  stage: scan
  image: aquasec/trivy:latest
  script:
    - trivy image --severity HIGH,CRITICAL $IMAGE_TAG
  allow_failure: true

deploy_k8s:
  stage: deploy
  image: bitnami/kubectl:latest
  script:
    - kubectl config use-context $KUBE_CONTEXT
    - kubectl set image deployment/myapp myapp=$IMAGE_TAG
    - kubectl rollout status deployment/myapp
  environment:
    name: production
    url: https://myapp.example.com
  only:
    - main

Use Case 3: Multi-Environment Deployment with Manual Approval

stages:
  - build
  - deploy_staging
  - deploy_production

build:
  stage: build
  script:
    - ./build.sh
  artifacts:
    paths:
      - build/

deploy_staging:
  stage: deploy_staging
  script:
    - ./deploy.sh staging
  environment:
    name: staging
    url: https://staging.example.com
    on_stop: stop_staging
  only:
    - main

stop_staging:
  stage: deploy_staging
  script:
    - ./cleanup.sh staging
  environment:
    name: staging
    action: stop
  when: manual

deploy_production:
  stage: deploy_production
  script:
    - ./deploy.sh production
  environment:
    name: production
    url: https://www.example.com
  when: manual
  only:
    - main
  needs:
    - deploy_staging

Use Case 4: Terraform Infrastructure Deployment

stages:
  - validate
  - plan
  - apply

variables:
  TF_ROOT: ${CI_PROJECT_DIR}/terraform
  TF_STATE_NAME: default

.terraform:
  image: hashicorp/terraform:latest
  before_script:
    - cd ${TF_ROOT}
    - terraform init -backend-config="address=${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}"

validate:
  extends: .terraform
  stage: validate
  script:
    - terraform validate
    - terraform fmt -check

plan:
  extends: .terraform
  stage: plan
  script:
    - terraform plan -out=plan.tfplan
  artifacts:
    paths:
      - ${TF_ROOT}/plan.tfplan
    expire_in: 1 day

apply:
  extends: .terraform
  stage: apply
  script:
    - terraform apply -auto-approve plan.tfplan
  dependencies:
    - plan
  when: manual
  only:
    - main
  environment:
    name: production

Use Case 5: Monorepo with Selective Job Execution

workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_COMMIT_BRANCH == "main"'

variables:
  FRONTEND_PATH: "apps/frontend"
  BACKEND_PATH: "apps/backend"

.changes_frontend: &changes_frontend
  changes:
    - "${FRONTEND_PATH}/**/*"
    - "package.json"
    - ".gitlab-ci.yml"

.changes_backend: &changes_backend
  changes:
    - "${BACKEND_PATH}/**/*"
    - "requirements.txt"
    - ".gitlab-ci.yml"

build_frontend:
  stage: build
  image: node:16
  script:
    - cd $FRONTEND_PATH
    - npm ci
    - npm run build
  rules:
    - <<: *changes_frontend

build_backend:
  stage: build
  image: python:3.9
  script:
    - cd $BACKEND_PATH
    - pip install -r requirements.txt
    - python -m pytest
  rules:
    - <<: *changes_backend

deploy_all:
  stage: deploy
  script:
    - ./deploy-all.sh
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
      changes:
        - "${FRONTEND_PATH}/**/*"
        - "${BACKEND_PATH}/**/*"

-...

Buenas prácticas

  • Uso cache_ para dependencias y artifacts para salidas de construcción: Cache acelera las operaciones de tuberías posteriores almacenando dependencias como node_modules/, mientras que los artefactos pasan las salidas de construcción entre etapas. Nunca construyen artefactos de caché.

Implementar reglas de flujo de trabajo adecuadas para evitar operaciones de tubería innecesarias: Utilice workflow:rules para controlar cuando se ejecutan los oleoductos, evitando los desperdicios en los proyectos de RM o solo los cambios de documentación. Esto ahorra recursos de corredor y reduce los costos.

  • Tag corredores y trabajos adecuadamente: Use etiquetas específicas (docker, kubernetes_, gpu__) para encaminar trabajos a corredores apropiados. Esto asegura que los puestos de trabajo se ejecuten en infraestructura con las capacidades necesarias y evita la contención de recursos.

  • Use needs__ palabra clave para tuberías DAG: En lugar de etapas secuenciales, utilice needs: para crear gráficos acíclicos dirigidos (DAGs) que ejecutan trabajos tan pronto como las dependencias completan, reduciendo significativamente el tiempo total de tubería.

  • ** Datos confidenciales en variables CI/CD, nunca en código**: Utilice variables protegidas y enmascaradas para secretos como claves de API, contraseñas y fichas. Permitir la protección para restringir el acceso a las ramas/tags protegidas solamente.

Implement security scan early in the pipeline: Incluya SAST, análisis de dependencia y escaneo de contenedores en etapas tempranas. Utilice allow_failure: true inicialmente para evitar bloquear el desarrollo mientras los equipos abordan los hallazgos.

Use only:changes_ o rules:changes_ para monorepos*: Los trabajos de desencadenación sólo cuando los archivos relevantes cambian, evitando las construcciones y pruebas innecesarias. Esto es crítico para los monorepos grandes con múltiples aplicaciones.

  • Tiempo de caducidad apropiado del artefacto: Fabricación predeterminada a corto plazo (1-7 días) para ahorrar costes de almacenamiento. Use expire_in: never sólo para los artefactos de liberación que necesitan retención permanente.

El aprendizaje incluye y plantillas para configuración DRY: Crear plantillas reutilizables en repositorios separados e incluirlas usando include:project o include:remote_. Esto garantiza la coherencia entre los proyectos.

  • ** Capacidad y escala de corredores de monitor adecuadamente**: Seguimiento de horarios de búsqueda y tiempos de espera de trabajo. Configure concurrent__ setting in config.toml basado en los recursos disponibles, y los corredores de escala horizontalmente durante los tiempos máximos.

-...

Troubleshooting

Issue Solution
Runner not picking up jobs Verify runner is active: INLINE_CODE_75. Check runner tags match job tags. Ensure runner isn't paused in GitLab UI. Check INLINE_CODE_76 setting in INLINE_CODE_77.
"This job is stuck" error No runner available with matching tags. Either add tags to job, register runner with those tags, or enable INLINE_CODE_78 in runner config.
Docker-in-Docker (DinD) permission errors Add INLINE_CODE_79 to runner config or use Docker socket binding: INLINE_CODE_80. Ensure runner has proper permissions.
Cache not working between jobs Verify cache key is consistent: use INLINE_CODE_81 or file-based keys. Check cache storage configuration (S3, GCS, etc.). Ensure INLINE_CODE_82 is set correctly (INLINE_CODE_83 for read/write).
Pipeline fails with "yaml invalid" Validate syntax with INLINE_CODE_84 or GitLab's CI Lint tool (CI/CD > Pipelines > CI Lint). Check indentation (use spaces, not tabs). Verify all required fields are present.
Artifacts not available in downstream jobs Use INLINE_CODE_85 or INLINE_CODE_86 to explicitly declare artifact dependencies. Check artifact paths are correct. Verify artifacts haven't expired (INLINE_CODE_87).
Jobs timing out Increase timeout in job definition: INLINE_CODE_88. Check for hanging processes. Review runner's INLINE_CODE_89 setting if system resources are exhausted.
"Cannot connect to Docker daemon" error Ensure Docker service is running on runner host. For Docker executor, add INLINE_CODE_90. For DinD, use INLINE_CODE_91 service.
Kubernetes runner pods failing to start Check namespace exists and runner has permissions. Verify resource requests/limits. Review pod logs: INLINE_CODE_92. Check image pull secrets for private registries.
Variables not being passed to jobs Check variable scope (project, group, instance). Ensure variables aren't masked when trying to print them. For protected variables, job must run on protected branch/tag. Use INLINE_CODE_93 prefix: INLINE_CODE_94.
Runner registration token invalid Token may have expired or been revoked. Get new token from GitLab UI: Settings > CI/CD > Runners. For project runners, use project-specific token. For group/instance runners, use appropriate token.
High runner CPU/memory usage Reduce INLINE_CODE_95 value in INLINE_CODE_96. Implement job resource limits. Use INLINE_CODE_97 to reduce redundant downloads. Consider distributing load across multiple runners.
SSL certificate verification failures Add INLINE_CODE_98 to runner config (not recommended for production). Install proper CA certificates. Use INLINE_CODE_99 variable to specify CA bundle.

-...

Importantes variables CI/CD

Variable Description
INLINE_CODE_100 Full commit SHA that triggered the pipeline
INLINE_CODE_101 First 8 characters of commit SHA
INLINE_CODE_102 Branch or tag name
INLINE_CODE_103 Lowercase branch/tag name, suitable for URLs
INLINE_CODE_104 Unique project ID in GitLab
INLINE_CODE_105 Project name
INLINE_CODE_106 Project namespace with project name
INLINE_CODE_107 Unique pipeline ID
INLINE_CODE_108 Unique job ID
INLINE_CODE_109 Token for authenticating with GitLab API
INLINE_CODE_110 GitLab Container Registry address
INLINE_CODE_111 Full image path for project's container registry
INLINE_CODE_112 Username for container registry authentication
INLINE_CODE_113 Password for container registry authentication
CI_ENVIRONMENT_NAME_ Silencio Nombre del medio ambiente (si)