Bạn push một lần, máy tự build app, tự test, tự ship — không cần người, không còn 'để tối mình làm'.
← / → để chuyển slide · chuyển EN/VI bên dưới
Trước CI/CD, mỗi lần deploy là một sự kiện: có người phải nhớ các bước, làm theo thứ tự, rồi cầu may.
Restart server? Thay file? Chạy migration? Công thức nằm trong đầu một người và trong wiki chẳng ai cập nhật.
'Chạy trên máy mình rồi, chắc ổn.' Khi deadline dồn dập, bước test là thứ đầu tiên biến mất lặng lẽ.
Người đầu tiên thấy bug là khách hàng, trên production, lúc 2 giờ sáng. Không phải test, không phải đồng đội.
Deployment tích lũy, thay đổi to dần, và mỗi lần ship mang theo nhiều rủi ro hơn cần.
CI/CD = một pipeline tự động: hễ code thay đổi, máy tự build, tự test, tự deploy — cùng một cách, mỗi lần.
Một công thức các bước chạy tự động trên máy cloud. Bạn push code; băng chuyền lo phần còn lại.
Mỗi commit: build app và chạy test. Lỗi bị bắt trong vài phút, không phải vài tuần.
Khi test pass, đưa kết quả lên staging hay production — tự động, hoặc một cú click.
Không cần 'ngày deploy'. Mỗi push vào repo đều kích hoạt cùng một pipeline — nhỏ, thường xuyên, nhàm chán. Nhàm chán là tốt.
Hai ý tưởng, một pipeline. CI hỏi 'có an toàn không?'; CD nói 'làm cho xong'.
Build + test mỗi commit. Ngay khi thay đổi của bạn làm hỏng gì đó, pipeline đỏ và deploy dừng lại.
Mục tiêu: thay đổi nhỏ và thường xuyên; lỗi bị bắt trong vài phút.
Pipeline pass thì kết thúc bằng deployment: bản mới lên staging (hoặc thẳng tới production). Luôn cùng một con đường.
Mục tiêu: app luôn có thể deploy bất kỳ lúc nào — vì nó vừa được làm vậy.
Một push vào repo, máy chạy dọc băng chuyền từ trái sang phải. Bước nào đỏ là dừng tất cả.
Giữa 'git push' và 'đã live', máy làm bốn việc này — mỗi lần đều vậy, cùng một thứ tự.
Máy tải đúng commit bạn push — cùng byte, cùng phiên bản, không còn cảnh 'biết là phiên bản nào nữa'.
Một máy sạch cài Python và dependencies từ requirements.txt. Không còn 'chạy trên máy mình' để viện cớ.
Bộ test chạy. Một test fail = pipeline đỏ = không có gì được ship. Đây là CI đang làm việc.
App thành image container, và image mới được deploy lên server. Staging trước, production sau — tự động.
Đây là toàn bộ việc 'deploy' — một log tự cuộn trong khi bạn làm chuyện khác.
Một test fail — nên code xấu không bao giờ tới server. Bạn nhận lỗi sau vài phút, thay vì khách hàng gọi lúc 2 giờ sáng.
Trên GitHub, toàn bộ phép màu nằm trong một file: vài dòng YAML mô tả các bước.
File này nằm trong repo tại .github/workflows/. GitHub tự chạy nó mỗi khi bạn push vào main.
# runs automatically on every push
name: build-test-deploy
on:
push:
branches: [main]
jobs:
ship:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4 # 1. get the code
- run: pip install -r requirements.txt # 2. deps
- run: pytest # 3. test
- run: docker build -t myapp . # 4. build image
- run: ./deploy.sh # 5. ship it
on: push = khi nào · jobs = làm gì · steps = theo thứ tự nào.
Mọi workflow GitHub Actions đều chỉ là ba ý này. Phần còn lại là từ vựng.
'Chạy khi nào?' on: push = mỗi lần push vào repo. Các lựa chọn khác: theo lịch, khi có pull request, khi có tag.
Job là một khối việc đặt tên chạy trên máy mới — runs-on: ubuntu-latest. Ở đây, một job tên ship làm mọi thứ.
Các lệnh theo thứ tự từ trên xuống: - uses: chạy bước có sẵn (checkout), - run: chạy một lệnh shell. Bước fail đầu tiên dừng hết phần còn lại.
Bước cuối làm phần nhàm chán — viết một lần, tự chạy mãi mãi.
# deploy.sh — runs on the server
docker pull myapp:latest # newest image
docker stop web || true
docker rm web || true
docker run -d --name web -p 8080:5000 myapp:latest
curl -fsS http://127.0.0.1:8080/health
Dừng container cũ, khởi động cái mới, gõ cửa kiểm tra nó có trả lời không.
Cùng một ý tưởng, mỗi nơi một chỗ. Khóa này dùng GitHub Actions — mấy cái còn lại chỉ để bạn nhận ra khi gặp ngoài đời.
| Công cụ | Nó sống ở đâu | Cần biết gì |
|---|---|---|
| GitHub Actions | GitHub — nơi đặt repo của khóa học này | File YAML trong repo (.github/workflows/). Miễn phí cho repo public. Lựa chọn của khóa học. |
| GitLab CI | GitLab — cloud hoặc tự host | Cùng ý tưởng, cấu hình trong một file .gitlab-ci.yml. Phổ biến ở những nơi tự host. |
| Jenkins | Server của bạn — lão làng | Chương trình bạn tự cài, đã có từ khoảng 2011. Pipeline viết bằng code hoặc UI. Vẫn có mặt ở khắp các công ty lớn. |
Không chỉ vì tốc độ. Mà vì xóa bỏ cả một dạng khoảnh khắc đáng sợ của con người.
Deploy do pipeline thực hiện, không do lịch của một người hùng. Bạn push; băng chuyền lo phần còn lại.
Cùng các bước, cùng máy, cùng thứ tự — cho cả sửa 3 dòng lẫn tính năng lớn. Lặp lại giết chết 'chạy trên máy mình'.
Push → xanh hay đỏ sau vài phút. Bạn biết thay đổi của mình làm hỏng gì trước khi người dùng kịp biết.
Vì ship nhàm chán và tự động, thay đổi được giữ nhỏ và thường xuyên. Đó là cách team ship hằng ngày mà không sợ.
Một câu về cả chủ đề: máy chạy băng chuyền, bạn chỉ việc push.
git push
bước người duy nhấtcheckout → install → test → build → deploy
băng chuyềnbản mới đã live
tự động · đã test · lặp lại đượcpush → pipeline → live. Không còn ngày deploy, không còn bước quên, không còn 'chạy trên máy mình'.
push → build → test → deploy, mỗi lần thay đổi. Băng chuyền chạy; bạn ship.