Triển khai CI/CD với GitHub Actions
2025/02/26
CI/CD (Continuous Integration & Continuous Deployment) giúp tự động hóa việc build, test, và deploy code một cách nhanh chóng và hiệu quả. GitHub Actions là một công cụ mạnh mẽ giúp bạn thiết lập CI/CD ngay trong GitHub repository.
Tạo Workflow CI/CD với GitHub Actions
GitHub Actions sử dụng workflow files để định nghĩa các bước thực hiện CI/CD. Các file này được lưu trong thư mục .github/workflows/
trong từng repository của bạn.
Tạo file workflow
Trong project của bạn, tạo một file mới:
📂 .github/workflows/node-ci.yml
name: Github Actions
on:
push:
branches: [develop]
pull_request:
branches: [develop]
jobs:
build-job:
timeout-minutes: 10
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [lts, 20]
container:
image: node:${{ matrix.node-version }}
options: --user root
volumes:
- .:/app
steps:
- name: Check out repository code
uses: actions/checkout@v4
- name: Install packages
run: npm ci --unsafe-perm=true --allow-root
- name: Build
run: npm run generate
- name: Upload dist folder as artifact
if: github.event_name == 'push' && github.ref == 'refs/heads/develop' && matrix.node-version == 'lts'
uses: actions/upload-artifact@v4
with:
name: dist-${{ matrix.node-version }}-${{ github.run_id }}
path: dist/
retention-days: 1
Giải thích file workflow:
on: push
: Kích hoạt khi có push lên branchdevelop
.on: pull_request
: Kích hoạt khi có pull request mới được tạo vào nhánh basedevelop
.jobs: build-job
: Tên công việc được thực hiện ở tác vụ CICD này.timeout-minutes: 10
: Số phút tối đa mà công việc có thể chạy trước khi Github hủy nó, mặc định sẽ là 360.runs-on: ubuntu-latest
: Chỉ định môi trường chạy là Ubuntu mới nhấtstrategy.matrix.node-version: [lts, 20]
: Matrix Strategy cho phép chạy workflow trên nhiều phiên bản Node.js khác nhau, ở đây workflow sẽ chạy với phiên bản lts và 20container.image: node:${{ matrix.node-version }}
: Chạy workflow trong container Node.js với phiên bản tương ứng trong matrix.node-version.options: --user root
: Chạy container với quyền root để có thể cài đặt thêm package hoặc chỉnh sửa file hệ thống nếu cần.volumes: - .:/app
: Mount thư mục hiện tại(.)
vào đường dẫn/app
bên trong container, giúp truy cập mã nguồn của dự án từ trong container.
Các bước trong steps
:
- Check out repository code từ GitHub.
- Install packages sử dụng lệnh
npm ci --unsafe-perm=true --allow-root
bạn có thể tìm hiểu cách sử dụngnpm ci
What does unsafe-perm in npm actually do?, npm sudo global installation & unsafe-perm - Stack Overflow, What the heck is npm unsafe perm - Vinay Raghu - Build project.
- Upload dist folder as artifact nếu
event
là push vào nhánh develop vàmatrix.node-version == 'lts'
Deploy lên Amazon S3 và CloudFront
Ngoài việc deploy lên server, bạn có thể sử dụng AWS S3 và CloudFront để lưu trữ và phân phối ứng dụng.
Cấu hình AWS Credentials
Vào GitHub Repository → Settings → Secrets and Variables → Actions → New repository secret và thêm:
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_REGION
S3_BUCKET_NAME
💡 Mẹo:
AWS_ACCESS_KEY_ID
,AWS_SECRET_ACCESS_KEY
vàAWS_REGION
được tạo ở phần security credentials > access key trong IAM user
Chỉnh sửa workflow để deploy lên S3
Cập nhật file .github/workflows/node-ci.yml
:
deploy-job:
timeout-minutes: 10
needs: build-job
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/develop'
steps:
- name: Download dist artifact
uses: actions/download-artifact@v4
with:
name: dist-lts-${{ github.run_id }}
path: ./dist
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Deploy static site to S3 bucket
run: |
aws s3 sync ./dist s3://${{ secrets.S3_BUCKET_NAME }} --delete
- name: Update index.html cache settings
run: |
aws s3 sync s3://${{ secrets.S3_BUCKET_NAME }}/ s3://${{ secrets.S3_BUCKET_NAME }}/ \
--exclude "*" --include "index.html" \
--cache-control "max-age=0, s-maxage=2592000, must-revalidate" \
--content-type 'text/html' \
--metadata-directive REPLACE
Invalidate CloudFront Cache
Để cập nhật nội dung nhanh chóng, thêm bước:
- name: Invalidate CloudFront cache
run: |
aws cloudfront create-invalidation --distribution-id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} --paths "/*" >/dev/null
💡 Mẹo:
CLOUDFRONT_DISTRIBUTION_ID
cần được thêm vào GitHub Secrets. Khi có thay đổi, nội dung trên CloudFront sẽ được cập nhật ngay.
Kết luận
GitHub Actions giúp tự động hóa quá trình triển khai ứng dụng, giảm thiểu lỗi và tăng tốc độ phát triển. Bạn có thể mở rộng CI/CD với các bước kiểm tra mã nguồn (Lint), chạy test (Jest), thông báo Slack, v.v.
🚀 Giờ đây, mỗi lần push lên develop
, ứng dụng của bạn sẽ tự động được build và deploy lên S3 và CloudFront!
Cảm ơn tài liệu tham khảo từ 💓
Lưu ý: Tất cả các bài viết trên blog này được viết dựa trên kinh nghiệm cá nhân và quá trình tìm hiểu của mình. Mình hy vọng chúng có thể giúp ích cho bạn trong công việc và học tập, nhưng hãy xem đây như một nguồn tham khảo thay vì hướng dẫn tuyệt đối. Công nghệ luôn thay đổi, mỗi dự án có những đặc thù riêng, vì vậy bạn nên kiểm tra, thử nghiệm và điều chỉnh cho phù hợp với nhu cầu thực tế. Nếu có góp ý hay câu hỏi, đừng ngần ngại chia sẻ nhé!