Bối cảnh
Mình quản lý khá nhiều site WordPress. Trang dự án ghi hơn 40 site đang chạy cùng một bản SL Migrations. Mỗi lần chuyển server, khôi phục sau một sự cố hay đẩy bản thử về site thật, việc này lặp lại.
Làm tay thì phải xuất database bằng dòng lệnh, nén file, tải sang chỗ mới, rồi sửa địa chỉ website trong database. Đến bước cuối là dễ hỏng nhất. WordPress cất nhiều cấu hình dưới dạng chuỗi kèm độ dài (gọi là dữ liệu serialized). Thay địa chỉ kiểu tìm-và-thay thô sẽ làm sai độ dài, và cấu hình đó hỏng im lặng.
SL Migrations là plugin mình dùng chung cho các site đó: một bản duy nhất, gói được cả file lẫn database, có bộ cài riêng để dựng lại site ở nơi khác. Plugin này không viết từ con số không: mình port và gộp từ nhiều plugin WordPress mã nguồn mở (GPL) khác nhau, rồi chỉnh lại thành một plugin riêng, thống nhất.

Thách thức
Có bốn chuyện làm việc này khó hơn vẻ ngoài.
Thứ nhất, sao lưu thủ công tốn thời gian và dễ sai, nhất là bước đổi địa chỉ trong dữ liệu serialized.
Thứ hai, các plugin thương mại có sẵn tính phí theo từng site. Với hơn 40 site, mình cần một bản dùng chung, không bị giới hạn số site.
Thứ ba, mỗi tình huống cần một cách khôi phục khác nhau. Site đang chạy bị lỗi nặng cần quay lại thật nhanh. Chuyển sang server mới cần dựng ở nơi trống. Site rất lớn thì gặp giới hạn thời gian của máy chủ. Có lúc chỉ cần khôi phục database.
Thứ tư, một bản backup chứa toàn bộ database của site. Nếu ai đó lấy được bản backup thì coi như lấy được cả dữ liệu.
Cách làm
1. Một gói gồm file, database và bộ cài
Bấm "Create New", plugin chạy một bước quét trước (Scan) để kiểm môi trường: dung lượng, quyền đọc file, phiên bản WordPress. Rồi nó nén file và database thành một gói, kèm một tệp installer.php để dựng lại site. Gói được kiểm toàn vẹn bằng mã băm. Có thể chọn mã hoá bằng AES-256 và đặt mật khẩu.
Ở bước thiết lập, mục Security cho chọn ba kiểu: không đặt gì, đặt mật khẩu cho bộ cài, hoặc mã hoá cả gói.


2. Sáu chế độ khôi phục cho sáu tình huống
Mình chia cách khôi phục theo tình huống thật gặp ngoài đời, không theo kỹ thuật.
Khi site đang chạy bị lỗi nặng, dùng Recovery Point: đánh dấu trước một gói làm điểm khôi phục khẩn cấp, cần thì quay lại trong một thao tác. Khi chuyển sang chỗ trống, dùng Classic (mặc định). Muốn xoá site hiện tại và dựng lại từ gói, dùng Overwrite. Site đích đã có WordPress và plugin thì dùng Import Install, tải gói lên ngay trong wp-admin. Chỉ cần database, dùng Database only. Site lớn hơn 5 GB hoặc máy chủ hay ngắt giữa chừng thì dùng Two-Part: giải nén bằng dòng lệnh trước, rồi mới chạy bộ cài.

Bộ cài chạy độc lập, không cần WP-CLI và không cần cài plugin ở máy đích. Trước khi làm gì, nó tự kiểm môi trường đích.

3. Lưu ở đâu, tải về thế nào
Gói có thể giữ trên máy (Local) hoặc đẩy sang chỗ khác qua FTP hay SFTP, giữ số bản theo cấu hình. Lịch chạy dùng WP-Cron hoặc cron của hệ thống.
Bản backup chỉ tải được qua trang quản trị, bằng một mã (token) có ký HMAC và hết hạn sau 1 giờ. Thư mục chứa backup cũng bị chặn truy cập trực tiếp ở máy chủ web.


4. Sửa theo những lần khôi phục thật
Cách duy nhất để biết một bản backup dùng được là khôi phục nó. Lỗi của bộ cài lộ ra khi mình khôi phục thật, mình sửa rồi ghi vào changelog. Từ 06/2026 đến 10/2026 có 6 bản phát hành, từ 1.8.5 đến 1.8.10. Ví dụ: bộ cài báo sai phiên bản dù khớp, nhập đúng mật khẩu vẫn quay lại khung mật khẩu, và một kiểu sắp xếp chữ mới của MariaDB 11.8 làm câu lệnh tạo bảng bị lỗi.
Kết quả
Các con số "6", "40+" và "AES-256" lấy từ trang dự án và tài liệu SL Migrations (phiên bản 1.8.10, 18/10/2026). Số mã hoá và số site là số do mình công bố, không có số đo độc lập. Riêng phần bên dưới là số mình đo ngày 08/11/2026, trên một site WordPress mẫu mới cài (không phải site của khách), chạy bằng máy chủ PHP đơn giản trên máy của mình.
Đo ngày 08/11/2026 trên một site WordPress mẫu mới cài (không phải site của khách), chạy bằng máy chủ PHP đơn giản trên máy của mình, kiểu nén ZIP. Trước: dung lượng file mà bước quét báo (103,4 MB, chưa nén). Sau: gói backup tạo ra (28,9 MB). Site mẫu chủ yếu là chữ và mã PHP nên nén tốt, site nhiều ảnh nén được ít hơn.
Trên site mẫu đó, tạo gói mất chưa tới một phút. Khôi phục sang một thư mục mới và database trống mất khoảng 9 giây, dựng lại 14 bảng, và site đích mở được. Site mẫu chủ yếu là chữ và mã PHP nên nén tốt. Site có nhiều ảnh nén được ít hơn, nên gói sẽ gần dung lượng gốc hơn.
Có một việc chưa làm được. Bản này chỉ lưu ở Local, FTP và SFTP. Các kho đám mây như Amazon S3, Dropbox hay Google Drive đã bị gỡ khỏi bản dùng chung, nên hiện chưa đẩy thẳng lên đó được.
Bài học
Backup chưa thử khôi phục thì chưa phải backup. Phần lớn lỗi mình tìm ra nằm ở bộ cài, và chỉ lộ ra khi khôi phục thật lên một nơi trống. Có thể đọc thêm ở bài Sao lưu website đúng cách: quy tắc 3-2-1 và thử khôi phục định kỳ.
Bộ cài nằm trong từng gói. Sửa lỗi ở plugin thì gói cũ vẫn mang lỗi cũ, chỉ gói tạo mới mới có bản sửa.
Bản backup cũng là một tệp cần bảo vệ. Ở bản 1.8.9 mình phát hiện thư mục backup nằm trong webroot, nên ai biết tên tệp là tải được. Mình đổi sang tải qua trang quản trị bằng mã hết hạn sau 1 giờ, và chặn thư mục ở máy chủ web. Phần làm cứng máy chủ web nói thêm ở bài Làm website chạy Nginx an toàn hơn, từng bước.
Nâng cấp cũng có thể làm hỏng cấu hình. Ở 1.8.9, một site mất cấu hình đích SFTP vì cách mã hoá cấu hình đổi khoá. Không mất dữ liệu, và bản 1.8.10 sửa bằng cách giữ khoá cũ cho site đã dùng khoá đó khi nâng cấp.
Cần việc tương tự?
Nếu bạn có nhiều site WordPress và đang sao lưu thủ công, hoặc sắp chuyển server, gửi mình vài dòng về tình huống. Mình sẽ xem site cần giữ lại gì, thử khôi phục trên một chỗ trống trước, rồi nói rõ cách nào phù hợp.




