Trang chủTin tứcChạy nhiều website trên 1 VPS: cấu hình virtual host an toàn
Chạy nhiều website trên 1 VPS: cấu hình virtual host an toàn
Bạn có 5 website nhỏ: blog cá nhân, hai landing page bán hàng, một web công ty và một trang demo cho khách. Thuê 5 VPS riêng thì lãng phí, gom vào hosting share thì thiếu linh hoạt. Giải pháp ở giữa: chạy nhiều website trên 1 VPS với virtual host cấu hình đúng cách — vừa tiết kiệm, vừa giữ được cách

Chạy nhiều website trên 1 VPS: cấu hình virtual host an toàn

Bạn có 5 website nhỏ: blog cá nhân, hai landing page bán hàng, một web công ty và một trang demo cho khách. Thuê 5 VPS riêng thì lãng phí, gom vào hosting share thì thiếu linh hoạt. Giải pháp ở giữa: chạy nhiều website trên 1 VPS với virtual host cấu hình đúng cách — vừa tiết kiệm, vừa giữ được cách ly và an toàn cần thiết.

Bài viết này hướng dẫn cấu hình virtual host an toàn trên cả Nginx và Apache: cách ly user, phân quyền file, SSL từng domain và giới hạn tài nguyên để một website "nghịch" không kéo sập cả dàn.

Khi nào nên gom nhiều website trên 1 VPS?

Gom nhiều website trên một VPS hợp lý khi:

  • Các website có lưu lượng vừa và nhỏ. 5–10 website, mỗi site vài nghìn lượt xem/ngày, hoàn toàn "sống khỏe" trên VPS 4–8GB RAM — trong khi thuê riêng 5 VPS tốn gấp nhiều lần mà tài nguyên đa phần nằm không.
  • Bạn là agency/freelancer quản lý site cho nhiều khách. Một VPS duy nhất giúp quản trị tập trung: backup một chỗ, cập nhật một chỗ, giám sát một chỗ.
  • Các site cùng stack kỹ thuật. Cùng chạy WordPress/PHP trên LEMP/LAMP — dùng chung môi trường giúp tối ưu tài nguyên và đơn giản hóa vận hành.

Đừng gom khi: một website có lưu lượng lớn, đột biến (sẽ "nuốt" tài nguyên các site khác); các site thuộc khách hàng có yêu cầu cách ly nghiêm ngặt (nên tách VPS hoặc container riêng); hoặc bạn không có thời gian quản trị server.

Nguyên tắc vàng: gom website để tiết kiệm chi phí, không phải để tiết kiệm sự cẩn thận. Cấu hình ẩu thì một site bị hack sẽ thành "cửa hậu" vào tất cả các site còn lại.

Nhiều website trên 1 vps: nguyên tắc cách ly: user riêng, PHP-FPM pool riêng

Sai lầm phổ biến nhất: tất cả website chạy dưới cùng một user hệ thống (www-data). Khi đó, website A bị upload shell thì attacker có quyền đọc/ghi file của website B, C, D — vì cùng một user sở hữu tất cả.

Mô hình cách ly đúng:

Mỗi website một system user riêng. Site blog.vn chạy dưới user blogvn, site shop.vn dưới user shopvn. File của website nào thuộc về user đó, và user này không có quyền đọc file của website khác.

Mỗi website một PHP-FPM pool riêng. Mỗi pool chạy dưới một user khác nhau và lắng nghe trên socket riêng:

[blogvn]
user = blogvn
group = blogvn
listen = /run/php/php8.3-fpm-blogvn.sock
pm = dynamic
pm.max_children = 10

Trong virtual host, trỏ fastcgi_pass đến đúng socket của site đó. Mã PHP của site A chạy hoàn toàn dưới quyền user A — không thể "ngó" sang file của site B dù cùng một server.

Tách database user riêng. Mỗi website một database và một DB user chỉ có quyền trên database đó. Đừng dùng chung user root hay một user "all privileges" cho mọi site.

Nhiều website trên 1 vps: cấu hình virtual host Nginx an toàn

Virtual host (Nginx gọi là server block) cho phép một Nginx phục vụ nhiều domain, mỗi domain một file cấu hình riêng trong /etc/nginx/sites-available/, enable bằng symlink sang sites-enabled/.

server {
    listen 80;
    server_name blog.vn www.blog.vn;
    root /home/blogvn/public_html;
    index index.php index.html;

    # Chặn truy cập file ẩn và file nhạy cảm
    location ~ /\. { deny all; }
    location ~* \.(sql|bak|log|env)$ { deny all; }

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php8.3-fpm-blogvn.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

Bốn điểm an toàn: (1) root riêng cho từng site; (2) chặn file ẩn (.git, .env) — kẻ tấn công thường dò các file này để moi thông tin; (3) chặn đuôi file nguy hiểm (.sql, .bak, .log); (4) fastcgi_pass trỏ đúng socket pool riêng của site để đảm bảo cách ly user.

Sau khi thêm/sửa cấu hình, luôn chạy nginx -t kiểm tra cú pháp trước khi systemctl reload nginx — một lỗi cú pháp nhỏ có thể khiến tất cả các site "sập" cùng lúc.

Cấu hình virtual host Nginx an toàn

Nhiều website trên 1 vps: cấu hình virtual host Apache an toàn

Với Apache, mỗi site một file trong /etc/apache2/sites-available/blog.vn.conf, enable bằng a2ensite blog.vn:

<VirtualHost *:80>
    ServerName blog.vn
    ServerAlias www.blog.vn
    DocumentRoot /home/blogvn/public_html

    <Directory /home/blogvn/public_html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    <FilesMatch "^\.|\.(sql|bak|log|env)$">
        Require all denied
    </FilesMatch>

    php_admin_value open_basedir /home/blogvn/public_html:/tmp
</VirtualHost>

Ba điểm cần chú ý:

Tắt Indexes (Options -Indexes): ngăn Apache liệt kê danh sách file khi không có index — tránh lộ cấu trúc thư mục và file backup.

open_basedir: giới hạn PHP của site chỉ được truy cập file trong thư mục của chính nó. Đây là "hàng rào" bổ sung bên cạnh việc tách user.

MPM Event + PHP-FPM thay vì mod_php: mod_php chạy PHP "nhúng" trong tiến trình Apache dưới cùng một user — phá vỡ mô hình cách ly. Hãy dùng MPM Event kết hợp PHP-FPM qua proxy_fcgi, mỗi site một pool riêng.

Cấu hình virtual host Apache an toàn

Phân quyền file và thư mục đúng cách

Quy tắc chuẩn cho mọi site trên VPS:

  • Thư mục: 755 — chủ sở hữu đọc/ghi/thực thi, người khác chỉ đọc và "đi qua".
  • File: 644 — chủ sở hữu đọc/ghi, người khác chỉ đọc.
  • File cấu hình nhạy cảm (wp-config.php, .env): 600 hoặc 640.
  • Không bao giờ 777. Nếu plugin/theme "đòi" 777 mới chạy được, đó là dấu hiệu plugin kém chất lượng — hãy tìm giải pháp khác.

Lệnh chuẩn hóa nhanh cho một site:

chown -R blogvn:blogvn /home/blogvn/public_html
find /home/blogvn/public_html -type d -exec chmod 755 {} \;
find /home/blogvn/public_html -type f -exec chmod 644 {} \;
chmod 600 /home/blogvn/public_html/wp-config.php

Riêng thư mục upload: web server cần quyền ghi để upload ảnh. Cách an toàn là để thư mục này thuộc group của PHP-FPM pool với quyền 775, thay vì mở 777. Và cấm thực thi PHP trong thư mục upload — đây là nơi attacker thường upload shell nhất:

location /wp-content/uploads/ { location ~ \.php$ { deny all; } }  # Nginx

SSL cho từng domain với Let's Encrypt

Mọi website hiện nay đều cần HTTPS. Với Let's Encrypt và Certbot, bạn cấp SSL miễn phí cho không giới hạn domain trên cùng một VPS:

certbot --nginx -d blog.vn -d www.blog.vn -d shop.vn -d www.shop.vn

Certbot tự động xác thực quyền sở hữu domain, cấp chứng chỉ, cấu hình redirect HTTP sang HTTPS và đặt lịch tự gia hạn. Mỗi domain có chứng chỉ riêng — hết hạn hay thu hồi chứng chỉ của site A không ảnh hưởng site B.

Ba lưu ý:

  1. Kiểm tra tự động gia hạn bằng certbot renew --dry-run định kỳ — chứng chỉ hết hạn mà không renew được sẽ khiến site báo lỗi đỏ.
  2. Redirect HTTP → HTTPS cho mọi site: đừng để phiên bản HTTP "sống" song song — vừa mất điểm SEO, vừa để lộ phiên bản không mã hóa.
  3. HSTS (nâng cao): header Strict-Transport-Security buộc trình duyệt luôn dùng HTTPS. Chỉ bật khi HTTPS đã ổn định trên mọi subdomain.

Giới hạn tài nguyên cho từng site

Một site bị traffic spike, bị tấn công hoặc code lỗi gây loop có thể chiếm hết CPU/RAM, khiến các site còn lại "chết chìm" theo. Ba lớp giới hạn:

PHP-FPM pool limits: mỗi pool đặt pm.max_children riêng theo "khẩu phần" của site. Site nhỏ: 5–10 children; site lớn hơn: 20–30. Khi site A vượt quá số children của mình, request của nó phải xếp hàng — site B không bị ảnh hưởng.

Giới hạn kết nối web server: với Nginx, limit_conn và limit_req hạn chế số kết nối và request/giây trên mỗi IP — vừa chống một site bị "cào" quá đà, vừa giảm tác động của tấn công nhắm vào một site cụ thể.

Giám sát theo site: dùng slow log của PHP-FPM (slowlog + request_slowlog_timeout = 5s) để phát hiện site nào đang "ăn" CPU. Khi đã xác định được "thủ phạm", bạn có thể tăng giới hạn cho nó hoặc tối ưu code — thay vì nâng cấp cả VPS một cách mù quáng.

Về lâu dài, nếu một site phát triển vượt trội, hãy "tốt nghiệp" cho nó một VPS riêng — đó là dấu hiệu thành công, không phải thất bại của mô hình multi-site.

Backup và giám sát từng website

Chung một VPS không có nghĩa là chung một bản backup. Mỗi website cần backup độc lập để khi cần khôi phục, bạn chỉ restore đúng site gặp sự cố.

  • File + database riêng từng site: script backup lặp qua danh sách site, nén thư mục web và dump database thành file riêng, đặt tên theo site và ngày.
  • Lịch backup theo mức độ quan trọng: site bán hàng có đơn mỗi ngày → backup hàng ngày; blog ít cập nhật → backup hàng tuần.
  • Lưu backup off-server: backup nằm cùng VPS với dữ liệu gốc thì khi VPS sập, backup cũng "đi" theo. Đồng bộ lên object storage hoặc VPS khác.
  • Test restore định kỳ: backup chưa từng restore thử thì chưa phải là backup. Mỗi quý, restore thử một site lên môi trường staging.

Giám sát cũng theo từng site: uptime monitoring cho từng domain, cảnh báo hết dung lượng ổ đĩa chung, và theo dõi log lỗi PHP-FPM theo từng pool để phát hiện site nào đang sinh lỗi.

Lỗi thường gặp và cách khắc phục

Triệu chứng Nguyên nhân phổ biến Cách khắc phục
Vào domain A hiện nội dung domain B Thiếu server_name, request rơi vào virtual host mặc định Kiểm tra server_name, đặt virtual host mặc định trả 444
Lỗi 403 sau khi phân quyền Web server không có quyền đọc thư mục site Kiểm tra ownership và quyền 755/644
Upload file bị lỗi 500 Thư mục upload không cho phép ghi Chown về user của pool, quyền 775
Site mới thêm không có SSL Quên chạy certbot cho domain mới certbot --nginx -d domain-moi.vn, kiểm tra renew
Một site chậm, các site khác bình thường Pool PHP-FPM quá tải hoặc code lỗi Kiểm tra slow log, tăng pm.max_children hoặc tối ưu code
Tất cả các site cùng sập Lỗi cú pháp config Nginx/Apache nginx -t / apachectl configtest, xem log và rollback
Shell từ site A đọc được site B Các site chung user www-data Tách user + pool PHP-FPM riêng cho từng site

90% sự cố multi-site rơi vào một trong các hàng trên — và đều khắc phục được trong vài phút nếu bạn hiểu nguyên nhân.

Kết luận

Chạy nhiều website trên 1 VPS là nghệ thuật cân bằng giữa tiết kiệm và an toàn. Công thức gói gọn trong 5 việc: mỗi site một virtual host cấu hình chuẩn, mỗi site một system user và PHP-FPM pool riêng, phân quyền file đúng (không bao giờ 777), SSL riêng cho từng domain bằng Let's Encrypt, và backup + giám sát độc lập từng site.

Làm đúng 5 việc này, một VPS 4–8GB RAM hoàn toàn có thể "cõng" 5–10 website vừa và nhỏ một cách an toàn — mỗi site là một "căn hộ riêng" trong cùng một tòa nhà.

Nếu bạn đang tìm VPS đủ mạnh và ổn định để triển khai mô hình multi-site — với SSD Enterprise, băng thông không giới hạn và hỗ trợ kỹ thuật 24/7 — các gói VPS của SunCloud (dùng thử 10–30 ngày) là điểm khởi đầu lý tưởng. Liên hệ hotline 083 979 3434 hoặc truy cập suncloud.vn để được tư vấn cấu hình phù hợp.

Câu hỏi thường gặp

Một VPS 4GB RAM chạy được bao nhiêu website WordPress?

Phụ thuộc lưu lượng và độ nặng của theme/plugin, nhưng thực tế phổ biến là 5–10 site vừa và nhỏ (mỗi site vài nghìn lượt xem/ngày) trên VPS 4GB RAM với PHP-FPM được tinh chỉnh. Dấu hiệu cần nâng cấp: RAM thường xuyên trên 80%. Hãy giám sát thực tế thay vì đoán.

Dùng chung một database cho nhiều website có được không?

Được về mặt kỹ thuật (mỗi site một prefix bảng khác nhau), nhưng không nên. Chung database nghĩa là một site bị SQL injection có thể đọc/ghi dữ liệu site khác, và backup/restore từng site trở nên rắc rối. Hãy tạo database và DB user riêng cho mỗi site.

Có nên dùng Docker thay vì virtual host truyền thống?

Docker cho mức cách ly tốt hơn, nhưng độ phức tạp vận hành cao hơn: quản lý image, volume, network. Với 5–10 site PHP/MySQL thông thường, virtual host + user/pool riêng đã đủ an toàn và đơn giản hơn nhiều. Hãy chọn Docker khi cần chạy nhiều phiên bản PHP khác nhau hoặc cách ly ở mức hệ điều hành.

Website bị hack thì các site khác có an toàn không?

Phụ thuộc mức độ cách ly. Nếu mỗi site có user, PHP-FPM pool, database và open_basedir riêng, attacker từ site A rất khó "nhảy" sang site B. Khi phát hiện một site bị hack: cô lập site đó ngay, đổi toàn bộ mật khẩu/DB user của mọi site, quét mã độc toàn VPS, và vá lỗ hổng gốc trước khi đưa site trở lại.

Certbot tự động gia hạn có đáng tin không?

Có, với điều kiện bạn kiểm tra định kỳ. Certbot tự renew khi chứng chỉ còn dưới 30 ngày. Rủi ro thường gặp: firewall chặn thử thách xác thực, hoặc virtual host bị sửa tay làm hỏng cấu hình certbot. Hãy chạy certbot renew --dry-run mỗi vài tháng và đặt cảnh báo hết hạn SSL.

Nên chọn Nginx hay Apache cho multi-site?

Cả hai đều làm tốt. Nginx nhẹ hơn, xử lý đồng thời tốt hơn với cùng lượng RAM — lợi thế rõ rệt khi nhiều site chung một VPS. Apache dễ cấu hình hơn với .htaccess. Xu hướng hiện nay: Nginx + PHP-FPM là combo phổ biến nhất cho VPS multi-site WordPress vì hiệu năng trên tài nguyên hạn chế.


Tác giả:
Ảnh đại diện của Trường Phạm
Tôi là Trường Phạm, hiện đảm nhiệm vai trò CEO của SunCloud. Với kiến ​​thức sâu rộng về mạng lưới hệ thống, điện toán đám mây và an ninh mạng, góp phần định hướng chiến lược phát triển bền vững cho doanh nghiệp. Tôi đã điều hành SunCloud phát triển và vận hành thành công hàng loạt dự án thực tiễn, mang lại giá trị thực tế cho các doanh nghiệp và cơ sở kinh doanh. Bản thân tôi đã đạt được các chứng chỉ quốc tế uy tín như CCNP, LPI, VCP và không ngừng học hỏi để nâng cao năng lực quản lý cũng như chuyên môn mỗi ngày. Đam mê công nghệ và khao khát cống hiến, tôi luôn nỗ lực xây dựng SunCloud trở thành một hệ sinh thái công nghệ đáng tin cậy, đồng thời lan tỏa những giá trị tri thức hữu ích đến cộng đồng.

Tin tức nổi bật