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%.
Cách xử lý triệt để lỗi không upload được ảnh trong WordPress trên VPS bằng phân quyền 755/644/2775 với user www-data, tạm biệt thói quen chmod 777 nguy hiểm.
Đừng bao giờ dùng lệnh chmod -R 777 hay chown -R www-data toàn bộ mã nguồn chỉ vì không upload được một tấm ảnh. Hãy giữ code ở mức 755/644 thuộc về deploy user và chỉ cấp quyền ghi 2775 cho group www-data của PHP-FPM tại đúng thư mục wp-content/uploads.
Phạm vi thực hành: Hệ điều hành Ubuntu 24.04 LTS trên máy chủ VPS thử nghiệm riêng biệt với tên miền lab
lab-cf02.localhost.vn. Chỉ thao tác trên hạ tầng do chính bạn quản lý. Đội ngũ đã khảo sát hệ thống tệp tin (filesystem), bắt tận tay lỗi upload qua REST API bị chặn tại thư mục con theo năm/tháng và khắc phục chính xác hai thư mục đó trên LAB-CF-02 vào ngày 30/09/2026 (đợt chạy lúc 23:54 UTC+7 đã tải ảnh và sinh ảnh thu nhỏ thumbnail thành công). Ngày 01/10 lúc 12:56, chúng tôi thực hiện bài test đưa hai thư mục năm/tháng về lại mode755để tái hiện lỗi rồi khôi phục2775bằng tiến trình thăm dò (probe) chạy dưới quyềnwww-data. Cuối cùng, đợt thực nghiệm kết thúc lúc 17:35:49 cùng ngày đã tải ảnh và lưu thuộc tính Alt trực tiếp trên giao diện Media Library, sau đó mở xem trước bài viết nháp trên trình duyệt ở cả khung nhìn máy tính lẫn di động.
Ắt hẳn bất kỳ ai từng tự tay quản trị WordPress trên VPS đều ít nhất một lần chạm mặt thông báo lỗi kinh điển: “Unable to create directory wp-content/uploads/… Is its parent directory writable by the server?” (Không thể tạo thư mục… Thư mục cha có cho phép máy chủ ghi không?). Và phản xạ buồn cười nhưng phổ biến nhất của không ít anh em lúc đang cáu tiết là mở terminal gõ ngay cú phang thần thánh chmod -R 777 /var/www/... cho hết lỗi! Đúng là lỗi biến mất thật đấy, nhưng đổi lại bạn vừa tháo tung toàn bộ cửa nẻo ngôi nhà, mời gọi mọi tiến trình hay mã độc trên máy chủ vào sửa đổi mã nguồn core tự do. Bài viết quyền file WordPress hôm nay sẽ hướng dẫn bạn cách truy tìm chính xác ai đang cần ghi vào đường dẫn nào và chỉ mở khóa đúng cánh cửa của căn phòng đó.
Để không bao giờ phải đoán mò khi phân quyền, bạn hãy hình dung rõ vai trò của ba nhân vật đang cùng làm việc trên thư mục website của chúng ta:
www-data): Là người đầu bếp xử lý mã PHP. Anh ta chỉ cần quyền đọc mã nguồn và file cấu hình, nhưng cần quyền ghi vào đúng khu vực kho chứa wp-content/uploads để lưu hình ảnh do biên tập viên tải lên.Từ sự phân vai rành mạch đó, bộ thông số chuẩn mực hiện ra cực kỳ logic: các thư mục mã nguồn đặt quyền 755, các file mã nguồn đặt quyền 644 (mọi dịch vụ đều đọc và đi qua được, nhưng chỉ chủ sở hữu deploy user mới được quyền sửa code). Riêng file nhạy cảm wp-config.php được siết chặt ở mức 640 với nhóm là www-data (để PHP-FPM đọc được thông số kết nối DB mà người ngoài bị chặn sạch). Cuối cùng, chỉ riêng thư mục wp-content/uploads được cấp quyền 2775 cho nhóm www-data để PHP-FPM thoải mái tạo thư mục năm/tháng và lưu ảnh.

Sơ đồ minh họa kiến trúc do đội ngũ localhost.vn biên soạn nhằm tóm tắt mô hình phân quyền giữa Deploy User và PHP-FPM, không phải ảnh chụp màn hình trên máy chủ lab.
Khi gặp sự cố không tải được ảnh, bạn hãy thử tải lên một tấm ảnh PNG nhỏ gọn (không chứa thông tin nhạy cảm), ghi nhận lại thời điểm và đọc từng chữ trong câu thông báo lỗi của WordPress xem nó đang vấp ở đường dẫn cụ thể nào. Đừng quên kiểm tra nhanh xem ổ đĩa có bị đầy trước khi ngồi tải thử thêm mấy chục tấm ảnh khác nhé.
Trên cửa sổ dòng lệnh SSH của VPS, hãy chạy ngay cụm lệnh khảo sát đường dẫn sau:
ls -ld /var/www/lab-cf02/wp-content
ls -ld /var/www/lab-cf02/wp-content/uploads
namei -l /var/www/lab-cf02/wp-content/uploads
Đây chính là bí quyết của dân làm hệ thống lâu năm: nếu WordPress đang bật tính năng chia thư mục lưu trữ theo từng năm và tháng (ví dụ wp-content/uploads/2026/09), việc bạn chỉ nhìn mỗi quyền của thư mục gốc uploads là hoàn toàn chưa đủ! Rất nhiều trường hợp thư mục uploads gốc có quyền 2775 đẹp đẽ, nhưng thư mục con 2026 hoặc 2026/09 (do một lần giải nén bản sao lưu bằng quyền khác tạo ra) lại mang quyền 755 thuộc về user triển khai — thế là tiến trình www-data bị chặn đứng ngay cửa phòng con! Hãy dùng lệnh namei -l lên tận đường dẫn thư mục tháng hiện tại để soi quyền đi qua (execute bit x) của toàn bộ các thư mục cha từ gốc / đi xuống.
sudo grep -nE '^(user|group|listen)' \
/etc/php/8.3/fpm/pool.d/www.conf
ps -eo user,group,comm | grep php-fpm
Khi nhìn vào danh sách tiến trình từ lệnh ps, bạn sẽ thấy một tiến trình master process của PHP-FPM chạy bằng quyền root, còn các tiến trình con pool www (worker) mới là những người trực tiếp xử lý yêu cầu web của WordPress. Hãy nhìn vào cột user và group của các tiến trình worker này (cũng như đối chiếu với file cấu hình /etc/php/8.3/fpm/pool.d/www.conf). Trên Ubuntu mặc định, danh tính này là www-data.
Sau khi đã xác nhận đúng danh tính worker là www-data, chúng ta hãy nhờ lệnh sudo -u www-data đóng vai chính tiến trình PHP-FPM để kiểm tra quyền đọc code và quyền ghi vào thư mục uploads:
sudo -u www-data test -r /var/www/lab-cf02/index.php
sudo -u www-data test -w /var/www/lab-cf02/wp-content/uploads
Lệnh test của Linux có phong cách rất kiệm lời: nếu thành công nó sẽ im lặng và trả về mã thoát bằng 0. Nếu lệnh kiểm tra quyền ghi (test -w) báo lỗi trên thư mục uploads hoặc thư mục con uploads/2026/09, bạn đã bắt tận tay thủ phạm rồi đấy!
Trong trường hợp bạn vừa dựng website mới mà thư mục wp-content/uploads chưa hề tồn tại, hãy dùng tài khoản triển khai (deploy user) chạy khối lệnh an toàn dưới đây để khởi tạo:
(
set -eu
test "$(id -u)" -ne 0
DEPLOY_USER=$(id -un)
CONTENT_DIR=/var/www/lab-cf02/wp-content
UPLOADS_DIR="$CONTENT_DIR/uploads"
test -d "$CONTENT_DIR"
test ! -L "$CONTENT_DIR"
test "$(stat -c '%U' "$CONTENT_DIR")" = "$DEPLOY_USER"
test -w "$CONTENT_DIR"
test -x "$CONTENT_DIR"
test ! -e "$UPLOADS_DIR"
test ! -L "$UPLOADS_DIR"
mkdir -m 700 -- "$UPLOADS_DIR"
sudo chgrp www-data -- "$UPLOADS_DIR"
chmod 2775 -- "$UPLOADS_DIR"
stat -c '%U:%G %a %n' "$UPLOADS_DIR"
)
Khối lệnh trên lấy danh tính thực của phiên làm việc qua id -un, tự tay tạo thư mục uploads để deploy user giữ quyền chủ sở hữu (owner), sau đó gán nhóm sở hữu (group) sang www-data và đặt chế độ quyền 2775. Con số 2 ở đầu trong 2775 chính là bit setgid: nó ra lệnh cho Linux rằng bất kỳ thư mục năm/tháng nào được tạo mới bên trong uploads sau này cũng sẽ tự động kế thừa nhóm sở hữu www-data thay vì lấy nhóm riêng của người tạo!
Còn nếu thư mục uploads của bạn đã tồn tại từ trước và đang có sẵn các thư mục con (như trường hợp máy chủ LAB-CF-02 trong biên bản cuối bài), bạn cần lưu ý một chi tiết cực kỳ quan trọng: việc bật bit 2775 ở thư mục gốc uploads không tự động sửa lại chế độ quyền của các thư mục con 2026 hay 2026/09 đã được tạo từ trước đó! Bạn cần kiểm tra và cấp quyền 2775 cùng nhóm www-data cho đúng những thư mục năm/tháng đang bị thiếu quyền ghi trong phạm vi uploads. Và làm ơn nhớ kỹ lời dặn này: dù bực mình đến mấy cũng tuyệt đối không chạy lệnh chown -R www-data:www-data /var/www cho toàn bộ máy chủ chỉ để chữa lỗi upload ảnh của một website, vì làm vậy là bạn đang trao quyền tự sửa đổi mã nguồn core của mọi website trên VPS cho tiến trình PHP!
Nếu bạn có dùng lệnh đệ quy để chuẩn hóa lại quyền thư mục mã nguồn về 755 và file mã nguồn về 644, hãy luôn nhớ kiểm tra và giữ nguyên ngoại lệ cho hai vị trí đặc biệt: file két sắt wp-config.php phải giữ nguyên quyền 640, và nhánh wp-content/uploads phải giữ nguyên quyền ghi nhóm 2775.

Sơ đồ minh họa kiến trúc do đội ngũ localhost.vn biên soạn nhằm tóm tắt 4 yếu tố cần rà soát trước khi gõ lệnh chmod, không phải ảnh chụp màn hình trên máy chủ lab.
Có những ngày đẹp trời quyền thư mục uploads đã chuẩn chỉnh 2775 từng milimét mà WordPress vẫn khăng khăng báo không ghi được file. Lúc đó, đừng ngồi gõ đi gõ lại lệnh chmod nữa mà hãy kiểm tra ngay sức khỏe ổ đĩa bằng hai lệnh sau:
df -h /var/www/lab-cf02
df -i /var/www/lab-cf02
Lệnh df -h cho biết dung lượng trống tính theo Gigabyte/Megabyte, còn lệnh df -i kiểm tra một thông số rất hay bị bỏ quên là số lượng inode (hồ sơ quản lý tệp tin trên hệ thống file Linux). Nếu VPS của bạn có hàng trăm nghìn file cache nhỏ li ti hoặc thư rác làm cạn sạch 100% số lượng inode, hệ điều hành sẽ từ chối tạo thêm bất kỳ file mới nào dù dung lượng ổ cứng vẫn còn trống hàng chục GB! Ngoài ra, nếu ổ đĩa gặp sự cố phần cứng và bị hạt nhân Linux tự động chuyển sang chế độ chỉ đọc (read-only mount), mọi thao tác ghi cũng sẽ thất bại.
Trong trường hợp bạn tải ảnh dung lượng nhỏ vài chục KB thì ngon lành nhưng cứ tải ảnh chụp từ máy cơ vài MB lên là báo lỗi (hoặc nhận mã HTTP 413 Request Entity Too Large), thì nguyên nhân nằm ở giới hạn kích thước tải lên: hãy rà soát thông số client_max_body_size trong cấu hình NGINX cùng cặp thông số upload_max_filesize và post_max_size trong file php.ini của PHP-FPM. Còn nếu ảnh gốc tải lên thành công nhưng WordPress không tự cắt được các ảnh thu nhỏ (thumbnail), hãy kiểm tra xem gói thư viện xử lý đồ họa php-gd hoặc php-imagick đã được cài đặt chưa.
Sau khi đã điều chỉnh quyền cho đúng thư mục cần ghi, hãy đăng nhập vào Dashboard WordPress bằng tài khoản có quyền quản lý thư viện và tải thử lại tấm ảnh nhỏ lúc nãy. Quan sát xem ảnh đã hiện hình thu nhỏ trong Media Library chưa, mở đường dẫn trực tiếp của bức ảnh trên một cửa sổ trình duyệt ẩn danh (chưa đăng nhập) xem NGINX có trả về ảnh bình thường không, rồi thử chèn ảnh đó vào một bài viết nháp.
stat -c '%U %G %a %n' /duong-dan-file-anh-vua-tao
Hãy dùng lệnh stat với đường dẫn thực tế của file ảnh vừa được tạo ra trên ổ đĩa: bạn sẽ thấy file ảnh mới này mang chủ sở hữu là www-data (do tiến trình PHP-FPM trực tiếp sinh ra) và nằm gọn trong thư mục năm/tháng. Trong giao diện Thư viện → Tải tệp lên, hãy bấm vào ảnh vừa tải để điền thêm dòng mô tả Văn bản thay thế (Alternative Text), tải lại trang để chắc chắn dữ liệu Alt đã lưu vào database, rồi mở xem trước bài viết nháp trên cả màn hình rộng (Desktop) lẫn khung nhìn hẹp (Mobile). Khi không cần dùng tới tấm ảnh thử nghiệm đó nữa, hãy bấm xóa trực tiếp ngay trong giao diện Media Library để WordPress tự động dọn dẹp luôn cả file gốc lẫn toàn bộ các file ảnh thu nhỏ đi kèm.

Sơ đồ minh họa kiến trúc do đội ngũ localhost.vn biên soạn nhằm tóm tắt quy trình nghiệm thu sau khi xử lý quyền ghi file, không phải ảnh chụp màn hình trên máy chủ lab.
Đây là thắc mắc kinh điển của 99% người mới chuyển từ Shared Hosting sang tự quản trị VPS: khi bạn vào mục Plugins bấm cài mới hoặc cập nhật, WordPress bỗng dưng bật ra một hộp thoại đòi nhập Hostname, FTP Username và FTP Password! Nhiều bạn tưởng VPS của mình bị thiếu dịch vụ FTP liền hì hục đi cài thêm vsftpd, hoặc tệ hơn là nghe lời xúi dại trên mạng gõ chmod -R 777 và chèn FS_METHOD = 'direct' vào wp-config.php.
Sự thật kỹ thuật rất đơn giản: mỗi khi cần cài đặt hay cập nhật plugin/theme, WordPress sẽ tự kiểm tra xem tiến trình PHP-FPM (www-data) có quyền ghi trực tiếp vào thư mục mã nguồn và tạo file mang cùng chủ sở hữu với bộ code hiện tại hay không. Vì trong mô hình bảo mật chuẩn của chúng ta, chủ sở hữu mã nguồn là tài khoản triển khai (deploy user) chứ không phải www-data, nên WordPress lịch sự bật hộp thoại hỏi thông tin FTP để nhờ một tài khoản đúng chủ sở hữu đứng ra ghi file hộ! Thay vì phá vỡ mô hình bảo mật bằng cách giao toàn bộ quyền sửa code cho PHP, cách làm văn minh và an toàn nhất là quản lý, cài đặt và cập nhật plugin/theme thông qua công cụ dòng lệnh WP-CLI dưới tài khoản triển khai (chúng ta sẽ thực hành chi tiết ngay ở bài 41 kế tiếp).
Trước khi thay đổi chủ sở hữu hay chế độ quyền trên bất kỳ nhánh thư mục nào, hãy luôn dùng lệnh stat hoặc ls -ld ghi chép lại thông số hiện trạng vào sổ tay vận hành. Nhờ vậy, khi cần hoàn nguyên bạn có thể trả về đúng con số ban đầu thay vì đoán mò. Đặc biệt lưu ý: nếu bạn phát hiện một website trước đó đã trót bị ai đó chạy lệnh chmod -R 777 trong thời gian dài, việc chỉ gõ lệnh đưa quyền về lại 755/644 là chưa đủ — bạn bắt buộc phải kiểm tra tính toàn vẹn của bộ mã nguồn (bằng wp core verify-checksums), rà soát các file lạ trong thư mục uploads và đổi lại mật khẩu/khóa bảo mật phòng trường hợp mã độc đã kịp cài cắm từ trước.
Trong môi trường học tập (lab) có cần dùng tạm quyền 777 cho nhanh không? Không nên một chút nào. Tập thói quen phân quyền đúng chuẩn 755/644/2775 ngay từ trên máy lab sẽ giúp bạn hình thành phản xạ chuẩn xác khi bước vào vận hành hệ thống thật.
Có phải mọi máy chủ chạy WordPress đều dùng user www-data không? Không phải. www-data là tài khoản mặc định của NGINX và PHP-FPM trên hệ điều hành Debian/Ubuntu. Trên RHEL/AlmaLinux/Rocky Linux nó có thể là nginx hoặc apache, còn trên các hệ thống chia tách nhiều pool PHP-FPM thì mỗi website sẽ chạy dưới một tên user riêng biệt. Đó là lý do Bước 2 luôn yêu cầu bạn kiểm tra thực tế file cấu hình pool trước khi phân quyền.
Khi nào mới được coi là đã xử lý dứt điểm lỗi ghi file? Chỉ khi bạn đáp ứng đủ cả 4 tiêu chí: (1) chỉ rõ được thư mục nào từng bị thiếu quyền và vì sao, (2) tải ảnh lên và xem ảnh ngoài trang công khai thành công, (3) các file mã nguồn index.php và file cấu hình wp-config.php vẫn giữ nguyên quyền chặt chẽ (644 và 640), không bị mở toang cho PHP ghi, và (4) có biên bản đối chiếu trước/sau rõ ràng.
Biên bản dưới đây ghi lại một tình huống thực tế cực kỳ điển hình trên máy chủ LAB-CF-02 vào ngày 30/09/2026 (múi giờ UTC+7): thư mục gốc wp-content/uploads đã có quyền 2775 hoàn hảo, nhưng khi tải ảnh lên vẫn nổ lỗi 500 vì hai thư mục con theo năm/tháng bên trong lại mang quyền 755!
| Mốc thời gian và thao tác | Kết quả quan sát thực tế |
|---|---|
23:01 — Rà soát tại thư mục gốc uploads |
Chủ sở hữu/nhóm là tutorial:www-data, mode 2775; user www-data tạo, ghi và xóa file nháp tại đây thành công |
| 23:47 — Thử tải ảnh qua giao thức REST API | Bị chặn đứng với lỗi HTTP 500, mã lỗi rest_upload_sideload_error |
| Soi sâu vào đường dẫn đích thực tế của tháng 09/2026 | Phát hiện hai thư mục con uploads/2026 và uploads/2026/09 tuy thuộc tutorial:www-data nhưng lại mang mode 755 (thiếu quyền ghi cho nhóm www-data) |
| 23:49 — Cấp quyền đúng chỗ cho hai thư mục con | Chuyển mode của đúng hai thư mục đó từ 755 sang 2775 (giữ nguyên owner/group); phép thử ghi bằng user www-data lập tức chuyển từ false sang true |
| 23:54 — Thử tải lại ảnh qua REST API | Tải lên thành công mỹ mãn với mã HTTP 201 Created; cả URL ảnh gốc lẫn ảnh thu nhỏ thumbnail đều phản hồi 200 OK, mã băm SHA-256 của ảnh gốc khớp 100% với file đầu vào |
Bạn thấy đấy, nếu chỉ nhìn lướt qua thư mục gốc uploads lúc 23:01 rồi kết luận “quyền đúng rồi mà sao vẫn lỗi, thôi chmod 777 hết đi” là sập bẫy ngay! Chỉ cần đi dọc xuống đúng thư mục uploads/2026/09 nơi WordPress thực sự đặt bút ghi file, chúng ta chỉ việc chỉnh đúng hai thư mục đó sang 2775 mà không cần đụng chạm tới bất kỳ file mã nguồn nào khác (file index.php vẫn giữ nguyên 644 và wp-config.php vẫn giữ nguyên 640; dung lượng ổ đĩa lúc đó mới dùng 7% và inode mới dùng 2%).
Vào lúc 10:52:49 ngày 01/10/2026 (UTC+7), chúng tôi chạy kịch bản rà soát tổng thể cấu hình và quyền truy cập trên LAB-CF-02, đồng thời thử tạo và xóa một file thăm dò (probe file) dưới danh tính www-data để lưu lại bằng chứng trực quan trên màn hình console:
| Hạng mục xác minh | Kết quả quan sát thực tế |
|---|---|
| Mã nguồn và file cấu hình | index.php: tutorial:www-data, mode 644; wp-config.php: cùng owner/group, mode 640; kiểm tra cú pháp PHP đạt |
Cây thư mục uploads |
Thư mục gốc uploads, uploads/2026 và uploads/2026/09 đều thuộc tutorial:www-data với mode 2775 |
| Giới hạn quyền của user PHP-FPM | www-data đọc được wp-config.php nhưng bị chặn hoàn toàn quyền ghi vào index.php |
| Cấu hình Pool và Unix socket | Pool chạy dưới user/group www-data; lắng nghe tại /run/php/php8.3-fpm.sock với owner/group socket là www-data |
| Phép thử ghi file tạm (probe) | Tạo và xóa file tạm thành công; file sinh ra mang owner/group www-data:www-data, mode 600 |
| Phản hồi HTTP HEAD bảo vệ cấu hình | wp-config.php: 403; .bak: 403; .old: 404 |
Ảnh chụp màn hình console thực tế lúc 10:53:28 ngày 01/10/2026 (UTC+7) của đợt chạy bắt đầu lúc 10:52:49; giữ nguyên điểm ảnh gốc và đính kèm logo nhận diện. Toàn bộ mật khẩu và chuỗi khóa nhạy cảm đều được bảo mật tuyệt đối. Bấm vào ảnh để xem kích thước đầy đủ.
Một lưu ý thực tế: vì bức ảnh trên chụp vào ngày 01/10 nên kịch bản vẫn kiểm tra trên thư mục uploads/2026/09 đã tạo từ hôm trước; khi bước sang tháng mới, WordPress sẽ tạo tiếp thư mục uploads/2026/10 (và nhờ bit setgid 2775 trên thư mục cha uploads/2026, thư mục tháng 10 mới sinh ra cũng sẽ tự động kế thừa nhóm www-data).
Để chứng minh mối quan hệ nhân quả rõ ràng 100% giữa chế độ quyền 755 và lỗi từ chối ghi file, trong khoảng thời gian 12:56:26 đến 12:56:27 ngày 01/10/2026 (UTC+7), chúng tôi thực hiện một bài thực nghiệm có kiểm soát trên đúng hai thư mục uploads/2026 và uploads/2026/09 bằng tiến trình thăm dò hệ điều hành chạy dưới danh tính www-data (UID/GID 33):
| Trạng thái thử nghiệm | Kết quả quan sát thực tế |
|---|---|
1. Trạng thái ban đầu (hai thư mục ở mode 2775) |
Tiến trình www-data tạo, đọc và xóa file probe (mode 600) thành công |
2. Đưa hai thư mục về lại mode 755 |
Thao tác ghi lập tức bị hệ điều hành từ chối với mã lỗi errno 13 (Permission denied) |
| 3. Kiểm tra trang đọc bài viết trong lúc đang khóa ghi | Các bài viết đã xuất bản trên cả site gốc lẫn bản clone vẫn hiển thị bình thường cho khách |
4. Khôi phục mode 2775 cho hai thư mục |
Đối chiếu khớp chuẩn inode/device, owner/group và mode; tiến trình www-data lập tức tạo/đọc/xóa file probe thành công trở lại |
| 5. Hậu kiểm toàn diện | Danh mục file trong uploads, quyền sở hữu và mã băm (hash) của các file giữ nguyên 100% như trước khi thử; cả 6 phép thử HTTP trước/trong/sau đều đạt |
Bài thực nghiệm ngắn gọn kéo dài đúng 1 giây trên cho thấy: khi quyền thư mục con bị tụt về 755, khách truy cập vẫn đọc được bài viết cũ như thường nên chủ web rất khó phát hiện ra lỗi cho tới tận lúc vào đăng bài mới và tải ảnh lên. Và ngay khi trả lại quyền 2775 cho nhóm www-data, khả năng ghi file lập tức hồi phục mà không cần khởi động lại bất kỳ dịch vụ nào.
Để khép lại chuỗi bài kiểm tra bằng trải nghiệm thực tế của người dùng cuối trên trình duyệt, vào đợt chạy kết thúc lúc 17:35:49 ngày 01/10/2026 (UTC+7), chúng tôi mở trình duyệt đăng nhập vào Dashboard của LAB-CF-02 và thực hiện tải lên một tấm ảnh PNG kích thước 1120 × 857 pixel (dung lượng 49.614 byte) thông qua giao diện Media Library:
Ảnh chụp trình duyệt thực tế ngày 01/10/2026 ngay trước khi bấm chọn tệp ảnh tải lên (lúc này thư viện chưa có tệp media nào). Ảnh giữ nguyên điểm ảnh giao diện gốc và đính kèm logo ở chân ảnh; bấm vào ảnh để xem bản đầy đủ.
Ngay sau khi chọn file ảnh qua nút bấm trên giao diện, WordPress đã lưu file vào thư mục uploads, tự động cắt các kích thước ảnh thu nhỏ và tạo bản ghi đính kèm (attachment ID 22). Tiếp đó, chúng tôi mở hộp thoại chi tiết ảnh, điền dòng mô tả Văn bản thay thế (Alt text) bằng tiếng Việt, đợi hệ thống tự lưu rồi tải lại (reload) toàn bộ trang trình duyệt để xác nhận dòng chữ Alt đã thực sự nằm chắc trong cơ sở dữ liệu:
Ảnh chụp giao diện thực tế ngày 01/10/2026 sau khi đã lưu thuộc tính Alt và tải lại trang. Bấm vào ảnh để xem kích thước đầy đủ.
| Hạng mục nghiệm thu | Kết quả ghi nhận thực tế |
|---|---|
| Tải ảnh và lưu Alt text trên giao diện UI | Khởi tạo thành công attachment ID 22; văn bản thay thế tiếng Việt giữ nguyên vẹn sau khi tải lại trang |
| Truy cập file ảnh từ phiên khách (chưa đăng nhập) | Cả file ảnh gốc lẫn 3 bản thu nhỏ (150 × 150, 300 × 230, 1024 × 784) đều phản hồi HTTP 200 với kiểu MIME image/png |
| Kiểm tra tính toàn vẹn của file ảnh gốc | Dung lượng đúng 49.614 byte; mã băm SHA-256 khớp tuyệt đối 100% với file ảnh đầu vào |
| Hiển thị trong bản xem trước bài viết nháp (Preview) | Bài nháp ID 23 hiển thị hình ảnh rõ nét kèm đúng thuộc tính Alt trên cả khung nhìn máy tính 1440px lẫn di động 390px (bề rộng hiển thị thực tế lần lượt đạt 645px và 330px) |
| Dọn dẹp dữ liệu thử nghiệm | Đã xóa sạch bài nháp ID 23 cùng attachment ID 22 và đóng phiên trình duyệt |
Ảnh chụp giao diện xem trước (Preview) bài viết nháp trên khung nhìn máy tính rộng 1440 pixel vào ngày 01/10/2026 (đợt chạy hoàn tất lúc 17:35:49). Bấm vào ảnh để xem kích thước đầy đủ.
Như vậy, với mô hình phân quyền chuẩn chỉ (755 cho thư mục code, 644 cho file code, 640 cho wp-config.php và 2775 cho nhánh wp-content/uploads), toàn bộ quy trình từ tải ảnh trên giao diện, tự động cắt ảnh thu nhỏ bằng thư viện đồ họa PHP, lưu dữ liệu mô tả Alt cho tới hiển thị trên bài viết đều hoạt động trơn tru mà không cần tới bất kỳ một lệnh chmod 777 nào!
Các tài liệu chính thức được đội ngũ rà soát, đối chiếu lại vào ngày 01/10/2026 gồm WordPress: file permissions và WordPress: Media Library. Các tài liệu nền tảng giữ mốc đối chiếu ngày 30/09/2026 gồm WordPress: gia cố bảo mật (Hardening), Ubuntu: cài đặt và cấu hình PHP và WordPress: Media REST API.
Xem toàn bộ lộ trình WordPress trên VPS. Bài trước: Cấu hình WordPress mà không lộ bí mật DB. Bài tiếp theo: Tạo admin, cài theme/plugin và phân quyền cơ bản.