Phần 9 — Pipeline thực tế Next.js → Docker → K8s + best practices + debug
Ý kiến
0
Chưa có ý kiến nào. Hãy là người đầu tiên chia sẻ!
Chưa có ý kiến nào. Hãy là người đầu tiên chia sẻ!
Khai báo environment để GitLab theo dõi deployments, có lịch sử và nút rollback. Review Apps — tính năng signature: mỗi MR tự deploy lên môi trường tạm.
Tái sử dụng pipeline giữa nhiều dự án với include (local, project, template, remote), kế thừa job với extends (hidden job), và YAML anchors.
Scale CI bằng Kubernetes executor: mỗi job sinh ra một pod, chạy xong huỷ. Triển khai GitLab Runner Helm chart trên K8s cluster.
Series GitLab CI/CD Toàn Tập — 9 phần:
Phần 1 — Tổng quan: GitLab CI/CD, kiến trúc và các khái niệm
Phần 2 — .gitlab-ci.yml đầu tiên và Variables (predefined, UI, masked)
Phần 5 — GitLab Runner self-hosted: cài đặt và executors (Shell/Docker)
Phần 9 — Pipeline thực tế Next.js → Docker → K8s + best practices + debug ← bạn đang đọc
Phần cuối series — gộp ba chủ đề bắt buộc cho mọi pipeline chạy production: pipeline thực tế Next.js → Docker (DinD + buildx cache registry) → K8s (kubectl set image + rollout), best practices vận hành (interruptible, needs, workflow rules, resource_group), và debug khi pipeline lỗi (CI Lint, pipeline visualizer, CI_DEBUG_TRACE).
Pipeline production hoàn chỉnh: test, build Docker image, push lên GitLab Container Registry, deploy lên K8s, có manual approval cho production.
stages:
- test
- build
- deploy
default:
image: node:20-alpine
variables:
IMAGE: $CI_REGISTRY_IMAGE
TAG: $CI_COMMIT_SHORT_SHA
# ---------- TEST ----------
lint:
stage: test
cache:
key:
files: [pnpm-lock.yaml]
paths: [.pnpm-store/]
before_script:
- corepack enable
- pnpm config set store-dir .pnpm-store
- pnpm install --frozen-lockfile
script:
- pnpm lint
unit-test:
stage: test
cache:
key:
files: [pnpm-lock.yaml]
paths: [.pnpm-store/]
policy: pull
before_script:
- corepack enable
- pnpm install --frozen-lockfile
script:
- pnpm test --reporter=junit --output=junit.xml
artifacts:
when: always
reports:
junit: junit.xml
# ---------- BUILD ----------
build-image:
stage: build
image: docker:24
services:
- docker:24-dind
variables:
DOCKER_TLS_CERTDIR: ""
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- docker buildx build
--cache-from type=registry,ref=$IMAGE:cache
--cache-to type=registry,ref=$IMAGE:cache,mode=max
--tag $IMAGE:$TAG
--tag $IMAGE:latest
--push .
rules:
- if: $CI_COMMIT_BRANCH == "main"
- if: $CI_COMMIT_TAG
# ---------- DEPLOY ----------
.deploy-template:
stage: deploy
image: alpine/k8s:1.30
before_script:
- kubectl config use-context $CI_PROJECT_PATH:agent
script:
- kubectl set image deployment/myapp myapp=$IMAGE:$TAG -n $K8S_NAMESPACE
- kubectl rollout status deployment/myapp -n $K8S_NAMESPACE --timeout=3m
deploy-staging:
extends: .deploy-template
variables:
K8S_NAMESPACE: staging
environment:
name: staging
url: https://staging.example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
deploy-production:
extends: .deploy-template
variables:
K8S_NAMESPACE: production
environment:
name: production
url: https://example.com
deployment_tier: production
resource_group: production
rules:
- if: $CI_COMMIT_TAG
when: manual
allow_failure: false
Phân tích:
Stage test chạy lint & unit test song song trên image node:20-alpine, share cache pnpm qua key dựa trên lockfile.
Stage build dùng Docker-in-Docker (DinD) để build image. Cache layer được lưu trực tiếp trong container registry, lần build sau chỉ mất 30s nếu code không đổi nhiều.
Stage deploy: deploy-staging chạy tự động khi merge vào main; deploy-production chỉ chạy khi tạo tag (v1.2.3) và bắt buộc manual approval — tránh deploy production nhầm.
resource_group: production đảm bảo nếu 2 tag được push gần nhau, deploy sẽ tuần tự.
Pin version: image (node:20.18.0-alpine), template (ref: 'v1.2.0'), runner version. Tránh "hôm qua chạy được, hôm nay fail".
Đặt interruptible: true cho job CI: khi push commit mới đè lên, GitLab tự huỷ pipeline cũ — tiết kiệm tài nguyên.
default:
interruptible: true
deploy-prod:
interruptible: false # Deploy thì không được huỷ giữa chừng
Tách job nhẹ trước, job nặng sau: lint < unit test < integration test < build < deploy. Fail sớm = tiết kiệm phút build.
Dùng needs: để vượt stage: job chỉ phụ thuộc 1-2 job, không cần đợi cả stage trước hoàn tất.
deploy-frontend:
stage: deploy
needs: [build-frontend] # Khởi chạy ngay khi build-frontend xong
script: ./deploy-fe.sh
Đặt timeout: cho job để tránh runner bị chiếm vô hạn.
Mask + Protect secret: token, password, key đều phải bật cả 2 flag.
Hạn chế privileged: true: chỉ bật khi thực sự cần DinD. Privileged container = root host.
Dùng workflow: để chặn pipeline trùng lặp:
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
- if: $CI_COMMIT_TAG
- when: never # Skip mọi branch push khác
Giới hạn artifacts: đặt expire_in ngắn (1 week), tránh lưu file lớn (vd Docker image — đẩy lên registry thay vì artifact).
Theo dõi quota CI minutes: trên GitLab.com xem ở Settings → Usage Quotas. Vượt quota = chạy lậu trên shared runner sẽ bị chặn.
CI Lint: CI/CD → Editor → Lint kiểm tra cú pháp YAML và inheritance trước khi push.
Pipeline visualizer: tab Pipeline cho phép xem DAG, dependencies, thời gian từng job.
Retry job: bấm vào job lỗi → "Retry" thay vì retry cả pipeline.
Re-run với debug log: thêm vào job lỗi:
variables:
CI_DEBUG_TRACE: "true"
⚠️ Cẩn thận — log sẽ in cả biến môi trường, kể cả masked variable. Chỉ bật khi private repo, sau đó xoá log.
Chạy local với gitlab-runner exec (deprecated trong v17 nhưng vẫn dùng được trên các version cũ): giả lập job ngay trên máy.
Shell into runner: SSH vào VPS chạy runner, xem /var/log/gitlab-runner.log để debug lỗi cài đặt.
Trong phần này bạn đã nắm:
Pipeline 3-stage hoàn chỉnh: test (lint, junit) → build (DinD + buildx cache registry) → deploy (kubectl set image + rollout status).
Cache Docker layer trong registry: --cache-from type=registry,ref=$IMAGE:cache + --cache-to ...,mode=max — giảm thời gian build 5 phút xuống ~30s.
Best practices: interruptible: true (huỷ pipeline cũ khi push commit mới), needs: để skip stage barrier, workflow.rules chặn duplicate pipeline, mask + protect mọi secret.
Debug: CI Lint kiểm tra YAML trước push, pipeline visualizer xem DAG, CI_DEBUG_TRACE: "true" trên job riêng lẻ (cẩn thận — log lộ cả masked vars).
Cảm ơn bạn đã theo dõi 9 phần series. GitLab CI/CD vượt trội ở 3 điểm: tích hợp đồng bộ, executor đa dạng, và Review Apps. Áp dụng vào dự án thật, hãy bắt đầu từ pipeline 3-stage cơ bản (test/build/deploy) rồi mở rộng dần với rules, environments và resource_group khi đội trưởng thành.
Đây là phần cuối series. Cảm ơn bạn đã theo dõi! Quay lại Phần 1 nếu cần đọc lại từ đầu.