Triển Khai Lên VPS
Hướng dẫn này giúp bạn đưa LaunchPad lên một máy chủ VPS Production với tiêu chí: Zero-Downtime, Zero-Build trên VPS.
Triết lý triển khai
VPS (thường cấu hình thấp 1–2GB RAM) không làm nhiệm vụ Build code. Toàn bộ quá trình đóng gói diễn ra tại máy Local. VPS chỉ cần Pull Image về và chạy.
Trước Khi Bắt Đầu
Hãy chuẩn bị đủ những thứ sau:
Checklist chuẩn bị
- [ ] VPS với Ubuntu 20.04+ và tối thiểu 1GB RAM
- [ ] Docker Engine cài trên VPS (
curl -fsSL https://get.docker.com | sh) - [ ] Docker Compose v2 (
docker compose versionđể kiểm tra) - [ ] Private Docker Registry — dùng LaunchPad Registry Stack hoặc bất kỳ registry nào
- [ ] Đã SSH được vào VPS (
ssh user@your-server-ip) :::
Kiến Trúc Triển Khai
Luồng làm việc mỗi khi update:
- Sửa code trên máy Local
- Build Docker Image và Push lên Registry
- VPS Pull Image mới → Restart container
Giai Đoạn 1: Build & Push từ Máy Local
Sử dụng VS Code Task (cách nhanh nhất)
- Nhấn
Ctrl + Shift + B - Chọn Task:
🐳 registry: push-all - Nhập thông tin khi được hỏi:
- Registry Address: địa chỉ Private Registry của bạn (VD:
103.x.x.x:5000) - Image Tag: phiên bản (dùng
latesthoặc điền mã version)
- Registry Address: địa chỉ Private Registry của bạn (VD:
Không dùng VS Code? Build bằng lệnh tay
# Build image Next.js
docker build -t <registry>/launchpad-next:latest ./next
# Build image Strapi
docker build -t <registry>/launchpad-strapi:latest ./strapi
# Push cả hai
docker push <registry>/launchpad-next:latest
docker push <registry>/launchpad-strapi:latestGiai Đoạn 2: Deploy Trên VPS
SSH vào VPS và thực hiện theo thứ tự:
Bước 1 — Clone dự án (chỉ lần đầu)
git clone https://github.com/tuquet/launchpad-cms-fullstack.git
cd launchpad-cms-fullstackBước 2 — Tạo file .env
chmod +x scripts/copy-env.sh
./scripts/copy-env.sh --env prod . ./strapiScript này tự động set COMPOSE_FILE=compose.prod.yml, bạn không cần gõ -f mỗi lần.
Mở file .env và kiểm tra / sửa thông số Registry:
# Địa chỉ Registry (mặc định là localhost:5000 nếu Registry cùng VPS)
REGISTRY_URL=localhost:5000
IMAGE_TAG=latestBước 3 — Pull & Start
# Tải các image mới nhất từ Registry
docker compose pull
# Khởi động toàn bộ hệ thống
docker compose up -dBước 4 — Tắt Seed Data (Bảo mật & Tối ưu!)
Cơ chế Bảo vệ Đa lớp Mới
Để nâng cao trải nghiệm nhà phát triển và tránh rủi ro mất mát dữ liệu:
- Tự động Khóa (Lock Flag): Khi hệ thống nạp dữ liệu thành công lần đầu, container Strapi sẽ tự động tạo một file đánh dấu
.seededtrong thư mục persistent volume. Từ đó, dùSEED_DATA=truevẫn bật, container sẽ tự động bỏ qua bước seed ở các lần restart sau, đảm bảo không bao giờ ghi đè lên dữ liệu của bạn. - Khuyến nghị Tắt Biến Host: Sau khi cài đặt hoàn tất, bạn vẫn nên tắt biến này ở phía host
.envbằng script để bảo mật và tối ưu thời gian khởi động:
chmod +x scripts/toggle-seed.sh
./scripts/toggle-seed.sh disableCập Nhật & Rollback
Cập nhật lên phiên bản mới
# Trên máy Local: Build & Push như thường
# (Ctrl+Shift+B → registry: push-all)
# Trên VPS:
docker compose pull # Kéo image mới
docker compose up -d # Restart với image mớiRollback về phiên bản cũ
Nếu bản update bị lỗi, chỉ cần đổi IMAGE_TAG trong .env về tag cũ:
# Sửa IMAGE_TAG trong .env
nano .env
# Đổi: IMAGE_TAG=v1.2.0 (tag cũ của bạn)
# Khởi động lại với image cũ
docker compose pull
docker compose up -dCấu Hình Nginx & HTTPS
(Bỏ qua phần này nếu bạn không dùng LaunchPad Registry Stack)
Container Nginx của CMS đẩy website ra cổng 8000 (không chiếm cổng 80/443). Bạn cần cấu hình Nginx UI để trỏ domain vào đây.
Các bước trong Nginx UI
1. Đăng nhập vào Nginx UI trên VPS
2. Tạo Site mới:
| Trường | Giá trị |
|---|---|
| Server Name | cms.yourdomain.com |
| Listen | 80 |
3. Trong Locations, tạo Proxy:
| Trường | Giá trị |
|---|---|
| Path | / |
| Proxy Pass | http://127.0.0.1:8000 |
| Host | Bật "Preserve Host" ($host) |
4. Tab SSL → Enable SSL (Let's Encrypt) → Điền Email → Bấm Issue
Sau vài giây, domain của bạn sẽ tự động có HTTPS! 🎉
Chạy Không Có Domain (Dùng IP)
Bạn chưa có tên miền?
Bạn hoàn toàn có thể chạy LaunchPad chỉ với địa chỉ IP. Domain là tùy chọn nâng cấp sau.
Khi chưa có domain, truy cập hệ thống qua IP:
| Dịch vụ | URL |
|---|---|
| Website | http://<IP_VPS>:8000 |
| Strapi Admin | http://<IP_VPS>:1337/admin |
| Registry UI | http://<IP_VPS>:5001 |
| Nginx UI | http://<IP_VPS> (port 80) |
Khi sẵn sàng nâng cấp lên domain:
- Mua tên miền và trỏ DNS A Record về IP VPS
- Trong Nginx UI, tạo Site mới cho từng subdomain
- Bật SSL (Let's Encrypt) cho từng subdomain
- Xem chi tiết tại Hạ Tầng Registry Stack
Xử Lý Sự Cố
❌ VPS báo lỗi "No space left on device"
Các lần Push/Pull nhiều lần tạo ra "rác" (dangling images). Chạy script dọn dẹp:
sh scripts/cleanup.shLưu ý
Script này an toàn — chỉ xóa rác và container đã dừng, không ảnh hưởng container đang chạy.
❌ Không kết nối được Registry
Kiểm tra Registry còn sống:
curl http://<REGISTRY_URL>/v2/_catalogNếu báo lỗi kết nối, kiểm tra firewall VPS đã mở port của Registry chưa.
❌ Container khởi động rồi tự tắt
Xem log để biết lý do:
docker compose logs --tail=50 strapi
docker compose logs --tail=50 launchpad-nextjs