KDIGI CMS
Tự host KDIGI CMS: Docker Compose, Coolify, VPS
Một máy Linux có Docker là đủ: một container ứng dụng và một PostgreSQL.
Cập nhật lần cuối:

Clone repo, chạy docker compose up -d --build là có server Next.js (admin và API, cổng 3000) cùng PostgreSQL. Có sẵn cấu hình cho Coolify và cách chạy không Docker.
Tóm tắt nhanh
- Bốn cách: máy cá nhân, VPS Compose, Coolify, không Docker.
- Biến tối thiểu:
DATABASE_URI,PAYLOAD_SECRET,PAYLOAD_PUBLIC_SERVER_URL.- Migration tự chạy khi container khởi động.
- Sao lưu cả database lẫn media.
- Người đầu tiên tạo tài khoản thành
super-admin.

Bạn triển khai những gì
- Ứng dụng Node 22 Alpine,
next start, cổng 3000, chạy bằng usernode. - PostgreSQL Service
dbđi kèm hoặc PostgreSQL managed quaDATABASE_URI. - Volume
postgres_data,media_data(/app/media),app_data(/app/data). - Health
GET /api/healthchỉ là liveness, không truy vấn database.
Website công khai là frontend riêng gọi headless API; CMS không render trang thay bạn.
Cách 1: thử trên máy cá nhân
Chỉ cần Docker kèm Compose plugin:
git clone https://github.com/kdigivn/kdigi-cms-open.git
cd kdigi-cms-open
SEED_DEMO=true docker compose up --build
Mở http://localhost:3000/admin và tạo người dùng đầu tiên (tự động là super-admin). Bỏ SEED_DEMO=true để có bản cài trống. Chạy dev có hot reload: bắt đầu nhanh.
Cách 2: VPS với Docker Compose
- Máy Linux có Docker và Compose plugin
- RAM từ 2 GB
- Domain đã trỏ về máy
git clone https://github.com/kdigivn/kdigi-cms-open.git
cd kdigi-cms-open
cat > .env <<'EOF'
POSTGRES_PASSWORD=change-me-to-a-long-random-password
PAYLOAD_SECRET=change-me-to-a-random-string-of-32-chars-or-more
PAYLOAD_PUBLIC_SERVER_URL=https://cms.example.com
ENABLE_JOBS_AUTORUN=true
EOF
docker compose up -d --build
Đặt reverse proxy kết thúc TLS phía trước và chặn cổng 3000 bằng tường lửa. Ví dụ Caddy:
cms.example.com {
reverse_proxy 127.0.0.1:3000
}
Cảnh báo Không chạy
SEED_DEMO=truetrên bản production thật.
Cách 3: Coolify
- Tạo resource Chọn New Resource → Docker Compose, đặt Compose Location là
/docker-compose.coolify.yml. - Đặt biến bí mật Thêm
PAYLOAD_SECRET(tạo bằngopenssl rand -hex 32); đây là biến bắt buộc duy nhất. - Gắn domain Vào service
app(cổng 3000); domain riêng cần thêmPAYLOAD_PUBLIC_SERVER_URL. - Deploy Lần đầu áp dụng mọi migration; mở
/adminvà tạo người dùng đầu tiên.
Các biến tùy chọn và cách sao lưu db trong Coolify: tài liệu Coolify.
Cách 4: không dùng Docker
Cần Node.js ≥ 20.9, pnpm 10 và PostgreSQL. Đặt DATABASE_URI, PAYLOAD_SECRET, PAYLOAD_PUBLIC_SERVER_URL, rồi chạy pnpm build, pnpm migrate, pnpm start dưới systemd hoặc pm2. Chi tiết: tài liệu triển khai.
Sau khi deploy
- Tạo người dùng đầu tiên ngay Trên database trống, ai mở
/admintrước sẽ thànhsuper-admin. - Tạo site Nhập
siteKey,domain, ngôn ngữ; xem quản lý nhiều website. - Mời người dùng Gán vai trò và site (phân quyền).
- Bật job revalidate Đặt
ENABLE_JOBS_AUTORUN=truetrên đúng một instance. - Chọn nơi lưu media Mặc định ổ đĩa; Cloudflare R2 theo từng site (thư viện media).
Sao lưu và khôi phục
Sao lưu cả database lẫn media, và giữ PAYLOAD_SECRET. Mất secret thì phiên đăng nhập và API key ngừng hoạt động, dữ liệu vẫn đọc được.
docker compose exec -T db pg_dump -U kdigi --format=custom kdigi > kdigi-$(date +%F).dump
docker compose exec -T app tar czf - -C /app/media . > media-$(date +%F).tgz
- Chép dump ra khỏi máy chủ
- Thử restore trên máy phụ
- Site dùng R2: bật versioning phía Cloudflare
- PostgreSQL managed: dùng snapshot của nhà cung cấp
Lệnh restore và quy trình đầy đủ: sao lưu và nâng cấp.
Nâng cấp
- Đọc CHANGELOG Tìm mục Breaking và biến môi trường mới (phát hành).
- Sao lưu Database và media.
- Lấy code mới, build lại
docker compose up -d --build; Coolify thì redeploy. - Kiểm tra Đăng nhập
/admin, tải một ảnh, gọi một URL công khai.
Lưu ý Tránh
pnpm migrate:downtrên production: nó đảo ngược cả batch gần nhất. Khi cần quay lại, khôi phục bản sao lưu.
Bảo mật khi vận hành
PAYLOAD_SECRETngẫu nhiên, từ 32 ký tự- Đặt CMS sau HTTPS
- Giới hạn truy cập database trong mạng ứng dụng
- Đổi
POSTGRES_PASSWORDmặc định nếu cổng truy cập được từ ngoài - Giới hạn tốc độ request ở reverse proxy
Chi tiết: chính sách bảo mật và bảo mật, phân quyền.
Sự cố thường gặp
| Triệu chứng | Kiểm tra |
|---|---|
Container khởi động lại, báo PAYLOAD_SECRET must be at least 32 characters |
Đặt secret ≥ 32 ký tự, hoặc bỏ đặt để entrypoint tự sinh |
| Đăng nhập admin lặp, API trả 403 | PAYLOAD_PUBLIC_SERVER_URL phải khớp origin trên thanh địa chỉ |
| Không kết nối được database | Trong Compose dùng host db, không dùng localhost |
| Ảnh tải lên mất sau redeploy | /app/media chưa nằm trên volume bền |
| Frontend không làm mới sau khi đăng bài | ENABLE_JOBS_AUTORUN=true trên một instance, đã đặt domain của site |
| Build bị kill, hết bộ nhớ | Build trên máy lớn hơn hoặc thêm swap |
Câu hỏi thường gặp
Cần cấu hình máy chủ tối thiểu để chạy KDIGI CMS?
KDIGI CMS chạy những thành phần nào?
Biến môi trường nào là bắt buộc?
Làm sao nâng cấp lên phiên bản mới?
Tôi cần sao lưu những gì?
Đọc tiếp
Chuyển từ WordPress
Hướng dẫn chuyển WordPress sang KDIGI CMS: bài viết, trang, media, menu, dữ liệu Yoast/RankMath, WooCommerce, redirect 301. Có checklist và giới hạn rõ ràng.
Thực hành tốt
Hướng dẫn thực hành tốt cho KDIGI CMS: SEO on-page, cấu trúc nội dung, bảo mật và phân quyền, hiệu năng và cache, sao lưu và nâng cấp. Chọn bài theo vai trò.
Thư viện media
Quản lý ảnh theo thư mục, sửa ảnh trực tiếp, nhập ảnh từ URL có chống SSRF, lưu trên ổ đĩa hoặc Cloudflare R2, xuất WebP để trang tải nhanh hơn.
Demo
Đăng nhập demo KDIGI CMS bằng tài khoản có sẵn, thử soạn bài, SEO, media và phân quyền. Dữ liệu demo được đặt lại hằng đêm, có giới hạn sandbox.