Phiên bản: Go 1.22.4
Cập nhật lần cuối: 26/03/2026
Phạm vi: Quy trình triển khai Production của API Backend, bao gồm kiến trúc Build-Deploy tách biệt, quy trình CI/CD trên AWS và hướng dẫn rollback khẩn cấp.
1. Kiến Trúc Triển Khai Production#
1.1. Nguyên Tắc Thiết Kế#
Môi trường Production áp dụng kiến trúc tách biệt hoàn toàn giữa giai đoạn Build và giai đoạn Deploy:Giai đoạn Build diễn ra trên Bastion Build Server — máy chủ trung gian chuyên dụng. Máy này có Go toolchain, Docker và quyền truy cập AWS ECR.
Giai đoạn Deploy diễn ra trên Production Server (AWS EC2). Máy này không có Go toolchain, không có mã nguồn, chỉ kéo Docker image từ ECR và chạy.
Lợi ích của kiến trúc này:Production Server không bao giờ chứa mã nguồn Go hay Go toolchain, giảm thiểu bề mặt tấn công.
Docker image được build một lần và deploy nhiều lần, đảm bảo tính nhất quán.
Có thể rollback về bất kỳ phiên bản nào bằng cách chỉ định tag commit cụ thể.
Build server có thể được tắt khi không cần thiết để tiết kiệm chi phí.
1.2. Luồng Triển Khai Tổng Quan#
Khi developer merge code vào nhánh master:GitLab CI kích hoạt pipeline với hai stage tuần tự: build-master và deploy-master.
Stage build-master kết nối SSH đến Bastion Build Server, pull code mới nhất, build Docker image đa kiến trúc (arm64 + amd64) và push lên AWS ECR.
Stage deploy-master kết nối SSH đến Production Server, kéo image mới từ ECR và khởi động lại container.
2. Giai Đoạn Build (build-master)#
2.1. Cấu Hình Pipeline#
2.2. Xác Thực SSH Đến Bastion Build Server#
BASTION_BUILD_KEY là SSH private key (base64 encoded) được lưu trong GitLab CI/CD Variables Protected. Key này chỉ có quyền truy cập Bastion Build Server.2.3. Đăng Nhập AWS ECR#
AWS ECR token có hiệu lực 12 giờ. Lệnh này lấy token mới và đăng nhập Docker vào ECR registry.2.4. Cập Nhật Mã Nguồn#
2.5. Build Docker Image Đa Kiến Trúc#
Giải thích các tham số quan trọng:--cache-from $TAG_LATEST — Tận dụng layer cache từ image cũ. Các layer không thay đổi (Go base image, go mod download) được tái sử dụng, giảm thời gian build từ 10 phút xuống còn 2-3 phút.
--platform linux/arm64,linux/amd64 — Build cho cả chip ARM (AWS Graviton) và x86_64. Đảm bảo image chạy được trên mọi loại EC2 instance.
-t $TAG_LATEST — Tag latest để deploy nhanh.
-t $TAG_COMMIT — Tag theo commit hash ($CI_COMMIT_SHORT_SHA) để rollback về phiên bản cụ thể.
--push — Push image lên ECR ngay sau khi build xong.
2.6. Biến CI/CD Cho Build#
| Biến | Mô Tả |
|---|
AWS_REGION | ap-southeast-1 (Singapore) |
AWS_ACCOUNT_ID | 211125536219 |
AWS_ECR | $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com |
IMAGE_NAME | traffic/api-prod |
PLATFORM | linux/arm64,linux/amd64 |
TAG_LATEST | $AWS_ECR/$IMAGE_NAME:latest |
TAG_COMMIT | $AWS_ECR/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA |
3. Giai Đoạn Deploy (deploy-master)#
3.1. Cấu Hình Pipeline#
3.2. Lấy IP Production Server Động#
Kỹ thuật lấy IP qua AWS tag thay vì hardcode IP giúp pipeline hoạt động đúng ngay cả khi EC2 instance bị thay thế hoặc IP thay đổi.3.3. Quy Trình Deploy Trên Production Server#
Giải thích tham số docker-compose up:--force-recreate — Buộc tạo lại container ngay cả khi cấu hình không thay đổi. Đảm bảo container mới luôn sử dụng image mới nhất.
--remove-orphans — Xóa các container không còn được định nghĩa trong docker-compose.yml.
4. Quản Lý Image Trên AWS ECR#
4.1. Cấu Trúc Tag#
| Tag | Ví Dụ | Mô Tả |
|---|
latest | ...amazonaws.com/traffic/api-prod:latest | Image mới nhất, luôn được cập nhật sau mỗi lần build. |
| Commit hash | ...amazonaws.com/traffic/api-prod:b5f8r7w2 | Image của một commit cụ thể, dùng để rollback. |
4.2. Xem Danh Sách Image Trên ECR#
4.3. Thông Tin ECR Repository#
Repository name: traffic/api-prod
Full URI: 211125536219.dkr.ecr.ap-southeast-1.amazonaws.com/traffic/api-prod
5. Quy Trình Rollback Khẩn Cấp#
5.1. Khi Nào Cần Rollback#
Sau khi deploy, API trả về lỗi 500 liên tục.
Cron job không chạy hoặc chạy sai.
Kết nối database bị lỗi sau khi deploy.
Tính năng mới gây ra hành vi không mong muốn ảnh hưởng đến vận hành.
5.2. Quy Trình Rollback Nhanh#
Bước 1 — Xác định commit hash của phiên bản ổn định:Bước 2 — Đăng nhập SSH vào Production Server:Bước 3 — Cập nhật docker-compose.yml để dùng image cũ:Mở file docker-compose.yml và thay đổi tag image từ latest sang commit hash cụ thể:Bước 4 — Kéo image cũ và khởi động lại:Bước 5 — Xác nhận rollback thành công:Toàn bộ quy trình rollback có thể hoàn thành trong vòng 2 phút nếu image cũ đã có trong local cache của Production Server.5.3. Rollback Qua GitLab Pipeline#
Cách rollback an toàn hơn là revert commit trên GitLab:Pipeline sẽ tự động build và deploy phiên bản đã revert. Cách này mất nhiều thời gian hơn (5-10 phút) nhưng đảm bảo lịch sử Git sạch và có thể audit.
6. Giám Sát Sau Khi Deploy#
6.1. Kiểm Tra Ngay Sau Deploy#
Gọi GET / và nhận response {"message": "Hello, World!"}.
Đăng nhập với tài khoản test và nhận JWT token.
Gọi GET /api/user/profile với token và nhận thông tin user.
Kiểm tra log container không có lỗi panic.
Kiểm tra cron job đã khởi động: All cronjobs initialized successfully.
6.2. Theo Dõi Log Container#
6.3. Kiểm Tra Tài Nguyên Server#
6.4. Kiểm Tra Log Trong Container#
7. Bảo Mật Trong Môi Trường Production#
7.1. Quản Lý Secret#
Tất cả thông tin nhạy cảm được lưu trong GitLab CI/CD Variables với chế độ Protected và Masked:SSH private keys được lưu dạng base64 encoded.
AWS credentials được lưu dưới dạng biến riêng biệt.
Không có secret nào được hardcode trong .gitlab-ci.yml hay Dockerfile.
7.2. Nguyên Tắc Least Privilege#
SSH key của Bastion Build Server chỉ có quyền truy cập Bastion, không có quyền truy cập Production Server.
SSH key của Production Deploy chỉ có quyền truy cập Production Server.
AWS IAM role của Bastion Build Server chỉ có quyền push lên ECR repository traffic/api-prod.
AWS IAM role của Production Server chỉ có quyền pull từ ECR repository traffic/api-prod.
7.3. Không Lưu Mã Nguồn Trên Production Server#
Production Server chỉ chứa file docker-compose.yml và Docker image từ ECR. Không có Go toolchain, không có mã nguồn. Ngay cả khi Production Server bị xâm phạm, kẻ tấn công cũng không thể đọc mã nguồn hay sửa đổi logic ứng dụng.
8. Biến CI/CD Cần Thiết#
8.1. Danh Sách Biến Bắt Buộc#
| Biến | Phạm Vi | Mô Tả |
|---|
BASTION_BUILD_KEY | Protected | SSH private key (base64) để kết nối Bastion Build Server. |
BASTION_BUILD_USER | Protected | Username SSH của Bastion Build Server. |
BASTION_BUILD_IP | Protected | Địa chỉ IP của Bastion Build Server. |
BASTION_BUILD_PORT | Protected | Port SSH của Bastion Build Server. |
AWS_TRAFFIC_PROD_KEY | Protected | SSH private key (base64) để kết nối Production Server. |
AWS_TRAFFIC_PROD_USER | Protected | Username SSH của Production Server. |
AWS_TRAFFIC_PROD_PORT | Protected | Port SSH của Production Server. |
AWS_ACCESS_KEY_ID | Protected, Masked | AWS Access Key ID để đăng nhập ECR. |
AWS_SECRET_ACCESS_KEY | Protected, Masked | AWS Secret Access Key để đăng nhập ECR. |
AWS_DEFAULT_REGION | Protected | AWS Region: ap-southeast-1. |
TRAFFIC_DEV_77_37_47_88_KEY | Protected | SSH key cho server Develop/Staging. |
TRAFFIC_DEV_77_37_47_88_USER | Protected | Username SSH server Develop/Staging. |
TRAFFIC_DEV_77_37_47_88_IP | Protected | IP server Develop/Staging. |
TRAFFIC_DEV_77_37_47_88_PORT | Protected | Port SSH server Develop/Staging. |
AWS_TRAFFIC_REL_KEY | Protected | SSH key cho server Release. |
AWS_TRAFFIC_REL_USER | Protected | Username SSH server Release. |
AWS_TRAFFIC_REL_PORT | Protected | Port SSH server Release. |
9. Xử Lý Sự Cố Triển Khai Production#
9.1. Pipeline Build Thất Bại#
Lỗi: Permission denied (publickey) khi kết nối Bastion:Kiểm tra biến BASTION_BUILD_KEY có được cấu hình đúng không.
Kiểm tra public key tương ứng có trong ~/.ssh/authorized_keys trên Bastion không.
Lỗi: no space left on device khi build Docker:Lỗi: go mod download thất bại:9.2. Pipeline Deploy Thất Bại#
Lỗi: Không lấy được IP Production Server:Kiểm tra AWS credentials (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) có đúng không.
Kiểm tra EC2 instance có đang chạy và có tag đúng không.
Kiểm tra IAM role có quyền ec2:DescribeInstances không.
Lỗi: docker pull thất bại:Kiểm tra Production Server có quyền pull từ ECR không.
Kiểm tra image tag có tồn tại trên ECR không.
9.3. API Không Phản Hồi Sau Deploy#
9.4. Cron Job Không Chạy Sau Deploy#
Phải có dòng: All cronjobs initialized successfully.Nếu không có, kiểm tra biến môi trường cron trong .env của container:
10. Thông Tin AWS Services#
| Service | Mục Đích | Region |
|---|
| AWS ECR | Lưu trữ Docker image | ap-southeast-1 (Singapore) |
| AWS EC2 | Chạy Production Server | ap-southeast-1 (Singapore) |
| AWS IAM | Quản lý quyền truy cập | Global |
Tag EC2 instance Production được sử dụng để tự động lấy IP:Name: traffic-social-search-api-tool-prod
Service_Traffic: traffic-api
Modified at 2026-03-26 10:44:41