GitLab CI/CD
Automate your software delivery pipeline with GitLab's integrated CI/CD system.
When to Use This Skill
Use this skill when:
- Setting up CI/CD pipelines in GitLab
- Configuring GitLab runners (shared or self-hosted)
- Creating multi-stage deployment pipelines
- Implementing GitLab Auto DevOps
- Managing CI/CD variables and secrets
Prerequisites
- GitLab repository (gitlab.com or self-hosted)
- Basic understanding of YAML
- For self-hosted runners: Linux server or Kubernetes cluster
Pipeline Configuration
Create .gitlab-ci.yml in repository root:
yamlstages: - build - test - deploy variables: NODE_VERSION: "20" build: stage: build image: node:${NODE_VERSION} script: - npm ci - npm run build artifacts: paths: - dist/ expire_in: 1 hour test: stage: test image: node:${NODE_VERSION} script: - npm ci - npm test coverage: '/Coverage: \d+\.\d+%/' deploy: stage: deploy script: - ./deploy.sh environment: name: production url: https://example.com only: - main
Job Configuration
Rules-Based Execution
yamldeploy: script: ./deploy.sh rules: - if: $CI_COMMIT_BRANCH == "main" when: manual - if: $CI_PIPELINE_SOURCE == "merge_request_event" when: never - when: on_success
Parallel Jobs
yamltest: stage: test parallel: 3 script: - npm test -- --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL
Matrix Builds
yamltest: stage: test parallel: matrix: - NODE_VERSION: ["18", "20", "22"] OS: ["alpine", "slim"] image: node:${NODE_VERSION}-${OS} script: - npm test
Caching
yamlcache: key: files: - package-lock.json paths: - node_modules/ policy: pull-push build: cache: key: build-cache paths: - .cache/ policy: pull
Artifacts
yamlbuild: artifacts: paths: - dist/ - coverage/ reports: junit: junit.xml coverage_report: coverage_format: cobertura path: coverage/cobertura.xml expire_in: 1 week when: always
Environments and Deployments
yamldeploy_staging: stage: deploy script: - deploy --env staging environment: name: staging url: https://staging.example.com on_stop: stop_staging stop_staging: stage: deploy script: - undeploy --env staging environment: name: staging action: stop when: manual
Docker Builds
yamlbuild_image: stage: build image: docker:24 services: - docker:24-dind variables: DOCKER_TLS_CERTDIR: "/certs" script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA . - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
GitLab Runners
Install Runner
bash# Download and install curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash sudo apt install gitlab-runner # Register runner sudo gitlab-runner register \ --url https://gitlab.com/ \ --registration-token TOKEN \ --executor docker \ --docker-image alpine:latest
Runner Configuration
toml# /etc/gitlab-runner/config.toml [[runners]] name = "docker-runner" url = "https://gitlab.com/" token = "TOKEN" executor = "docker" [runners.docker] image = "alpine:latest" privileged = true volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock"]
Runner Tags
yamlbuild: tags: - docker - linux script: - make build
CI/CD Variables
Protected Variables
Define in Settings > CI/CD > Variables:
AWS_ACCESS_KEY_ID(protected, masked)AWS_SECRET_ACCESS_KEY(protected, masked)
Using Variables
yamldeploy: script: - aws s3 sync dist/ s3://$S3_BUCKET variables: AWS_DEFAULT_REGION: us-east-1
Include and Extend
Include Templates
yamlinclude: - template: Security/SAST.gitlab-ci.yml - project: 'group/shared-ci' file: '/templates/deploy.yml' - local: '/ci/jobs.yml'
Extend Jobs
yaml.base_job: image: node:20 before_script: - npm ci build: extends: .base_job script: - npm run build test: extends: .base_job script: - npm test
Multi-Project Pipelines
yamltrigger_downstream: stage: deploy trigger: project: group/downstream-project branch: main strategy: depend
Common Issues
Issue: Pipeline Stuck
Problem: Jobs stay pending Solution: Check runner availability and tags matching
Issue: Docker-in-Docker Fails
Problem: Cannot connect to Docker daemon
Solution: Use docker:dind service with proper TLS configuration
Issue: Cache Not Working
Problem: Cache misses between jobs Solution: Verify cache key and ensure runners share distributed cache
Best Practices
- Use
rulesinstead ofonly/exceptfor complex conditions - Leverage GitLab's built-in security scanning templates
- Use job dependencies to optimize pipeline speed
- Implement review apps for merge requests
- Cache dependencies aggressively
- Use artifacts for passing data between stages
Related Skills
- github-actions - GitHub CI/CD alternative
- argocd-gitops - GitOps deployments
- container-registries - Registry management


