Operations

Chuyển website sang VPS mới không downtime

Bạn đang chạy website production trên một VPS, nhưng cần nâng cấp lên gói mạnh hơn, chuyển sang hạ tầng khác hoặc VPS cũ sắp hết hạn. Việc tắt website để copy dữ liệu và chuyển DNS là không chấp nhận được nếu bạn vận hành cửa hàng online, SaaS hay bất kỳ dịch vụ nào yêu cầu uptime liên tục. Bài viết này sẽ hướng dẫn bạn từng bước chuyển website sang VPS mới với zero downtime, sử dụng các công cụ như rsync, DNS chuyển tiếp TTL thấp và kiểm tra trước khi chuyển hướng lưu lượng. Phương pháp này đã được kiểm chứng trên môi trường production với nhiều website WordPress, Laravel và các ứng dụng Node.js.

  • rsync đồng bộ dữ liệu (file, database) giữa VPS cũ và VPS mới chỉ với các thay đổi incremental.
  • Đặt TTL DNS xuống mức thấp nhất (60-300 giây) trước 24-48 giờ để chuyển đổi nhanh.
  • Kiểm tra kết nối và hoạt động của website trên VPS mới trước khi switch DNS.
  • Giữ nguyên VPS cũ chạy song song vài ngày để xử lý lỗi nếu có.

Yêu cầu trước khi bắt đầu

  • Hai VPS chạy cùng hệ điều hành (Ubuntu 24.04 LTS trong bài này) hoặc tối thiểu cùng nền tảng (Linux).
  • User có quyền sudo trên cả hai VPS.
  • SSH key đã được cấu hình giữa VPS cũ và VPS mới để tránh nhập mật khẩu khi chạy rsync.
  • Truy cập quản lý DNS (Cloudflare, DigitalOcean DNS, hoặc panel của nhà cung cấp tên miền).
  • Đã cài đặt sẵn web server (Nginx), database (MariaDB/PostgreSQL) và các dependency tương ứng trên VPS mới.

Vì sao cần zero downtime migration?

Khi bạn tắt website để sao chép dữ liệu và chuyển DNS, bạn mất từ vài phút đến vài giờ (nếu dữ liệu lớn). Đối với các trang thương mại điện tử, mỗi phút downtime có thể gây mất doanh thu, tổn hại SEO và giảm niềm tin người dùng. Phương pháp rsync incremental kết hợp với TTL DNS thấp cho phép bạn chuyển dữ liệu trong khi website vẫn chạy, sau đó chỉ chuyển hướng DNS gần như tức thời mà không có khoảng trống.

Bước 1 - Đồng bộ dữ liệu ban đầu với rsync

Đầu tiên, hãy đồng bộ toàn bộ dữ liệu website từ VPS cũ sang VPS mới. Giả sử thư mục web của bạn là /var/www/example.com và bạn dùng database MySQL/MariaDB.

Bước 1a - Sync file:

rsync -avz --delete /var/www/example.com/ root@YOUR_NEW_VPS_IP:/var/www/example.com/

Giải thích: -a (archive) giữ nguyên quyền, timestamp; -v (verbose) hiển thị tiến trình; -z nén dữ liệu; --delete xóa file ở VPS mới nếu file đó đã bị xóa ở VPS cũ, đảm bảo đồng bộ chính xác.

Bước 1b - Sync database: Export database từ VPS cũ và import vào VPS mới ngay lần đầu:

mysqldump -u root -p example_db | ssh root@YOUR_NEW_VPS_IP 'mysql -u root -p example_db'

Đảm bảo database example_db đã được tạo sẵn trên VPS mới trước khi chạy lệnh trên.

Bước 1c - Cấu hình web server: Copy file config Nginx/Apache từ VPS cũ sang VPS mới:

rsync -avz /etc/nginx/sites-available/example.com root@YOUR_NEW_VPS_IP:/etc/nginx/sites-available/
ssh root@YOUR_NEW_VPS_IP 'ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ && nginx -t && systemctl reload nginx'

VERIFY: SSH vào VPS mới và kiểm tra xem thư mục web và database đã được copy:

ls -la /var/www/example.com/
mysql -u root -p -e 'SHOW TABLES FROM example_db;'

Bước 2 - Thiết lập DNS chuyển tiếp với TTL thấp

Trước khi chuyển đổi chính thức (24-48 giờ trước), hãy đặt TTL bản ghi DNS A/AAAA xuống mức thấp. Điều này đảm bảo khi bạn chuyển IP, các DNS resolver và trình duyệt sẽ cập nhật nhanh thay vì cache lâu (thường mặc định 3600-86400 giây).

Các bước:

  1. Đăng nhập vào DNS provider của bạn (ví dụ Cloudflare, GoDaddy, Namecheap).
  2. Chuyển đổi tất cả bản ghi A/AAAA về TTL = 60 (hoặc 120, 300 tùy provider cho phép).
  3. Chờ ít nhất 24 giờ để các DNS resolver cũ hết hạn cache.

Ví dụ trên Cloudflare: Vào DNS tab, click vào giá trị TTL của bản ghi A và chọn "Auto" thành "Custom" và nhập "60". Nếu dùng Cloudflare proxy (màu cam), bạn cũng cần tắt proxy trong thời gian migration để chuyển thẳng IPv4, sau đó bật lại sau khi ổn định.

Bước 3 - Đồng bộ lần cuối (rsync incremental)

Ngay trước khi chuyển DNS (30 phút sau lần sync đầu), chạy lại rsync và database dump để chỉ đồng bộ các thay đổi cuối. Vì lần đầu đã copy hết, lần này chỉ mất vài giây đến vài phút tùy dung lượng thay đổi.

# Đồng bộ file lần cuối
rsync -avz --delete /var/www/example.com/ root@YOUR_NEW_VPS_IP:/var/www/example.com/

# Đồng bộ database lần cuối
mysqldump -u root -p example_db | ssh root@YOUR_NEW_VPS_IP 'mysql -u root -p example_db'

Lưu ý: Khi chạy rsync lần cuối, đảm bảo web server vẫn chạy trên VPS cũ (để không mất dữ liệu mới). Chỉ sau khi rsync xong, bạn mới thực hiện bước chuyển DNS.

Bước 4 - Kiểm tra trước khi chuyển DNS

Trước khi chính thức chuyển hướng lưu lượng, hãy kiểm tra VPS mới bằng cách cập nhật file /etc/hosts trên máy local hoặc dùng curl với header Host.

Cách 1 - Dùng /etc/hosts:

echo "YOUR_NEW_VPS_IP example.com www.example.com" | sudo tee -a /etc/hosts

Mở trình duyệt và truy cập https://example.com, bạn sẽ thấy website chạy từ VPS mới. Kiểm tra tất cả chức năng: form, đăng nhập, thanh toán, API, caching…

Cách 2 - Dùng curl:

curl -H "Host: example.com" https://YOUR_NEW_VPS_IP -I

Kiểm tra response HTTP 200, SSL hợp lệ, và các header (X-Powered-By, Cache-Control).

Sau khi kiểm tra OK, xóa dòng vừa thêm trong /etc/hosts.

Bước 5 - Chuyển DNS sang VPS mới

Khi đã hài lòng với kết quả kiểm tra, thay đổi bản ghi A/AAAA tại DNS provider trỏ đến IP mới. Vì TTL đã được hạ xuống 60 giây, quá trình cập nhật trên toàn cầu sẽ diễn ra trong vòng vài phút.

  1. Đăng nhập DNS provider, thay đổi bản ghi A/AAAA từ IP cũ sang IP mới.
  2. Lưu lại và đợi 5-10 phút.
  3. Kiểm tra từ nhiều máy khác nhau (dùng dig +short example.com hoặc dnschecker.org) để xem IP đã được cập nhật chưa.

Lưu ý: Nếu bạn dùng Cloudflare proxy (màu cam), sau khi trỏ IP mới, bật lại proxy cho các bản ghi A/AAAA. Nếu không dùng proxy, hãy chắc chắn VPS mới đã bật firewall mở port 80/443 (hoặc SSH 22 nếu cần).

Bước 6 - Giữ VPS cũ song song vài ngày

Sau khi chuyển DNS, vẫn giữ nguyên VPS cũ chạy và không đóng tài khoản ngay. Điều này cho phép bạn xử lý các phiên session cũ, cache DNS ở client chưa hết hạn, hoặc sự cố không mong muốn. Bạn có thể tắt VPS cũ sau 24-48 giờ khi chắc chắn mọi thứ ổn định. Dùng tail -f /var/log/nginx/access.log trên VPS cũ để xem có request nào vẫn đến không; nếu không, bạn có thể tắt an toàn.

Xử lý lỗi thường gặp

Lỗi: Website hiển thị lỗi 502 Bad Gateway sau khi chuyển DNS

Kiểm tra PHP-FPM hoặc Node.js service có chạy không trên VPS mới:

systemctl status php8.3-fpm
systemctl status nginx
journalctl -u nginx -n 20

Thường do cấu hình fastcgi_pass trong Nginx config chưa đúng (VD port 9000 vs 9001). Sửa lại file config và reload Nginx.

Lỗi: Một số request vẫn đến VPS cũ sau nhiều giờ

Kiểm tra TTL DNS vẫn còn cache ở các resolver địa phương (VD DNS cơ quan, nhà mạng). Dùng dig +trace example.com để xem đường đi. Bạn có thể giảm TTT hơn nữa (30 giây) hoặc chờ thêm. VPS cũ vẫn chạy nên không mất service, chỉ hơi chậm trong việc đồng bộ dữ liệu mới (nếu có).

Lỗi: SSL không hoạt động trên VPS mới

Nếu bạn dùng Let's Encrypt, hãy chạy certbot trên VPS mới để cấp chứng chỉ mới:

certbot --nginx -d example.com -d www.example.com

Nếu dùng SSL tải xuống, copy file .pem.key từ VPS cũ sang VPS mới bằng rsync và chỉnh đường dẫn trong config Nginx.

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

Có cần tắt website trên VPS cũ khi chạy rsync không?

Không. Rsync có thể chạy khi website vẫn hoạt động. Nó sẽ sao chép dữ liệu và ở lần chạy cuối (ngay trước khi chuyển DNS) chỉ đồng bộ các thay đổi nhỏ, đảm bảo dữ liệu gần như giống hệt.

Thời gian downtime tối thiểu là bao lâu?

Về mặt kỹ thuật là zero. Khi bạn chuyển DNS, quá trình cập nhật diễn ra bất đồng bộ (eventual consistency). Một số client dùng DNS cache cũ sẽ vẫn vào VPS cũ, số khác vào VPS mới. Không có khoảng trống vì cả hai VPS đều chạy và trả lời request. Dù vậy, hãy giảm TTL xuống thấp và giữ VPS cũ chạy 24-48 giờ để tránh lỗi.

Phải làm gì nếu database lớn và rsync quá chậm?

Trước tiên, bạn nên nén database trước khi transfer: mysqldump -u root -p example_db | gzip | ssh root@VPS_MOI 'gunzip | mysql -u root -p example_db'. Hoặc dùng pv để xem tiến trình. Nếu database rất lớn (hàng trăm GB), hãy xem xét dùng replication giữa hai database server, nhưng đó là chủ đề phức tạp hơn.

Có thể dùng công cụ nào thay rsync không?

Bạn có thể dùng rclone để sync lên object storage trung gian (S3-compatible) hoặc scp cho file nhỏ. Tuy nhiên, rsync vẫn là lựa chọn hàng đầu vì chỉ đồng bộ thay đổi, hỗ trợ nén và maintain quyền.

Có cần cấu hình firewall trên VPS mới trước khi chuyển DNS?

Có. Trên VPS mới, hãy chắc chắn mở các port cần thiết (80, 443, SSH) bằng ufw allow 80/tcp hoặc firewalld. Nếu không, người dùng sẽ nhận được timeout khi truy cập.

Sau khi chuyển DNS, có cần thay đổi gì trong config website không?

Nếu website dùng IP cứng để kết nối dịch vụ ngoài (API, SMTP), bạn cần cập nhật IP đó. Còn lại config web server và database đã được copy từ VPS cũ, chỉ cần verify các đường dẫn rất cao (VD /var/www/ trên VPS mới có khác không?).

Bài viết liên quan

Lưu ý: Bài viết mang tính tham khảo, tổng hợp kiến thức chung. Mỗi hệ thống, hạ tầng và nhu cầu có đặc thù riêng, nên kiểm thử trong môi trường an toàn và tham vấn kỹ sư trước khi triển khai thực tế.