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:
stages:
- 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
deploy: 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
test: stage: test parallel: 3 script: - npm test -- --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL
Matrix Builds
test: stage: test parallel: matrix: - NODE_VERSION: ["18", "20", "22"] OS: ["alpine", "slim"] image: node:${NODE_VERSION}-${OS} script: - npm test
Caching
cache: key: files: - package-lock.json paths: - node_modules/ policy: pull-push
build: cache: key: build-cache paths: - .cache/ policy: pull
Artifacts
build: 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
deploy_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
build_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
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
/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
build: 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
deploy: script: - aws s3 sync dist/ s3://$S3_BUCKET variables: AWS_DEFAULT_REGION: us-east-1
Include and Extend
Include Templates
include:
- template: Security/SAST.gitlab-ci.yml
- project: 'group/shared-ci' file: '/templates/deploy.yml'
- local: '/ci/jobs.yml'
Extend Jobs
.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
trigger_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 rules instead of only/except for 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