Cấu hình tối thiểu
| Thành phần | Tối thiểu | Khuyến nghị |
|---|---|---|
| CPU | 2 nhân | 4 nhân |
| RAM | 4 GB | 8 GB |
| Ổ cứng | 20 GB SSD | 50 GB SSD |
| Node.js | 20 LTS | 20 hoặc 22 LTS |
| Hệ điều hành | Ubuntu 22.04 | Ubuntu 22.04 / 24.04 |
Nếu chạy thêm mô hình cục bộ (Ollama) trên cùng máy, cộng thêm tối thiểu 8 GB RAM và cân nhắc GPU.
Biến môi trường bắt buộc
Thiếu bất kỳ biến nào dưới đây, tính năng tương ứng sẽ tắt hẳn thay vì chạy nửa vời — đây là thiết kế cố ý để lỗi lộ ra sớm.
# Địa chỉ công khai — nướng vào bundle lúc build, PHẢI có trước khi chạy next build NEXT_PUBLIC_SITE_URL=https://your-domain.com # Gửi email giao dịch LEXIOPERATOR_RESEND_API_KEY=re_xxx OFFICIAL_FROM_EMAIL=TÊN BẠN <[email protected]> [email protected] # Cổng thanh toán — thiếu biến này webhook từ chối MỌI request SEPAY_WEBHOOK_SECRET=chuoi_bi_mat_cua_ban # Thông báo Telegram TELEGRAM_BOT_TOKEN=1234567890:AAxxx TELEGRAM_CHAT_ID=123456789 # Cơ sở dữ liệu NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEY=xxx SUPABASE_SERVICE_ROLE_KEY=xxx
SUPABASE_SERVICE_ROLE_KEY tuyệt đối không được đặt tiền tố NEXT_PUBLIC_. Mọi biến NEXT_PUBLIC_* đều bị đưa vào mã nguồn tải về trình duyệt — đặt sai là công khai khoá có toàn quyền ghi xoá cơ sở dữ liệu.
Thứ tự triển khai
1. Đồng bộ mã nguồn
Copy toàn bộ thư mục ứng dụng lên máy chủ, loại trừ node_modules và .next.
2. Đặt biến môi trường TRƯỚC khi build
Các biến NEXT_PUBLIC_* được nướng vào bundle lúc build. Đặt sau khi build sẽ không có tác dụng — đây là lỗi hay gặp nhất.
3. Cài phụ thuộc và build
npm install rồi npx next build. Build phải báo 0 lỗi trước khi sang bước sau.
4. Khởi chạy qua trình quản lý tiến trình
Dùng pm2 hoặc systemd để tiến trình tự khởi động lại khi máy chủ reboot.
5. Đặt reverse proxy và chứng chỉ HTTPS
Nginx trỏ về cổng ứng dụng, kèm redirect HTTP sang HTTPS.
Ba sai lầm hay gặp
- Build đè lên thư mục .next của tiến trình đang chạy — ứng dụng sẽ sập liên tục trong suốt thời gian build. Hãy build xong rồi mới reload tiến trình.
- Redirect HTTP sang HTTPS bằng mã 301 — mã này biến POST thành GET và làm hỏng webhook thanh toán. Dùng 308 để giữ nguyên phương thức và nội dung.
- Đưa bí mật vào URL — mọi thứ trong query string đều bị ghi vào access log của web server.
Kiểm tra sau khi triển khai
# HTTPS redirect giữ đúng phương thức
curl -s -o /dev/null -w "%{http_code}\n" http://your-domain.com/
# kỳ vọng: 308
# Canonical không còn trỏ localhost
curl -s https://your-domain.com/sitemap.xml | grep -o "<loc>[^<]*</loc>" | head -3
# Webhook thanh toán từ chối request không ký
curl -s -o /dev/null -w "%{http_code}\n" -X POST https://your-domain.com/api/webhooks/sepay
# kỳ vọng: 401