Hướng dẫn CI/CD Auto-Deploy lên VPS
Tài liệu này mô tả luồng đưa code từ máy dev → GitLab → tự động deploy lên VPS,
đúng như cấu hình đang chạy của dự án ta-tech/cms.
1. Tổng quan luồng hoạt động
`
Máy dev GitLab (gitlab.com/ta-tech/cms) VPS (/opt/ta_cms)
┌────────┐ git push ┌──────────────────────────────┐ SSH ┌──────────────────┐
│ code │ ───────────► │ repo → pipeline CI/CD │ ──────► │ git reset --hard │
└────────┘ (SSH key) │ (.gitlab-ci.yml, runner) │ (key) │ docker compose │
└──────────────────────────────┘ └──────────────────┘
`
Mỗi lần git push lên nhánh main:
- GitLab shared runner chạy job
deploytrong .gitlab-ci.yml. - Runner SSH vào VPS bằng key
ci_deploy. - Trên VPS:
git fetch+git reset --hard origin/main(ép khớp đúng commit, không merge). docker compose up -d --buildbuild lại và chạy container.
Dùnggit reset --hardthay vìgit pullđể deploy idempotent: VPS luôn khớp
chính xác commit trên GitLab, không bao giờ kẹt conflict/merge.
2. Ba loại khóa SSH (đừng nhầm lẫn)
Quy tắc: public key (.pub, 1 dòng ssh-ed25519...) thì add vào nơi nhận kết nối;
private key (nhiều dòng BEGIN/END) thì giữ ở nơi khởi tạo kết nối.
3. Cấu hình một lần (đã làm xong)
3.1. Máy dev → GitLab
`bash
ssh-keygen -t ed25519 -C "you@email" -f ~/.ssh/id_ed25519_gitlab -N ""
cat ~/.ssh/id_ed25519_gitlab.pub # → add vào GitLab > User Settings > SSH Keys
`
~/.ssh/config (máy dev):
`
Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/id_ed25519_gitlab
IdentitiesOnly yes
`
3.2. VPS pull được từ GitLab (deploy key)
`bash
ssh-keygen -t ed25519 -f ~/.ssh/gitlab_deploy -N ""
cat ~/.ssh/gitlab_deploy.pub # → add vào GitLab > repo Settings > Repository > Deploy keys (KHÔNG cần write)
`
~/.ssh/config (VPS) — bắt buộc, nếu thiếu sẽ Permission denied (publickey):
`
Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/gitlab_deploy
IdentitiesOnly yes
`
Biến /opt/ta_cms thành git repo nối GitLab (giữ nguyên .env):
`bash
cd /opt/ta_cms
git init -b main
git remote add origin git@gitlab.com:ta-tech/cms.git
git fetch origin
git reset --hard origin/main # nhận file hiện có vào git, khớp với GitLab
git ls-remote origin >/dev/null && echo "✅ pull OK"
`
3.3. Runner SSH vào VPS (CI key)
`bash
ssh-keygen -t ed25519 -f ~/.ssh/ci_deploy -N ""
cat ~/.ssh/ci_deploy.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
cat ~/.ssh/ci_deploy # → copy TRỌN khối BEGIN..END vào biến SSH_PRIVATE_KEY
`
3.4. Biến CI/CD trên GitLab
GitLab → repo Settings → CI/CD → Variables:
⚠️ SSH_PRIVATE_KEY không mask được (key nhiều dòng) → bỏ tick Mask.
Nhánh main mặc định chưa "protected" → bỏ tick Protect, nếu không biến sẽ rỗng trong job.
3.5. File .env production trên VPS
.env không nằm trong git (đã .gitignore). Tạo thủ công một lần trên VPS:
`bash
cd /opt/ta_cms
cp .env.example .env
nano .env # điền secret thật: PAYLOAD_SECRET, MONGO password, S3 keys, SERVER_URL...
`
4. Quy trình dùng hằng ngày
`bash
Trên máy dev
git add .
git commit -m "mô tả thay đổi"
git push origin main
`
→ Xong. Theo dõi deploy tại: https://gitlab.com/ta-tech/cms/-/pipelines
- ✅ Xanh = đã deploy lên VPS.
- ❌ Đỏ = mở job
deployxem log.
5. Xử lý sự cố (các lỗi đã gặp)
6. Lệnh vận hành trên VPS
`bash
cd /opt/ta_cms
docker compose ps # trạng thái container
docker compose logs payload --tail 50 -f # xem log app
docker compose restart payload # restart
docker compose down && docker compose up -d --build # rebuild toàn bộ
`
Rollback về commit trước (khi bản mới lỗi):
`bash
cd /opt/ta_cms
git reset --hard <commit-cũ>
docker compose up -d --build
`