Quy trình 6 bước chuyển website WordPress về CloudFly (Hosting & VPS) mượt mà, Zero Downtime
Quy trình 6 bước chuyển website WordPress về CloudFly (Cloud Hosting & VPS) không gián đoạn: hạ DNS TTL, test ngầm bằng hosts file và săn mã giảm tới 70%.
Hướng dẫn chuyển WordPress từ HTTP sang HTTPS, cấu hình Redirect 301 chuẩn xác, chạy WP-CLI search-replace an toàn và xử lý dứt điểm lỗi Mixed Content.
Cài xong chứng chỉ SSL mới chỉ là đi được nửa chặng đường; muốn ổ khóa HTTPS xanh mượt, bạn phải đồng bộ Site Address, gom Redirect 301 về một mối và quét sạch đám tài nguyên Mixed Content cứng đầu bằng WP-CLI search-replace có backup đàng hoàng.
Phạm vi thực hành: Ubuntu 24.04 LTS trên VPS thử nghiệm riêng biệt; domain lab
lab-cf02.localhost.vn. Chỉ thao tác trên tài sản do chính bạn quản lý. Phiên quan sát lúc 00:02–00:03 ngày 01/10/2026 (UTC+7) ghi nhận trạng thái website đã bật HTTPS. Phiên thực hành độc lập lúc 20:34–20:35 trên bản clone đã thực hiện đổi URL trong database, rà soát dữ liệu serialized và khôi phục (rollback) bằng file SQL. Phiên thử nghiệm trên trình duyệt lúc 21:02–21:03 ở một bài viết riêng đã tái hiện cảnh file script HTTP bị trình duyệt chặn đứng, sau đó sửa sang HTTPS và xác nhận script chạy mượt. Đây là các bài kiểm tra tách biệt, chưa phải bước nghiệm thu Mixed Content toàn website hay kiểm thử đăng nhập/biểu mẫu ngay sau khi đổi URL.
Rất nhiều anh em mới dựng web hay lầm tưởng rằng cứ chạy Certbot lấy xong chứng chỉ SSL là website tự khắc hóa rồng với ổ khóa bảo mật lung linh. Thực tế phũ phàng hơn nhiều: để chuyển WordPress sang HTTPS trọn vẹn, bạn phải giải quyết gọn gàng cả ba mắt xích: cấu hình web server phục vụ TLS chuẩn chỉnh, khai báo lại địa chỉ HTTPS trong cấu hình WordPress, và truy quét toàn bộ các đường dẫn tài nguyên vẫn còn vương vấn http:// cũ kỹ trong nội dung (thủ phạm gây ra căn bệnh kinh điển mang tên Mixed Content). Chứng chỉ SSL hợp lệ mới chỉ giúp bạn qua ải đầu tiên mà thôi. Bài viết này dành cho những website đã hoàn tất bước cài đặt TLS cơ bản từ bài 43 và đang cần quy hoạch lại toàn bộ đường đi nước bước về một mối HTTPS duy nhất.
Trong nghề sysadmin, sửa cấu hình URL mà không có bản backup khác nào đi dây qua vực mà quên thắt dây an toàn. Trước khi đụng tay vào bất kỳ thiết lập URL nào, hãy xuất ngay một bản sao lưu (backup) cho cả database lẫn file cấu hình, ghi chép lại thông số URL hiện tại và chắc chắn rằng bạn đang mở sẵn một phiên SSH hoạt động ngon lành vào đúng máy chủ chứa website. Lỡ tay đổi URL làm trang quản trị wp-admin rơi vào vòng lặp chuyển hướng vô tận (redirect loop), bạn vẫn còn đường dùng SSH và WP-CLI để cứu bồ trong 30 giây. Nếu trong tay chưa nắm quyền SSH máy chủ mà chỉ trông chờ vào độc một tab trình duyệt đang đăng nhập sẵn Admin, lời khuyên chân thành là bạn hãy khoan bấm nút lưu.
Hãy mở terminal và dùng lệnh curl (tuyệt đối không kèm cờ -k bỏ qua xác thực chứng chỉ) để thăm dò trực tiếp https://lab-cf02.localhost.vn/. Nếu phía trước VPS có bật lớp proxy đám mây vàng của Cloudflare, hãy đảm bảo chế độ mã hóa SSL/TLS đang đặt ở mức Full (strict) để khóa chặt cả hai chặng kết nối từ trình duyệt tới Cloudflare và từ Cloudflare về máy chủ gốc (origin). Một khi bản thân giao thức HTTPS còn chưa thông suốt, bạn hãy quay về bài 43 xử lý dứt điểm tầng web server trước, tuyệt đối đừng lấy chuyện thay hàng loạt URL trong database ra làm phép thử cầu may.

Sơ đồ kiến trúc tổng quan do localhost.vn biên soạn nhằm minh họa luồng kỹ thuật, không phải ảnh chụp màn hình từ môi trường lab.
Trong trang quản trị WordPress, bạn mở mục Settings → General và ghi chép lại hai thông số sống còn: WordPress Address (URL) và Site Address (URL). Ở một số kiến trúc đặc thù khi mã nguồn lõi WordPress được đặt nằm riêng trong thư mục con (ví dụ /wp) nhưng hiển thị ra ngoài ở thư mục gốc, hai giá trị này cố tình được thiết kế khác nhau; bạn cần nắm rõ cấu trúc hiện có trước khi sửa. Trong khuôn khổ chuỗi bài thực hành này, WordPress được cài đặt trực tiếp tại thư mục gốc (root directory) của tên miền nên cả hai trường đều mang chung một giá trị tên miền chính.
Nếu máy chủ đã trang bị sẵn công cụ WP-CLI như hướng dẫn ở bài 41, hãy đăng nhập bằng tài khoản user hệ điều hành sở hữu mã nguồn website để thao tác, tuyệt đối tránh thói quen xấu là chạy WP-CLI bằng quyền root. Bạn gán đường dẫn tuyệt đối của bản clone đã sao lưu vào biến môi trường WP_ROOT. Mỗi khối lệnh dưới đây đều chạy trong một subshell cô lập và sẽ tự động phanh gấp nếu phát hiện đường dẫn sai lệch hoặc câu lệnh gặp trục trặc. Lưu ý nguyên tắc vàng: môi trường clone dùng để thử nghiệm phải sở hữu database và cây thư mục mã nguồn tách biệt hoàn toàn, không bao giờ dùng chung cơ sở dữ liệu với website đang chạy thật:
(
set -eu
: "${WP_ROOT:?Đặt đường dẫn tuyệt đối của WordPress clone}"
test "$(id -u)" -ne 0
case "$WP_ROOT" in /*) ;; *) exit 1 ;; esac
test ! -L "$WP_ROOT"
test -O "$WP_ROOT"
test -r "$WP_ROOT/wp-load.php"
cd -- "$WP_ROOT"
wp option get home
wp option get siteurl
)
Đừng quên mở file wp-config.php ra rà soát xem hai hằng số WP_HOME và WP_SITEURL có đang được định nghĩa cứng để ghi đè (override) cấu hình trong database hay không. Khi kiểm tra bằng dòng lệnh trên máy chủ, hãy lọc khéo léo để tránh in toẹt toàn bộ nội dung file chứa mật khẩu database hay các chuỗi khóa bảo mật (salts/secrets) ra màn hình log. Nếu trong code có khai báo hai hằng số này, giá trị nằm trong bảng wp_options của database sẽ bị vô hiệu hóa trên thực tế. Hãy ghi chú rõ ràng nguồn cấu hình đang nắm quyền quyết định để người tiếp quản vận hành sau này biết chính xác cần sửa ở đâu.
Khi đã xác nhận website cài đặt ở thư mục gốc của tên miền và không bị khống chế bởi hằng số cứng trong wp-config.php, bạn có thể cập nhật trực tiếp trên giao diện Dashboard hoặc chạy khối lệnh WP-CLI chuẩn xác dưới đây. Quy trình an toàn luôn bắt đầu bằng việc cất kỹ hai giá trị URL cũ vào biến lưu trữ. Hãy gán địa chỉ HTTPS của chính website đã vượt qua bài kiểm tra TLS vào biến TARGET_HTTPS_URL (nhớ thay bằng tên miền thực tế của bạn, đừng bê nguyên xi tên miền lab vào máy chủ sản phẩm):
(
set -eu
: "${WP_ROOT:?Đặt WordPress clone đã kiểm}"
: "${TARGET_HTTPS_URL:?Đặt URL HTTPS đúng site}"
test "$(id -u)" -ne 0
case "$WP_ROOT" in /*) ;; *) exit 1 ;; esac
case "$TARGET_HTTPS_URL" in https://*) ;; *) exit 1 ;; esac
test ! -L "$WP_ROOT"
test -O "$WP_ROOT"
test -r "$WP_ROOT/wp-load.php"
cd -- "$WP_ROOT"
wp option update home "$TARGET_HTTPS_URL"
wp option update siteurl "$TARGET_HTTPS_URL"
)
Có một chi tiết kỹ thuật quan trọng mà ít tài liệu nhắc tới: hai lệnh cập nhật home và siteurl của WP-CLI không nằm chung trong một giao dịch cơ sở dữ liệu (database transaction) duy nhất. Nghĩa là nếu lệnh đầu trọt lọt nhưng lệnh thứ hai chẳng may gãy gánh giữa đường, hệ thống sẽ rơi vào cảnh “chân trong chân ngoài” — một nửa HTTP, một nửa HTTPS. Do đó, nếu thấy bất kỳ báo lỗi nào xuất hiện, hãy dừng tay ngay lập tức và đối chiếu cả hai giá trị hiện tại với bản ghi cũ. Sau khi đổi URL thành công, trình duyệt thường sẽ yêu cầu bạn đăng nhập lại do phạm vi bảo mật của cookie phiên làm việc đã thay đổi. Hãy mở trình duyệt thử truy cập trang chủ và đăng nhập vào quản trị qua HTTPS ngay lúc này trước khi đụng tới việc sửa nội dung hàng loạt; nếu chẳng may bị văng sang một tên miền lạ hoắc, bạn chỉ cần dùng cửa sổ SSH đang mở sẵn để trả hai option về giá trị cũ rồi bình tĩnh tìm nguyên nhân.
Riêng với các hệ thống cài đặt WordPress nằm trong thư mục con như /blog, tuyệt đối không áp dụng máy móc câu lệnh gán chung một URL của site gốc. Bạn phải giữ nguyên tỷ lệ cấu trúc tương quan giữa đường dẫn chứa mã nguồn và đường dẫn hiển thị công khai theo đúng tài liệu kiến trúc của WordPress. Việc nâng cấp giao thức từ HTTP lên HTTPS đơn thuần khác hẳn với một cuộc đại phẫu vừa đổi giao thức vừa dời đường dẫn thư mục.
Một trong những nguyên nhân hàng đầu gây ra lỗi ERR_TOO_MANY_REDIRECTS khiến anh em quản trị web mất ăn mất ngủ chính là thói quen “thừa còn hơn thiếu”: vừa bật ép chuyển hướng trên Cloudflare, vừa cài thêm plugin SSL trong WordPress, lại vừa viết lệnh chuyển hướng trong NGINX. Khi mỗi tầng hiểu giao thức theo một kiểu, request của khách sẽ bị đá qua đá lại như quả bóng bàn cho đến khi trình duyệt bỏ cuộc. Nếu lúc chạy Certbot công cụ đã tự động sinh khối chuyển hướng HTTP sang HTTPS trong cấu hình NGINX, bạn hãy đọc kỹ và tận dụng luôn thiết lập đó để quy về một mối. Khối cấu hình vhost lắng nghe cổng 80 tối giản dưới đây chỉ nên áp dụng sau khi cổng 443 (TLS) của tên miền chính đã vận hành trơn tru:
server {
listen 80;
server_name lab-cf02.localhost.vn;
return 301 https://lab-cf02.localhost.vn$request_uri;
}
Khi đưa đoạn cấu hình này vào hệ thống thực tế, hãy ghép khéo léo vào kiến trúc file vhost hiện có, tránh tạo trùng lặp nhiều khối server cùng lắng nghe cổng 80 cho một server_name. Đặc biệt, hãy đảm bảo luồng xác thực tên miền HTTP-01 tại đường dẫn /.well-known/acme-challenge/ vẫn hoạt động thông suốt phục vụ việc gia hạn chứng chỉ tự động của Certbot, sau đó chạy thử lệnh gia hạn nháp (dry-run) để xác nhận chắc chắn. Tuyệt đối không đụng chạm tới khối cấu hình của các tên miền khác đang nằm chung trên cùng VPS.
sudo nginx -t &&
sudo systemctl reload nginx &&
curl --fail --show-error --connect-timeout 10 --max-time 30 \
-IL --max-redirs 5 http://lab-cf02.localhost.vn/
Kết quả chuẩn mực khi theo dõi qua curl -IL là một chuỗi chuyển hướng gọn gàng: khách gõ đường dẫn HTTP sẽ nhận mã 301 Moved Permanently nhảy thẳng một bước duy nhất tới đúng URL HTTPS chính thức và kết thúc bằng mã phản hồi 200 OK, không bao giờ có chuyện vòng ngược về HTTP hay nhảy qua tên miền cũ. Nếu website có kèm theo tên miền phụ hoặc bí danh (như biến thể có www và không www), chứng chỉ SSL vẫn phải bao phủ hợp lệ cả tên bí danh đó phòng trường hợp khách gõ trực tiếp địa chỉ HTTPS của bí danh trước khi lệnh redirect kịp kích hoạt.

Sơ đồ quy trình xử lý nội dung an toàn do localhost.vn biên soạn để minh họa các bước thực hiện, không phải ảnh chụp màn hình từ lab.
Vì sao đã chuyển hết cài đặt sang HTTPS mà biểu tượng ổ khóa trên thanh địa chỉ vẫn biến mất hoặc hiện cảnh báo tam giác chấm than? Đó là lúc bạn đối mặt với Mixed Content (nội dung hỗn hợp): trang HTML chính được tải qua kênh HTTPS bảo mật, nhưng bên trong mã nguồn trang lại lén gọi một tấm ảnh, một file CSS hay một đoạn mã JavaScript qua đường dẫn http:// trần trụi. Để bắt tận tay những đường dẫn lạc nhịp này, bạn hãy mở trang chủ, một bài viết có chèn nhiều hình ảnh và trang chứa biểu mẫu liên hệ, sau đó bật Developer Tools (F12) trên trình duyệt và chuyển qua hai tab Console cùng Network. Mọi yêu cầu HTTP phát sinh từ trang HTTPS sẽ hiện nguyên hình kèm theo dòng cảnh báo vàng hoặc đỏ chót. Hãy lập danh sách các URL gây lỗi cùng vị trí xuất phát của chúng: nằm trực tiếp trong nội dung bài viết (post_content), găm cứng trong file CSS của giao diện (theme), nằm ở thanh bên (widget) hay được nhúng từ một dịch vụ bên thứ ba.
Đối với các tài nguyên tĩnh nằm ngay trên máy chủ của bạn, bước đầu tiên là copy đường dẫn đó, đổi thử chữ http:// thành https:// rồi mở trực tiếp trên trình duyệt xem file có tải về ngon lành không trước khi bắt tay vào sửa cơ sở dữ liệu. Còn nếu tài nguyên đó được gọi từ một máy chủ bên ngoài vốn dĩ không hề hỗ trợ HTTPS, bạn buộc phải cân nhắc tải file về tự lưu trữ trên VPS của mình hoặc mạnh dạn gỡ bỏ tích hợp đó. Đừng bao giờ hướng dẫn người dùng tắt tính năng bảo vệ của trình duyệt để tải nội dung không an toàn — làm vậy chẳng khác nào lắp cửa khóa vân tay xịn xò nhưng lại khoét một lỗ hổng to đùng bên cạnh.
Kinh nghiệm xương máu là đừng chỉ nhìn bằng mắt thường thấy ảnh trong bài viết hiện đủ mà vội mừng. Hãy rà soát kỹ cả các thuộc tính background-image ẩn sâu trong file CSS, các file font chữ, khung nhúng iframe và đặc biệt là các tập tin thực thi JavaScript. Các trình duyệt hiện đại ngày nay có cơ chế tự động nâng cấp (auto-upgrade) một số tài nguyên thụ động như hình ảnh lên HTTPS, nhưng lại thẳng tay chặn đứng (block) các tài nguyên chủ động như script hay iframe vì lý do an ninh mạng.
Đúng 21:02:53 giờ Việt Nam ngày 01/10/2026, khi mở một trang thực hành riêng biệt trên máy chủ LAB-CF-02, giao diện trang web vẫn hiển thị bình thường nhưng dòng trạng thái cứ treo mãi ở thông báo “Đang chờ script”. Nguyên nhân là trong bài viết thử nghiệm này, chúng tôi đã chủ đích nhúng một tập tin JavaScript nằm trên cùng máy chủ lab nhưng lại gọi qua giao thức http://. Ngay lập tức, trình duyệt Chrome ghi nhận lỗi Mixed Content đỏ rực trong bảng Console và cắt đứt kết nối tải file, khiến đoạn mã xác nhận thực thi không bao giờ chạy được. Đây là tình huống được dàn dựng có kiểm soát trên bài viết nháp để minh họa trực quan cơ chế phòng vệ của trình duyệt, hoàn toàn không ảnh hưởng tới các nội dung chính thức đang vận hành.
Ảnh chụp giao diện thực tế từ phía trình duyệt khách ở trạng thái trước khi khắc phục, ghi nhận lúc 21:02:53 giờ Việt Nam ngày 01/10/2026. Ảnh được cắt gọn vùng hiển thị chính, giữ nguyên độ phân giải pixel gốc và đóng dấu logo ở chân ảnh; bạn có thể bấm vào ảnh để xem kích thước đầy đủ. Qua đó thấy rõ: việc trang web trả về giao diện nhìn thấy được không hề đồng nghĩa với việc các đoạn mã chức năng bên dưới đã vận hành.
Ảnh chụp bảng Console thực tế trong cùng thời điểm trước khi sửa lúc 21:02 ngày 01/10/2026. Vùng thông báo lỗi được giữ nguyên vẹn từng pixel mà không hề vẽ hay dựng lại bằng công cụ đồ họa. Hãy bấm vào ảnh để đọc chi tiết đường dẫn URL bị tuýt còi và lý do trình duyệt thẳng tay chặn thực thi.
Khi gặp hiện tượng tương tự trên dự án thực tế (ví dụ nút bấm mua hàng liệt cảm ứng, thanh trượt ảnh đứng im sau khi lên HTTPS), việc đầu tiên bạn cần làm là mở bảng Console để tóm gọn URL bị chặn rồi truy ngược về nơi sinh ra nó. Hãy thử mở bản HTTPS của tập tin đó trên trình duyệt xem máy chủ đã phục vụ chuẩn chưa rồi mới tiến hành sửa mã nguồn. Luôn tôn trọng cơ chế chặn Mixed Content của trình duyệt và nghiệm thu kỹ lưỡng từng tính năng tương tác, thay vì chỉ nhìn mã phản hồi HTTP 200 của trang HTML mà vội thở phào. Để hiểu sâu hơn về phân loại tài nguyên thụ động và chủ động cũng như cách trình duyệt ứng xử với từng loại, bạn có thể tham khảo tài liệu chuẩn mực của MDN về Mixed Content.
--dry-runKhi phát hiện hàng trăm đường dẫn hình ảnh, liên kết nội bộ mang http:// cũ kỹ đang nằm rải rác trong cơ sở dữ liệu, sai lầm chí mạng nhất của dân tay ngang là mở phpMyAdmin lên và phang ngay một câu lệnh UPDATE ... SET ... REPLACE() thuần SQL. Vì sao ư? Bởi vì WordPress cùng hàng tá plugin và page builder rất chuộng lưu trữ mảng dữ liệu dưới định dạng PHP serialized — nơi mỗi chuỗi văn bản đều đi kèm con số đếm chính xác độ dài byte của nó (ví dụ s:28:"http://lab-cf02.localhost.vn"). Khi bạn đổi http (4 ký tự) thành https (5 ký tự) bằng lệnh SQL thông thường, độ dài chuỗi tăng lên 29 nhưng con số khai báo vẫn dậm chân ở 28, làm vỡ tan cấu trúc mảng serialized và khiến toàn bộ cấu hình widget, theme options hoặc bố cục trang bốc hơi không dấu vết. Để xử lý bài toán này một cách êm ái, hãy giao phó cho wp search-replace của WP-CLI — công cụ biết tự động giải tuần tự hóa (unserialize), thay thế chuỗi rồi đóng gói lại độ dài byte chuẩn xác đến từng milimet:
(
set -eu
: "${WP_ROOT:?Đặt WordPress clone đã kiểm}"
: "${OLD_HTTP_URL:?Đặt URL HTTP cũ đúng site}"
: "${TARGET_HTTPS_URL:?Đặt URL HTTPS đích đã kiểm}"
test "$(id -u)" -ne 0
case "$WP_ROOT" in /*) ;; *) exit 1 ;; esac
case "$OLD_HTTP_URL" in http://*) ;; *) exit 1 ;; esac
case "$TARGET_HTTPS_URL" in https://*) ;; *) exit 1 ;; esac
test "${OLD_HTTP_URL#http://}" = "${TARGET_HTTPS_URL#https://}"
test ! -L "$WP_ROOT"
test -O "$WP_ROOT"
test -r "$WP_ROOT/wp-load.php"
cd -- "$WP_ROOT"
wp search-replace "$OLD_HTTP_URL" "$TARGET_HTTPS_URL" \
--all-tables-with-prefix --skip-columns=guid --dry-run
)
Khối lệnh mẫu bên trên chỉ thực hiện đổi giao thức từ HTTP sang HTTPS khi tên miền và cấu trúc đường dẫn giữ nguyên vẹn; bạn hãy chú ý giữ đồng nhất quy ước không có dấu gạch chéo (trailing slash) ở cuối cả hai biến URL. Dù lớp kiểm tra đầu lệnh đã giúp xác minh quyền sở hữu thư mục và đường dẫn, bạn vẫn cần tự mình rà soát lại file wp-config.php để chắc chắn mình đang thao tác trên đúng cơ sở dữ liệu mục tiêu. Hãy luôn chạy kèm cờ --dry-run trước tiên để đọc bảng thống kê số lượng ô dữ liệu dự kiến sẽ thay đổi mà chưa ghi đè thật xuống đĩa. Chỉ sử dụng tùy chọn --all-tables-with-prefix khi bạn nắm chắc tiền tố bảng (table prefix) đó thuộc độc quyền của một website duy nhất và hiểu rõ các bảng dữ liệu do plugin tạo thêm. Riêng với mô hình WordPress Multisite, quy trình thay thế URL phức tạp hơn nhiều và tuyệt đối không được áp dụng rập khuôn câu lệnh của website đơn lẻ.
Nếu kết quả chạy --dry-run báo tổng số thay thế bằng 0, điều đó có nghĩa là trong phạm vi các bảng và cột đã quét không còn tồn tại chuỗi URL HTTP mục tiêu nào nữa — lúc này bạn hoàn toàn không cần chạy lại lệnh bỏ cờ --dry-run chỉ để cho đủ thủ tục. Ngược lại, khi con số dự kiến thay thế hoàn toàn hợp lý với thực tế nội dung và bản sao lưu SQL đã nằm gọn trong tay, bạn mới gỡ bỏ cờ --dry-run để áp dụng thay đổi thật. Lưu ý đừng bao giờ chạy lệnh thay thế mù quáng chuỗi http:// ngắn ngủn thành https:// trên toàn bộ database vì sẽ làm hỏng các đường dẫn tài nguyên bên ngoài vốn không hỗ trợ TLS. Ngoài ra, theo đúng chuẩn mực vận hành WordPress, chúng ta luôn giữ nguyên cột guid (thông qua cờ --skip-columns=guid) khi chỉ đổi URL trên website đang hoạt động để tránh làm các trình đọc RSS hiểu lầm bài cũ thành bài mới đăng.
Sau khi cập nhật database xong xuôi mà mở trình duyệt lên vẫn thấy bóng dáng đường dẫn http:// cũ kỹ, bạn đừng vội hoảng hốt nghi ngờ WP-CLI hỏng: 99% trường hợp là do bộ nhớ đệm (cache) của plugin tạo trang tĩnh, Object Cache hoặc lớp đệm CDN ở phía trước vẫn đang nhiệt tình trả về bản HTML cũ. Hãy tiến hành xóa sạch (purge) đúng các lớp cache đang sử dụng, sau đó mở lại chính những trang từng bị báo lỗi Mixed Content bằng cả cửa sổ ẩn danh (đóng vai khách truy cập) lẫn tài khoản quản trị viên. Hãy ghi chép đầy đủ danh sách các URL đã xử lý cùng mã trạng thái phản hồi sau khi khắc phục.
Đúng 21:02:57 giờ Việt Nam ngày 01/10/2026, đường dẫn tập tin script trong bài viết thử nghiệm đã được cập nhật sang giao thức HTTPS thông qua WordPress REST API trên đúng ID bài viết xác định (sau khi đã đối chiếu kỹ ID, dấu hiệu nhận diện và mã băm SHA của nội dung). Ở bước xử lý điểm này, chúng tôi sửa đích danh bài viết thử nghiệm chứ không quét wp search-replace toàn cục; còn bài tập chạy search-replace hàng loạt ở Bước 5 được thực nghiệm độc lập trên cơ sở dữ liệu của bản clone.
Ngay sau khi cập nhật, yêu cầu tải file script lập tức trả về mã trạng thái 200 OK, kiểu dữ liệu MIME chuẩn application/javascript và mã băm SHA của nội dung tải về khớp hoàn toàn với tập tin gốc trên máy chủ. Trên giao diện trang web, dòng thông báo đã chuyển sang “HTTPS script đã chạy”, xác nhận mã lệnh thực thi trơn tru và bảng Console hoàn toàn sạch bóng cảnh báo đỏ. Toàn bộ quá trình khắc phục này diễn ra gọn gàng mà không cần đụng chạm tới cài đặt URL gốc của hệ thống, giao diện hay cấu hình chứng chỉ TLS của máy chủ lab.
Ảnh chụp bảng Network thực tế ở trạng thái sau khi đã sửa lỗi, ghi nhận lúc 21:02:57 giờ Việt Nam ngày 01/10/2026. Trong bảng vẫn còn lưu dòng yêu cầu favicon bị hủy (canceled) không liên quan; kết luận trả về mã 200 thành công được xác lập riêng cho tập tin script mục tiêu. Ảnh giữ nguyên pixel gốc kèm chân trang logo; bạn có thể bấm vào ảnh để xem chi tiết. Thông số kiểu MIME và mã băm được xác minh bổ sung qua bước đối chiếu phản hồi độc lập.
Ảnh chụp màn hình trang web thực tế sau khi sửa lỗi lúc 21:02 ngày 01/10/2026, giữ nguyên pixel gốc. Dòng trạng thái xác nhận chức năng JavaScript trong bài thử nghiệm đã hoạt động bình thường trở lại (lưu ý đây là bằng chứng thực thi script, không đại diện cho việc nghiệm thu đăng nhập hay gửi biểu mẫu).
Khi áp dụng vào website của chính bạn, hãy rà soát lại từng request từng bị trình duyệt chặn trước đó kết hợp với việc bấm thử các tính năng tương tác phụ thuộc vào chúng. Hãy lưu lại mã phản hồi HTTP, kiểu nội dung (Content-Type), màn hình Console sạch lỗi và kết quả hiển thị trên giao diện. Đâu có bệnh thì bốc thuốc đúng chỗ đó; nếu phát hiện thêm các cảnh báo khác, hãy tách riêng danh sách và tiếp tục rà soát hết các mẫu trang đại diện (trang chủ, chuyên mục, bài viết chi tiết, trang thanh toán) — bởi một tập tin chạy thành công trên một bài lẻ chưa đủ để đóng dấu chứng nhận toàn bộ website đã sạch bóng Mixed Content.

Sơ đồ danh mục nghiệm thu sau chuyển đổi do localhost.vn biên soạn nhằm tóm tắt quy trình, không phải ảnh chụp kết quả từ môi trường lab.
Trong quá trình chuyển đổi sang HTTPS, nếu chẳng may vấp phải sự cố, bạn có thể khoanh vùng nhanh theo ba triệu chứng kinh điển sau:
http:// hay trả về lỗi 404/500 không, đồng thời xóa sạch cache của các plugin gộp/nén CSS và rà lại hàm gọi tài nguyên trong theme.wp-config.php đang ghi đè ngược về HTTP hay không.Nếu sự cố xảy ra ngay sau khi bạn vừa đổi hai option home và siteurl, hãy dùng SSH chạy lệnh WP-CLI trả chúng về giá trị cũ đã ghi chép để khôi phục quyền truy cập quản trị trong môi trường mạng an toàn — nhưng tuyệt đối không mở cửa cho người dùng cuối gửi mật khẩu đăng nhập qua giao thức HTTP không mã hóa trên Internet. Còn nếu bạn lỡ tay chạy lệnh search-replace sai chuỗi làm hỏng dữ liệu, hãy bình tĩnh sao lưu lại những dữ liệu mới phát sinh (nếu có) rồi tiến hành nạp lại (import) bản sao lưu cơ sở dữ liệu SQL đã tạo ngay trước thời điểm thao tác. Đừng bao giờ tự ý chạy một lệnh search-replace đảo ngược từ https:// về http:// khi chưa phân biệt được đâu là những đường dẫn HTTPS vốn đã đúng từ trước.
Trong phiên thực nghiệm trình duyệt lúc 21:03:01 giờ Việt Nam ngày 01/10/2026, nội dung bài viết thử nghiệm đã được trả về nguyên trạng từng byte như trước lúc sửa. Khi mã băm khớp lại mốc ban đầu, tập tin script HTTP lập tức bị trình duyệt chặn lại như cũ và giao diện quay về thông báo “Đang chờ script”. Thao tác này đóng vai trò đối chứng khoa học để khẳng định 100% nguyên nhân gốc rễ nằm ở giao thức của URL script, hoàn toàn không phải là quy trình rollback database hay xúi bạn mang lỗi quay trở lại website thật.
Ngay sau khi hoàn tất bước đối chứng, chúng tôi đã dọn dẹp sạch sẽ bài viết thử nghiệm, các bản lưu nháp (revisions) cùng tập tin JS phục vụ bài tập. Đường dẫn bài thử nghiệm trả về mã 404 đúng chuẩn, trong khi website chính vẫn trả về mã 200 với nội dung nguyên vẹn. Qua đối chiếu danh mục và mã băm của các bài viết hiện có, tài khoản người dùng, cặp URL chính, chỉ thị noindex, các tập tin wp-config.php, index.php cùng danh sách plugin/theme đều khớp tuyệt đối với mốc trước khi thực hành (dù về mặt lý thuyết không thể khẳng định từng byte thô của toàn bộ hệ quản trị cơ sở dữ liệu giống hệt nhau). Phiên thử nghiệm trình duyệt này cũng không bao gồm việc kiểm thử đăng nhập, gửi biểu mẫu/email hay quét toàn bộ CSS/iframe bên ngoài. Riêng bài tập thực hành đổi URL và khôi phục database bằng SQL trên môi trường clone được ghi nhận độc lập ở khung giờ 20:34–20:35 ngay phần dưới đây.
Câu hỏi thường gặp 1: Vừa lên HTTPS xong có nên bật ngay HSTS (HTTP Strict Transport Security) không?
Lời khuyên của người đi trước là: Khoan hãy vội! HSTS là một cam kết cứng khiến trình duyệt của khách tự động ghi nhớ và ép mọi kết nối tới tên miền của bạn phải đi qua HTTPS trong một khoảng thời gian rất dài (thường từ vài tháng tới cả năm). Trước khi đóng chiếc mộc cam kết đó, bạn hãy vận hành hệ thống ổn định, chắc chắn 100% không còn lỗi chứng chỉ TLS, chuỗi Redirect 301 đã mượt mà, mọi tên miền phụ (subdomain) đều đã có HTTPS (nếu định bật includeSubDomains) và quy trình gia hạn chứng chỉ tự động đã qua kiểm chứng.
Câu hỏi thường gặp 2: Cài một plugin tự động sửa lỗi Mixed Content có đủ thay thế việc sửa Database không?
Các plugin dạng đó có thể đóng vai trò “thuốc giảm đau” tạm thời bằng cách lọc và viết lại đầu ra HTML ngay lúc hiển thị trang, nhưng gốc rễ dữ liệu lưu trong database vẫn đang mang http://. Về lâu dài, việc truy tìm tận gốc nguồn phát sinh URL cũ và chuẩn hóa trực tiếp trong cơ sở dữ liệu cùng file cấu hình sẽ giúp website nhẹ gánh hơn, tránh phụ thuộc vào plugin và không sợ bệnh cũ tái phát mỗi khi bạn đổi giao diện hay gỡ bớt tiện ích.
Phiên rà soát thực tế diễn ra lúc 00:02–00:03 (UTC+7) trên môi trường lab đã hoàn tất cấu hình HTTPS ghi nhận các thông số kỹ thuật sau:
| Hạng mục rà soát | Kết quả quan sát thực tế |
|---|---|
Cặp cấu hình home và siteurl |
Cùng mang giá trị https://lab-cf02.localhost.vn; trong wp-config.php không khai báo hằng số WP_HOME hay WP_SITEURL để ghi đè |
| Truy cập HTTP vào trang chủ | Nhận mã 301 chuyển thẳng sang HTTPS, chỉ qua đúng 1 bước chuyển hướng là trả về mã 200; xác thực chứng chỉ TLS mặc định hoàn toàn hợp lệ |
Truy cập HTTP vào đường dẫn sâu /bai-thu/?qa=redirect |
Nhận mã 301 chuyển sang HTTPS và bảo toàn nguyên vẹn đường dẫn (path) lẫn chuỗi truy vấn (query string), sau 1 bước chuyển hướng trả về 200 |
| Thẻ Canonical của bài viết thử nghiệm | Trỏ chuẩn xác về địa chỉ HTTPS /bai-thu/, đã loại bỏ tham số query thử nghiệm |
Chạy wp search-replace kèm cờ --dry-run |
Báo cáo dự kiến 0 vị trí cần thay thế từ HTTP sang HTTPS của tên miền lab trên toàn bộ các bảng cùng prefix (bỏ qua cột guid); không ghi thay đổi xuống DB |
Bộ phân tích cú pháp (parser) đã quét qua 2 thuộc tính tài nguyên trong mã HTML của trang chủ và 4 thuộc tính trong mã HTML của bài viết thử nghiệm, hoàn toàn không phát hiện bất kỳ chuỗi http:// nào sót lại ở các vị trí đó. Khi mở trên trình duyệt thực tế, cây DOM của bài viết thử nghiệm ghi nhận cả 4 đường dẫn tài nguyên đều dùng HTTPS và thuộc tính action của biểu mẫu bình luận cũng trỏ về HTTPS chuẩn xác. Suốt phiên quan sát không xuất hiện bất kỳ cảnh báo (warning) hay lỗi (error) nào trong Console; tiếng Việt có dấu hiển thị rõ ràng. Trang chủ trong phiên kiểm tra này không xuất thẻ link canonical riêng biệt, tuy nhiên chi tiết đơn lẻ đó hoàn toàn bình thường tùy theo thiết kế của theme và không phải là dấu hiệu lỗi.
Lưu ý về phạm vi kết quả: Con số 0 của lệnh chạy thử --dry-run ở buổi sáng chỉ phản ánh rằng trên cơ sở dữ liệu sạch lúc đó không có chuỗi URL HTTP của tên miền lab trong các cột được quét; nó chưa phải là bài kiểm tra năng lực xử lý dữ liệu serialized hay chứng nhận toàn bộ website không có Mixed Content ẩn ở nơi khác. Phiên quan sát lúc 00:02–00:03 chưa quét sâu vào bên trong nội dung các tập tin CSS, các stylesheet bên ngoài, tài nguyên sinh động bằng JS hay các chuỗi URL bị mã hóa (encoded), và cây DOM hiển thị cũng không thay thế hoàn toàn cho nhật ký Network. Bài viết thử nghiệm tại thời điểm đó cũng chưa đính kèm tập tin đa phương tiện (media). Chính vì vậy, để chứng minh thực tế quy trình thay thế dữ liệu serialized và khôi phục bằng SQL, chúng tôi đã thực hiện riêng một phiên thực nghiệm chuyên sâu trên bản clone vào buổi tối cùng ngày.
Vào tối ngày 01/10/2026, một môi trường clone hoàn toàn mới trên máy chủ LAB-CF-02 đã được dựng lên với cây thư mục mã nguồn, cơ sở dữ liệu và tài khoản database user tách biệt hoàn toàn; tiến trình web server của bản clone chỉ lắng nghe nội bộ tại địa chỉ loopback 127.0.0.1:8082. Toàn bộ tính năng gửi thư, tiến trình định kỳ (cron) và kết nối HTTP đi ra ngoài của ứng dụng đều bị khóa chặt để đảm bảo cô lập tuyệt đối. Chúng tôi chủ động bơm vào database clone bộ dữ liệu thử nghiệm hóc búa gồm: đường dẫn HTTP nằm trong nội dung bài viết, mảng dữ liệu serialized lồng nhau nhiều tầng (nested serialized data) và cột guid nhằm thử lửa khả năng thay thế chính xác của WP-CLI mà không đụng chạm tới hệ thống lab chính.
| Giai đoạn thực nghiệm | Kết quả ghi nhận thực tế | Ý nghĩa kỹ thuật |
|---|---|---|
| 1. Chuẩn bị môi trường | Cặp home/siteurl đang ở HTTP; xuất bản sao lưu SQL riêng biệt trước khi thao tác |
Thiết lập chốt an toàn để sẵn sàng khôi phục về nguyên trạng |
| 2. Đổi cặp URL chính | Cả hai option home và siteurl chuyển sang nhận giá trị HTTPS |
Xác nhận đổi cấu hình gốc ở tầng DB (chưa bao gồm kiểm thử đăng nhập qua trình duyệt) |
3. Chạy thử --dry-run |
Báo cáo phát hiện chính xác 3 vị trí dự kiến thay thế; ảnh chụp dữ liệu trong DB vẫn giữ nguyên chưa đổi |
Khẳng định lệnh tìm đúng dữ liệu HTTP mới bơm vào (khác với kết quả 0 ở buổi sáng) |
| 4. Thực thi thay thế thật (Apply), 20:35:02 | Thay thế thành công 3 vị trí; chạy lại --dry-run ngay sau đó trả về 0; mảng serialized lồng nhau đọc lại nguyên vẹn không vỡ cấu trúc, cột guid được bảo toàn nguyên xi, wp db check báo đạt |
Chứng minh WP-CLI xử lý chuẩn xác dữ liệu serialized trong phạm vi bảng đã chọn và tôn trọng cờ bỏ qua guid |
| 5. Khôi phục từ bản sao lưu SQL, 20:35:07 | Nạp lại file SQL đã lưu: toàn bộ URL, nội dung bài, mảng serialized, cột guid và danh sách bài viết/user quay về đúng mốc trước khi đổi; mã băm file backup nguyên vẹn |
Chứng minh quy trình rollback chuẩn mực là nạp lại bản sao lưu SQL chứ không phải chạy lệnh search-replace đảo ngược |
Ngay sau khi hoàn tất 5 bước thực nghiệm trên, chúng tôi tiếp tục nạp lại bản sao lưu SQL từ mốc sạch ban đầu (trước cả lúc bơm dữ liệu thử nghiệm), xác nhận bản clone phản hồi mã HTTP 200 với nội dung chuẩn xác rồi tiến hành thu dọn toàn bộ tiến trình web server nội bộ, cây thư mục clone, database/user tạm và các biến trạng thái. Mã băm (hash) của bốn bản sao lưu gốc cùng hai file cấu hình website chính trên máy chủ không mảy may suy suyển. Các thông số home, siteurl và chế độ noindex của môi trường lab chính giữ nguyên 100%, cả hai trang web hiện hữu đều vượt qua bài kiểm tra phản hồi HTTP bình thường.
Đúc kết lại cho anh em khi áp dụng vào công việc thực tế: hãy luôn lưu lại kết quả chạy --dry-run trước khi bấm nút thay thế thật, kiểm tra lại khả năng đọc dữ liệu serialized qua tầng ứng dụng WordPress và đối chiếu cột guid. Trước khi trông cậy vào một file sao lưu SQL để cứu nguy cho website sản phẩm, bạn hãy tập dượt thao tác nạp (import) file đó vào một môi trường clone tĩnh lặng không có người dùng đang ghi dữ liệu đồng thời. Lưu ý rằng phiên thực nghiệm database trên clone lúc 20:34–20:35 và phiên xử lý lỗi chặn script trên trình duyệt ở Bước 4 & Bước 6 là hai bài tập độc lập giải quyết hai mảnh ghép khác nhau của bài toán chuyển đổi HTTPS.
Các nguồn tài liệu kỹ thuật chính thống được đối chiếu ngày 01/10/2026: WordPress Advanced Administration: HTTPS, WP-CLI Commands: wp search-replace, và MDN Web Docs: Mixed content. Tài liệu đối chiếu ngày 30/09/2026: Cloudflare SSL/TLS: Full (strict) mode. Toàn bộ kịch bản xử lý sự cố và bảng biểu ghi nhận kết quả trong bài viết do đội ngũ kỹ thuật biên soạn riêng cho chuỗi bài thực hành này.
Mời bạn xem lại tổng thể lộ trình cài đặt và vận hành WordPress trên VPS từ A đến Z. Bài viết trước: Đưa WordPress ra công khai: checklist HTTPS, nội dung, form, index. Bài viết tiếp theo: Email từ WordPress: gửi thử, cấu hình SPF/DKIM/DMARC và giải cứu thư khỏi hố đen Spam.