---
id: cicd-gitlab
title: "GitLab CI"
shortTitle: "GitLab CI"
track: cicd
trackTitle: "CI/CD"
order: 3
level: important
status: published
estimatedMinutes: 30
prerequisites:
  - cicd-jenkins
next: cicd-azure-pipelines
reviewedAgainst: 2026-10-12
sources:
  - title: "Get started with GitLab CI/CD"
    url: https://docs.gitlab.com/ci/quick_start/
  - title: ".gitlab-ci.yml keyword reference"
    url: https://docs.gitlab.com/ci/yaml/
---

# GitLab CI

GitLab CI đọc `.gitlab-ci.yml` trong repo. Runner nhận job. Bài GitLab phía trước chỉ nói merge request. Bài này nói pipeline.

## Để làm gì

Bạn viết một file hai stage, `test` rồi `deploy`, và biết job không chạy nếu project chưa có Runner.

## Gồm những gì

- `stages`, job, `script`, `image`.
- Runner và executor.
- Khác tên với GitHub Actions: job không gọi là workflow.

Đừng đăng ký Shared Runner trả phí, và đừng đụng review app trong bài này.

## Dùng khi nào

Remote đã là GitLab. Bạn push lên nhánh, GitLab tạo pipeline nếu file YAML hợp lệ và có Runner.

Đừng copy `runs-on` của GitHub Actions vào file này. GitLab không đọc khóa đó. Job cần `script`, và image nếu executor là Docker.

## Kiến thức cốt lõi

Stage chạy theo thứ tự khai báo. Job cùng stage chạy song song nếu có nhiều Runner. Job stage sau bắt đầu khi stage trước thành công, trừ khi bạn đổi rule.

Mỗi job có `script`, một list lệnh. `image: node:24` dùng container đó làm môi trường, với Docker executor. `rules` quyết định job có vào pipeline không. `only` và `except` là cú pháp cũ, docs YAML hiện trỏ sang `rules`.

Runner là máy đã đăng ký với GitLab, giữ một token. Mất token thì gỡ Runner và đăng ký lại, đừng commit token. Tag trên Runner phải khớp `tags` trong job, không thì job pending mãi.

Biến bí mật đặt trong CI/CD variables của project, mask và protect nếu đó là secret. File YAML chỉ chứa tên biến.

## Lệnh và code mẫu

`.gitlab-ci.yml`:

```yaml
stages: [test, deploy]
test:
  stage: test
  image: node:24
  script:
    - node -e "console.log('ok')"
deploy:
  stage: deploy
  script:
    - echo "deploy chi chay sau test"
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
```

## Thực hành

1. Đọc file và ghi stage nào chạy trên mọi nhánh, stage nào chỉ trên `main`.
2. Không tạo project GitLab nếu bạn chưa có. Không dán Runner token vào file.
3. Nếu đang có project, mở CI lint trong GitLab và dán file. Lint đạt là đủ.

## Kết quả mong đợi

`test` không có `rules` nên được tạo cho pipeline thông thường. `deploy` chỉ khi nhánh là `main`.

## Checklist

- [ ] Secret nằm trong CI/CD variables, không nằm trong YAML.
- [ ] Job `pending` thì xem Runner và tag trước khi sửa `script`.
- [ ] Dùng `rules`, không thêm `only` mới.

## Lỗi thường gặp

**Pipeline không tạo.** File không ở gốc repo, hoặc nhánh không có file. GitLab chỉ đọc `.gitlab-ci.yml` trên commit vừa đẩy.

**`script` là một chuỗi nhiều dòng không có `|`.** YAML coi lệch thụt đầu dòng là lỗi. Để list, mỗi lệnh một gạch, như mẫu trên.

## Nguồn

1. [Get started with GitLab CI/CD](https://docs.gitlab.com/ci/quick_start/) — file YAML và Runner.
2. [Keyword reference](https://docs.gitlab.com/ci/yaml/) — `stages`, `script`, `rules`, `image`.

## Tiếp theo

[Azure Pipelines](./05-azure-pipelines.md)
