Claude
Skills
Sign in
Back

gitlab-ci

Included with Lifetime
$97 forever

Configure GitLab CI/CD pipelines and runners for automated building, testing, and deployment. Create .gitlab-ci.yml configurations, manage runners, and implement DevOps workflows. Use when working with GitLab repositories or self-hosted GitLab instances.

Cloud & DevOps

What this skill does


# 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:

```yaml
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

```yaml
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

```yaml
test:
  stage: test
  parallel: 3
  script:
    - npm test -- --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL
```

### Matrix Builds

```yaml
test:
  stage: test
  parallel:
    matrix:
      - NODE_VERSION: ["18", "20", "22"]
        OS: ["alpine", "slim"]
  image: node:${NODE_VERSION}-${OS}
  script:
    - npm test
```

## Caching

```yaml
cache:
  key:
    files:
      - package-lock.json
  paths:
    - node_modules/
  policy: pull-push

build:
  cache:
    key: build-cache
    paths:
      - .cache/
    policy: pull
```

## Artifacts

```yaml
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

```yaml
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

```yaml
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

```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

```yaml
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

```yaml
deploy:
  script:
    - aws s3 sync dist/ s3://$S3_BUCKET
  variables:
    AWS_DEFAULT_REGION: us-east-1
```

## Include and Extend

### Include Templates

```yaml
include:
  - 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

```yaml
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-actions/) - GitHub CI/CD alternative
- [argocd-gitops](../../orchestration/argocd-gitops/) - GitOps deployments
- [container-registries](../../containers/container-registries/) - Registry management

Related in Cloud & DevOps