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 yartifactspara salidas de construcción: Cache acelera las operaciones de tuberías posteriores almacenando dependencias comonode_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, utiliceneeds: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: neversó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 inconfig.tomlbasado 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) |