Khi bạn vận hành nhiều website WordPress trên cùng một server, một chiến lược phổ biến để tiết kiệm tài nguyên là cho các site dùng chung một bộ source code.

Ví dụ:

  • /var/www/wordpress/ → chứa code WordPress duy nhất.
  • example.com, demo.com → mỗi domain trỏ về thư mục code chung.

Tuy nhiên, vấn đề nảy sinh là thư mục wp-content/uploads/. Nếu để mặc định, tất cả các site sẽ cùng ghi file vào chung một nơi → dẫn đến hỗn loạn, khó quản lý và có nguy cơ lộ dữ liệu.


1. Các kịch bản thường gặp

Trường hợp A: Uploads chung cho tất cả site

  • Cách hoạt động: Toàn bộ ảnh/file từ mọi domain được lưu vào wp-content/uploads/.
  • Ưu điểm: Cấu hình mặc định, không cần chỉnh sửa gì.
  • Nhược điểm:
    • Khó quản lý khi hàng chục domain dùng chung → ảnh lẫn lộn.
    • Nguy cơ SEO nhầm lẫn: ảnh từ site A xuất hiện trên site B.
    • Rủi ro bảo mật: một site bị hack có thể xoá/sửa file của site khác.
  • Khi nào nên dùng: Chỉ khi bạn quản lý 1–2 site cá nhân, không quan trọng phân tách dữ liệu.

Trường hợp B: Tách uploads theo domain bằng define('UPLOADS')

Trong wp-config.php thêm:

define('UPLOADS', 'uploads/' . $_SERVER['HTTP_HOST']);
  • Kết quả:
    • example.comwp-content/uploads/example.com/
    • demo.comwp-content/uploads/demo.com/
  • Ưu điểm:
    • Dữ liệu được phân tách theo domain.
    • Cấu hình đơn giản, không cần chỉnh Nginx/Apache.
    • Hoạt động ngay trong core WordPress API (wp_upload_dir()).
  • Nhược điểm:
    • Một số plugin viết ẩu (hardcode wp-content/uploads) có thể không tương thích.
    • Vẫn lưu trong cùng thư mục source code → backup/restore chưa tối ưu.
    • Nếu bạn deploy code mới, cần giữ lại toàn bộ thư mục uploads cho tất cả site.
  • Thích hợp cho: Nhiều site nhỏ, ít plugin phức tạp, cần tách dữ liệu ở mức vừa phải.

Trường hợp C: Dùng Symlink để quản lý uploads

  • Cấu hình:
    • Uploads được lưu tại /var/www/uploads/example.com/var/www/uploads/demo.com.
    • Sau đó tạo symlink: ln -s /var/www/uploads/example.com /var/www/example.com/wp-content/uploads ln -s /var/www/uploads/demo.com /var/www/demo.com/wp-content/uploads
  • Ưu điểm:
    • Tách biệt hoàn toàn dữ liệu từng site.
    • Dễ dàng backup/restore riêng cho từng domain.
    • Có thể di chuyển thư mục uploads ra ổ đĩa khác (SSD/HDD rẻ).
    • Giảm rủi ro khi 1 site bị hack → khó lan sang site khác.
  • Nhược điểm:
    • Cần thao tác thủ công (hoặc script) khi thêm domain mới.
    • Nếu xoá nhầm symlink → site sẽ “mất” toàn bộ ảnh.
  • Thích hợp cho:
    • Nhiều site độc lập nhưng chung code.
    • Môi trường hosting chuyên nghiệp (cần backup theo domain).
    • Dự án lớn, có khả năng mở rộng.

Trường hợp D: Tách hoàn toàn Uploads + CDN

  • Cấu hình: Lưu uploads ra ngoài server hoặc dịch vụ riêng như Amazon S3, Cloudflare R2, hoặc MinIO.
  • Ưu điểm:
    • Giảm tải I/O cho server.
    • Ảnh được phân phát qua CDN nhanh hơn.
    • Dễ scale khi hàng chục site lớn chạy chung.
  • Nhược điểm:
    • Cấu hình phức tạp.
    • Tốn thêm chi phí hạ tầng.
  • Thích hợp cho: Hệ thống nhiều website traffic cao, yêu cầu tốc độ.

2. Bảo mật khi dùng Symlink và phân quyền

  • Symlink: giống “shortcut” trên Windows → an toàn nếu bạn không public trực tiếp /var/www/uploads.
  • Phân quyền chuẩn: chown -R www-data:www-data /var/www/uploads/example.com chmod -R 755 /var/www/uploads/example.com Trong đó:
    • www-data là user của Nginx/Apache/PHP.
    • 755 cho phép webserver đọc/ghi, người khác chỉ được đọc.
  • An toàn hơn:
    • Không cho phép liệt kê thư mục trong Nginx/Apache (autoindex off;).
    • Dùng .htaccess hoặc rule Nginx để chặn truy cập trực tiếp vào file nhạy cảm (.php, .sql, .bak).

👉 Nếu chỉ dùng để lưu ảnh/media, và không public nguyên thư mục uploads qua URL, thì gần như không có rủi ro bảo mật lớn.


3. Tự động hóa bằng script

Khi có nhiều domain, việc tạo thư mục + symlink thủ công dễ nhầm lẫn. Bạn có thể dùng script:

#!/bin/bash

DOMAIN=$1
UPLOAD_DIR="/var/www/uploads/$DOMAIN"
SITE_DIR="/var/www/$DOMAIN/wp-content"

# Tạo thư mục uploads nếu chưa có
mkdir -p $UPLOAD_DIR
chown -R www-data:www-data $UPLOAD_DIR

# Xóa symlink cũ (nếu có)
rm -rf $SITE_DIR/uploads

# Tạo symlink mới
ln -s $UPLOAD_DIR $SITE_DIR/uploads

echo "Đã cấu hình uploads riêng cho $DOMAIN"

Chạy:

bash add_uploads.sh example.com

4. Bảng so sánh nhanh

Cách quản lýƯu điểmNhược điểmKhi nên dùng
Uploads chungDễ triển khaiDữ liệu lẫn lộn, nguy hiểmSite cá nhân nhỏ
define('UPLOADS')Dễ cấu hình, tách domainCó thể lỗi pluginSite vừa, ít plugin
SymlinkTách biệt, backup dễCần script, quản lý phức tạpNhiều site độc lập
CDN/S3Hiệu năng cao, scale tốtTốn chi phí, phức tạpHệ thống lớn, traffic cao

✅ Kết luận

  • Ít site, dễ quản lý → dùng define('UPLOADS').
  • Nhiều site, cần tách biệt rõ → dùng symlink.
  • Hệ thống lớn, traffic cao → cân nhắc S3/CDN.

Dù chọn cách nào, hãy nhớ:

  • Không để lộ thư mục uploads gốc.
  • Luôn phân quyền đúng cho user www-data.
  • Có cơ chế backup định kỳ theo domain.