docker-compose.yml trong repo dựng hai dịch vụ: PostgreSQL 16 (db) và ứng dụng (app, cổng 3000). Migration chạy tự động mỗi lần ứng dụng khởi động.
Dữ liệu nằm ở đâu
Phần tiêu đề “Dữ liệu nằm ở đâu”Ba named volume giữ dữ liệu qua các lần docker compose down:
| Volume | Nội dung |
|---|---|
postgres_data | Cơ sở dữ liệu |
media_data | Ảnh và file tải lên (/app/media), khi site chưa cấu hình Cloudflare R2 |
app_data | Dữ liệu của ứng dụng, gồm PAYLOAD_SECRET tự sinh |
docker compose down -v xoá cả ba.
Biến cấu hình thường dùng
Phần tiêu đề “Biến cấu hình thường dùng”Đặt trong môi trường hoặc file .env cạnh docker-compose.yml. Chạy thử trên máy bạn thì không cần đặt gì.
| Biến | Mặc định | Ý nghĩa |
|---|---|---|
PAYLOAD_PUBLIC_SERVER_URL | http://localhost:3000 | Địa chỉ công khai của CMS như trình duyệt thấy; cũng là tiền tố URL của ảnh |
PAYLOAD_SECRET | trống (tự sinh một lần) | Khoá ký phiên đăng nhập. Trên máy chủ nên tự đặt, tối thiểu 32 ký tự |
POSTGRES_PASSWORD | kdigi | Mật khẩu database |
APP_PORT / DB_PORT | 3000 / 5432 | Cổng ra máy chủ. Database chỉ mở trên 127.0.0.1 |
SEED_DEMO | trống | true để nạp site demo (chạy lại không tạo trùng) |
SKIP_MIGRATIONS | trống | true để bỏ bước migration tự động khi container khởi động |
Danh sách đầy đủ, gồm AI SEO, reCAPTCHA cho bình luận, OpenTelemetry và importer WordPress, nằm trong file .env.example của repo và ở tài liệu cấu hình.
Chạy trên máy chủ
Phần tiêu đề “Chạy trên máy chủ”- Đặt
PAYLOAD_PUBLIC_SERVER_URLthành địa chỉhttps://thật của CMS vàPAYLOAD_SECRETthành chuỗi ngẫu nhiên dài (openssl rand -hex 32). - Đổi
POSTGRES_PASSWORDkhỏi giá trị mặc định. - Đặt một reverse proxy có TLS (Traefik, Caddy, nginx) phía trước cổng 3000.
- Giữ nguyên các volume để không mất dữ liệu khi cập nhật image.
Nếu dùng Coolify, đọc Triển khai trên Coolify.
Chạy ứng dụng ngoài Docker (phát triển)
Phần tiêu đề “Chạy ứng dụng ngoài Docker (phát triển)”Chỉ dựng database bằng Compose rồi chạy Next.js trên máy:
docker compose up dbcp .env.example .envpnpm installpnpm migratepnpm devKiểm tra sức khoẻ
Phần tiêu đề “Kiểm tra sức khoẻ”GET /api/health trả 200 khi tiến trình còn phục vụ HTTP. Endpoint này không truy vấn database, nên đừng coi nó là bằng chứng schema đã sẵn sàng.