Phiên bản: 2.5.0
Cập nhật lần cuối: 26/03/2026
1. Tổng Quan Môi Trường Staging#
1.1. Mục Đích#
Môi trường Staging là bước kiểm thử cuối cùng trước khi đưa code lên Production. Staging chạy trên server thực với cấu hình gần giống Production, kết nối với Staging API Backend, và xử lý traffic thực từ các chiến dịch test.Staging khác với Local ở những điểm cốt lõi:Chạy trên server Linux thực, không phải máy tính cá nhân.
Triển khai hoàn toàn tự động qua GitLab CI/CD khi push lên nhánh staging-v2.
Build diễn ra trực tiếp trên server (on-server build) bằng docker compose up --build.
Chạy hai instance song song (tool-v2-01 và tool-v2-02) trên cùng một server.
Không có hot-reload, không có debugger, không có bun run dev.
Kết nối với Staging API Backend thay vì localhost:33001.
1.2. Thông Tin Server#
SSH User: Được lưu trong GitLab CI/CD Variable TRAFFIC_DEV_77_37_47_88_USER
SSH Key: Được lưu trong GitLab CI/CD Variable TRAFFIC_DEV_77_37_47_88_KEY (base64 encoded)
Server này dùng chung cho cả Develop và Staging, phân biệt bằng thư mục deploy:Develop: /home/traffic/project/traffic/dev/
Staging: /home/traffic/project/traffic/stg/
1.3. Hai Instance Song Song#
Staging chạy hai instance Tools V2 độc lập:tool-v2-01: Instance thứ nhất, thư mục /home/traffic/project/traffic/stg/tool-v2-01/.
tool-v2-02: Instance thứ hai, thư mục /home/traffic/project/traffic/stg/tool-v2-02/.
Mỗi instance có file .env riêng với cấu hình khác nhau (proxy pool, SERVER_ID, port). Điều này cho phép test đồng thời với hai cấu hình khác nhau và phát hiện race conditions.
2. Quy Trình Triển Khai Tự Động#
2.1. Kích Hoạt Pipeline#
Pipeline staging được kích hoạt khi có commit mới vào nhánh staging-v2:Hoặc tạo Merge Request từ develop-v2 vào staging-v2 trên GitLab và merge.2.2. Cấu Hình Pipeline#
2.3. Các Bước Thực Thi#
SSH key được decode từ base64 và load vào ssh-agent. StrictHostKeyChecking no được set để tránh prompt xác nhận host.Bước 2 — Cập nhật deploy wrapper (tool-v2-01):Thư mục tool-v2-01 là wrapper repo chứa docker-compose.yml và .env. Nó có submodule build/tools trỏ đến repo code chính.Bước 3 — Cập nhật code nguồn (tool-v2-01):Checkout đúng nhánh staging-v2 trong submodule.Bước 4 — Build và restart (tool-v2-01):--build rebuild Docker image từ source code mới. -d chạy detached.Bước 5 — Lặp lại cho tool-v2-02:Tương tự bước 2-4 nhưng cho thư mục tool-v2-02.Xóa các Docker images không còn được dùng để giải phóng disk space.
3. Cấu Trúc Thư Mục Trên Server#
3.1. Thư Mục Deploy#
/home/traffic/project/traffic/stg/
├── tool-v2-01/ ← Instance 01
│ ├── docker-compose.yml ← Docker Compose config
│ ├── .env ← Biến môi trường instance 01
│ └── build/
│ └── tools/ ← Submodule: source code (nhánh staging-v2)
│ ├── src/
│ ├── package.json
│ ├── tsconfig.json
│ └── ...
└── tool-v2-02/ ← Instance 02
├── docker-compose.yml
├── .env ← Biến môi trường instance 02
└── build/
└── tools/ ← Submodule: source code (nhánh staging-v2)
3.2. Kiến Trúc Submodule#
Mỗi instance là một repo riêng (wrapper repo) chứa:docker-compose.yml: Cấu hình Docker Compose cho instance đó.
.env: Biến môi trường riêng của instance.
build/tools/: Git submodule trỏ đến repo code chính tool-v2.git.
Khi deploy, pipeline cập nhật cả wrapper repo (git pull origin) và submodule (git checkout staging-v2 && git pull origin staging-v2).
4. Cấu Hình Môi Trường Staging#
4.1. Khác Biệt So Với Local#
| Biến | Local | Staging |
|---|
NODE_ENV | development | production |
DEBUG | true | false |
API_HOST | http://localhost:33001 | URL Staging API |
SERVER_ID | "127.0.0.1" | IP thực của server |
BROWSER_LIMIT_PER_PROCESS | 1 (forced) | Theo cấu hình server |
LOG_LEVEL | debug | info |
LOG_COLORIZED | true | false |
DB_MONGO_HOST | localhost | Container name trong Docker network |
4.2. Cấu Hình .env Staging#
File .env trên server staging (không commit vào Git, được cấu hình thủ công trên server):# Server
PORT=3005
NODE_ENV=production
DEBUG=false
RUNTIME=bun
SERVER_ID="77.37.47.88-01" # Instance 01
# Authentication
API_KEY='staging-api-key'
WEBHOOK_API_KEY='staging-webhook-key'
PROXY_API_KEY='staging-proxy-key'
IP_ALLOWED=127.0.0.1,staging-api-ip
# Go API Backend (Staging)
API_HOST=https://traffic-api-staging.tenmien.club
# MongoDB
DB_MONGO_HOST=traffic_tool_mongodb_v2
DB_MONGO_PORT=27017
DB_MONGO_USERNAME=root
DB_MONGO_PASSWORD=staging-mongo-password
DB_MONGO_DATABASE=tool-traffic-tools
# Browser limits
BROWSER_LIMIT_PER_PROCESS=10
# Traffic control
TASK_RETRY_LIMIT=8
PROXY_RETRY_LIMIT=15
ENABLE_GEOLOCATION=true
# Anti-Captcha
CAPTCHA_SOLVING_ENABLED=true
CAPTCHA_FALLBACK_TO_MANUAL=true
ANTICAPTCHA_API_KEY=staging-anticaptcha-key
ANTICAPTCHA_BASE_URL=https://api.anti-captcha.com
ANTICAPTCHA_TIMEOUT=300000
ANTICAPTCHA_RETRY_ATTEMPTS=3
# OpenAI
CHATGPT_API_KEY=sk-proj-staging-openai-key
CHATGPT_MODEL=gpt-4o-mini
# Storage
DIGITAL_OCEAN_BUCKET_NAME=tools-greeting1073
DIGITAL_OCEAN_REGION=sgp1
DIGITAL_OCEAN_ACCESS_KEY_ID=staging-do-key-id
DIGITAL_OCEAN_SECRET_ACCESS_KEY=staging-do-secret
DIGITAL_OCEAN_ENDPOINT=https://sgp1.digitaloceanspaces.com
DIGITAL_OCEAN_CDN_URL=https://tools-greeting1073.sgp1.cdn.digitaloceanspaces.com
# SMTP
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=staging-email@gmail.com
SMTP_PASS=staging-app-password
# Logging
LOG_LEVEL=info
LOG_COLORIZED=false
LOG_WRITE_TO_FILE=true
LOG_WRITE_TO_CONSOLE=true
LOG_TIMESTAMP=true
LOG_FOR_RECORD=true
ENABLE_SCREENSHOTS=true
Instance 02 dùng cấu hình tương tự nhưng SERVER_ID="77.37.47.88-02" và có thể dùng proxy pool khác.4.3. Biến GitLab CI/CD Cần Thiết#
Các biến sau phải được cấu hình trong GitLab CI/CD Settings → Variables:| Biến | Mô tả |
|---|
TRAFFIC_DEV_77_37_47_88_KEY | SSH private key (base64 encoded) để kết nối server 77.37.47.88 |
TRAFFIC_DEV_77_37_47_88_USER | Username SSH của server |
TRAFFIC_DEV_77_37_47_88_IP | IP của server: 77.37.47.88 |
TRAFFIC_DEV_77_37_47_88_PORT | SSH port: 23821 |
Tất cả biến này phải được đánh dấu Protected và Masked trong GitLab.
5. Docker Compose Trên Staging#
5.1. Cấu Trúc docker-compose.yml#
Trên staging, docker-compose.yml trong mỗi instance wrapper repo build trực tiếp từ source code:5.2. On-Server Build#
Khác với Production (pull image từ ECR), Staging build Docker image trực tiếp trên server:docker compose up --build -d rebuild image từ Dockerfile mỗi lần deploy.
Source code được copy vào image trong quá trình build.
Không cần AWS ECR hay Bastion Build Server.
Build mất khoảng 3-5 phút mỗi lần deploy.
5.3. Hai Instance Trên Cùng Server#
Hai instance chạy trên cùng server nhưng độc lập:Mỗi instance có Docker network riêng.
Mỗi instance có MongoDB container riêng.
Mỗi instance có port riêng (3005 và 3006 hoặc cấu hình khác).
Mỗi instance có SERVER_ID riêng để Go API phân biệt.
6. Triển Khai Thủ Công Lên Staging#
6.1. Khi Nào Cần Triển Khai Thủ Công#
Triển khai thủ công cần thiết khi:Pipeline CI/CD thất bại và cần debug trực tiếp trên server.
Cần cập nhật file .env mà không muốn trigger pipeline.
Cần rollback về commit cũ hơn.
Cần restart container mà không rebuild.
6.2. SSH Vào Server#
6.3. Cập Nhật Code Thủ Công#
6.4. Restart Không Rebuild#
Khi chỉ cần restart container (ví dụ sau khi sửa .env):6.5. Rollback Về Commit Cũ#
7. Kiểm Tra Sau Khi Deploy#
7.1. Kiểm Tra Container Đang Chạy#
7.2. Kiểm Tra Health#
7.3. Kiểm Tra Trạng Thái#
7.4. Xem Log Khởi Động#
7.5. Kiểm Tra Kết Nối Go API#
Nếu không thấy log này hoặc thấy lỗi kết nối, kiểm tra API_HOST trong .env.
8. Xử Lý Sự Cố Triển Khai#
8.1. Pipeline Thất Bại Do Lỗi SSH#
Kiểm tra biến TRAFFIC_DEV_77_37_47_88_KEY trong GitLab CI/CD Variables:Biến phải được đánh dấu Protected.
Giá trị phải là SSH private key được encode base64.
Không có ký tự thừa hoặc newline.
8.2. Docker Build Thất Bại#
Lỗi cài đặt npm packages: Kiểm tra package.json và bun.lock.
Lỗi cài Chrome: Network issue khi download Chrome package.
Lỗi disk đầy: Chạy docker system prune -a để dọn dẹp.
8.3. Container Khởi Động Rồi Tắt Ngay#
File .env thiếu biến bắt buộc.
MongoDB chưa sẵn sàng khi Tools V2 khởi động (race condition).
Lỗi kết nối Go API Backend.
Port đã bị chiếm bởi instance khác.
Giải pháp cho race condition với MongoDB:8.4. Ổ Cứng Server Đầy#
8.5. Hai Instance Xung Đột Port#
Nếu cả hai instance dùng cùng port, instance thứ hai sẽ không khởi động được:
9. Quản Lý Hai Instance#
9.1. Mục Đích Hai Instance#
Hai instance song song cho phép:Test với hai cấu hình proxy pool khác nhau cùng lúc.
So sánh performance giữa hai cấu hình.
Phát hiện race conditions khi nhiều workers cùng request tasks từ Go API.
Tăng throughput tổng thể của staging environment.
9.2. Cấu Hình Khác Nhau Giữa Hai Instance#
Instance 01 và 02 thường khác nhau ở:SERVER_ID: Phải khác nhau để Go API phân biệt.
PORT: Phải khác nhau nếu chạy trên cùng host network.
Proxy configuration: Có thể dùng proxy pool khác nhau.
BROWSER_LIMIT_PER_PROCESS: Có thể điều chỉnh khác nhau để test.
9.3. Kiểm Tra Cả Hai Instance#
9.4. Dừng Một Instance#
10. Quy Trình Kiểm Thử Trên Staging#
10.1. Checklist Trước Khi Merge Lên Staging#
Trước khi merge code lên staging-v2, đảm bảo:bun run typecheck không có lỗi.
bun run lint không có lỗi.
Code đã được review bởi ít nhất một người khác.
Các tính năng mới đã được test trên local.
Không có breaking changes với Go API Backend.
10.2. Kiểm Tra Sau Khi Deploy Lên Staging#
Sau khi pipeline hoàn thành:Kiểm tra cả hai containers đang chạy: docker ps.
Kiểm tra health endpoints của cả hai instances.
Xem log để đảm bảo không có lỗi khởi động.
Kiểm tra tasks đang được nhận từ Go API.
Theo dõi trong 15-30 phút để đảm bảo ổn định.
10.3. Kiểm Tra Tính Năng Cụ Thể#
Với mỗi tính năng mới, kiểm tra:Tạo task trên Admin Dashboard và xem có được thực thi không.
Xem log để đảm bảo flow chạy đúng.
Kiểm tra screenshot bằng chứng trên Admin Dashboard.
Kiểm tra webhook callback về Go API thành công.
10.4. Kiểm Tra Report Tasks#
11. Theo Dõi Staging#
11.1. Xem Log Realtime#
11.2. Đọc Log Files#
11.3. Kiểm Tra System Metrics#
Các ngưỡng cần chú ý trên staging:ram.used_percent > 80%: Cần giảm BROWSER_LIMIT_PER_PROCESS.
disk.used_percent > 70%: Cần dọn dẹp log và Docker images.
cpu.usage > 85%: Server đang quá tải.
11.4. Kiểm Tra Từ Admin Dashboard#
Sau khi deploy staging, kiểm tra trên Admin Dashboard:Màn hình Server Management: Cả hai instances phải hiển thị is_active = true.
Màn hình Server Performance: Phải có dữ liệu từ cả hai instances.
Màn hình Task Management: Tasks phải được phân phối cho cả hai instances.
12. Sự Khác Biệt Giữa Staging Và Local#
12.1. Cách Chạy#
| Khía cạnh | Local | Staging |
|---|
| Khởi động | bun run dev thủ công | Tự động qua CI/CD |
| Hot-reload | Có (--watch) | Không |
| Debugger | Có (--inspect) | Không |
| Build | Không cần build | docker compose up --build |
| Số instances | 1 | 2 song song |
12.2. Cấu Hình#
| Khía cạnh | Local | Staging |
|---|
NODE_ENV | development | production |
BROWSER_LIMIT_PER_PROCESS | 1 (forced) | Theo cấu hình server |
TASK_RETRY_LIMIT | Unlimited | 8 |
LOG_LEVEL | debug | info |
API_HOST | localhost:33001 | URL Staging API |
| MongoDB host | localhost | Container name |
12.3. Mục Đích#
| Khía cạnh | Local | Staging |
|---|
| Mục đích chính | Phát triển và debug | Kiểm thử trước production |
| Ai dùng | Developer cá nhân | Toàn bộ team |
| Dữ liệu | Test data tùy ý | Gần giống production |
| Uptime | Không yêu cầu | Phải ổn định |
13. Nhánh Git Và Quy Trình#
13.1. Nhánh staging-v2#
Nhánh staging-v2 là nhánh ổn định cho staging environment.
Chỉ merge code đã được test kỹ trên local vào staging-v2.
Không commit trực tiếp lên staging-v2 ngoại trừ hotfix khẩn cấp.
Mọi thay đổi phải qua Merge Request với ít nhất một reviewer.
13.2. Luồng Code#
feature/xxx → develop-v2 → staging-v2 → release-v2 → master-v2
feature/xxx: Nhánh tính năng của developer.
develop-v2: Tích hợp các tính năng mới, deploy lên Develop server.
staging-v2: Kiểm thử tổng thể, deploy lên Staging server.
release-v2: Chuẩn bị release, deploy lên Release server.
master-v2: Production, build Docker image và deploy lên Vnetwork.
13.3. Quy Tắc Merge#
Không merge trực tiếp từ feature/xxx lên staging-v2.
Phải merge qua develop-v2 trước.
Staging phải luôn là superset của develop (không có code trên staging mà không có trên develop).
14. Dọn Dẹp Định Kỳ#
14.1. Dọn Dẹp Docker#
14.2. Dọn Dẹp Log Files#
14.3. Dọn Dẹp MongoDB#
15. Checklist Triển Khai Staging#
Trước khi push lên staging-v2:Code đã pass bun run typecheck không có lỗi.
Code đã pass bun run lint không có lỗi.
Merge Request đã được review và approve.
Không có breaking changes với Staging API Backend.
File .env trên server đã được cập nhật nếu có biến mới.
Sau khi pipeline hoàn thành:Cả hai containers đang chạy: docker ps.
Health check trả về OK cho cả hai instances.
Log khởi động không có lỗi.
Tasks đang được nhận từ Go API (xem log sau 1-2 phút).
Admin Dashboard hiển thị cả hai instances là active.
Theo dõi ổn định trong 15 phút trước khi kết luận deploy thành công.
Modified at 2026-03-27 02:42:21