Chuyển website từ VPS cũ sang VPS mới không chỉ là copy source rồi đổi DNS. Nếu website vẫn có người dùng truy cập trong lúc migrate, dữ liệu có thể thay đổi liên tục: file upload mới, đơn hàng mới, comment mới hoặc bản ghi database mới. Vì vậy, quy trình tốt cần tách thành nhiều giai đoạn: chuẩn bị VPS mới, đồng bộ dữ liệu lần đầu, dump/restore database, test website bằng hosts file hoặc domain tạm, giảm TTL trước cutover, khóa ghi trong một khoảng ngắn, đồng bộ lần cuối và chỉ sau đó mới đổi DNS. Bài viết này hướng dẫn chi tiết quy trình migrate website Linux/Nginx/PHP/MySQL bằng rsync và mysqldump, đồng thời chỉ ra các lỗi dễ gặp như permission sai, cron chạy trùng, SSL chưa sẵn sàng hoặc xóa nhầm file khi dùng `rsync --delete`.
Khi VPS cũ sắp hết tài nguyên, cần đổi datacenter hoặc muốn chuyển sang hạ tầng mới, bạn có thể migrate website sang VPS mới mà không cần để site offline quá lâu. Nhưng để downtime thực sự thấp, cần chuẩn bị trước thay vì chỉ copy file rồi đổi DNS.
Một quy trình tốt thường gồm hai lần đồng bộ:
- đồng bộ lớn lần đầu khi website vẫn chạy bình thường;
- đồng bộ lần cuối sau khi tạm dừng ghi dữ liệu trong thời gian ngắn.
Nếu bạn chưa có stack web trên máy mới, hãy xem bài Hướng dẫn cài website trên VPS Ubuntu. Nếu cần thêm storage trước khi migrate, có thể tham khảo Gắn thêm ổ đĩa trên VPS Ubuntu bằng UUID và fstab.
1. Mục tiêu của một lần migrate tốt
Một lần chuyển website nên đạt các mục tiêu:
- source đầy đủ;
- upload không thiếu;
- database nhất quán;
- permission đúng;
- PHP/runtime tương thích;
- cron không chạy trùng;
- SSL hoạt động;
- DNS chuyển nhanh;
- có phương án rollback.
Downtime tối thiểu không có nghĩa “không chuẩn bị maintenance”. Với website có ghi dữ liệu liên tục, một khoảng khóa ghi ngắn ở bước cuối thường an toàn hơn cố duy trì zero downtime bằng quy trình không kiểm soát.
2. Trước khi migrate, hãy inventory hệ thống cũ
Ghi lại:
- phiên bản Ubuntu;
- Nginx/Apache;
- PHP version và extension;
- MySQL/MariaDB version;
- đường dẫn website;
- database name/user;
- cron job;
- systemd service;
- queue worker;
- Redis/cache;
- SSL certificate;
- upload directory;
- environment file;
- DNS records;
- firewall rule.
Bạn có thể kiểm tra nhanh:
php -v
nginx -v
mysql --version
systemctl list-timers
crontab -l
3. Chuẩn bị VPS mới trước khi copy dữ liệu
VPS mới nên có:
- OS đã update;
- web server;
- PHP/runtime tương thích;
- database server;
- firewall;
- user deploy;
- thư mục website;
- đủ disk/RAM.
Không nên bắt đầu copy hàng trăm GB dữ liệu rồi mới phát hiện PHP version hoặc module thiếu.
Nếu cần một VPS mới để chuyển website, có thể tham khảo VPS tại HUONG CLOUD.
4. Giảm DNS TTL trước ngày chuyển
Nếu DNS hiện có TTL cao, resolver có thể giữ IP cũ lâu sau khi bạn đổi record.
Trước ngày migrate, nên giảm TTL xuống mức hợp lý theo khả năng DNS provider hỗ trợ, ví dụ vài phút.
Lưu ý
TTL chỉ có tác dụng sau khi bản ghi TTL thấp đã được resolver nhận. Nếu bạn giảm TTL ngay trước lúc cutover, các cache cũ vẫn có thể giữ giá trị trước đó tới khi hết TTL cũ.
Vì vậy, nên giảm TTL trước đủ sớm.
5. Backup trước khi làm bất cứ thay đổi nào
Backup tối thiểu:
- source code;
- upload;
- database;
- config;
- SSL/private key nếu cần migrate;
- cron/service config.
Không dùng VPS mới như “backup duy nhất”. Nên có ít nhất một bản sao độc lập.
6. Cài rsync trên hai VPS
sudo apt update
sudo apt install rsync -y
Kiểm tra:
rsync --version
Rsync rất phù hợp cho migrate vì lần chạy sau chỉ cần truyền phần thay đổi thay vì copy lại toàn bộ.
7. Test SSH giữa hai máy
Từ VPS mới, thử:
ssh user@IP_VPS_CU
Hoặc từ VPS cũ đẩy sang VPS mới:
ssh user@IP_VPS_MOI
Nên dùng SSH key để tránh phải nhập password nhiều lần trong quá trình đồng bộ.
8. Chạy rsync dry-run trước
Ví dụ từ VPS cũ:
rsync -avhn /var/www/example.com/ deploy@IP_VPS_MOI:/var/www/example.com/
Trong đó:
-a: archive mode;-v: verbose;-h: human-readable;-n: dry-run, không thay đổi dữ liệu.
Dry-run đặc biệt quan trọng khi bạn định dùng --delete.
9. Đồng bộ source lần đầu
Sau khi dry-run đúng:
rsync -avh --progress /var/www/example.com/ deploy@IP_VPS_MOI:/var/www/example.com/
Nếu website rất lớn, có thể dùng screen hoặc tmux để tránh mất phiên SSH.
10. Có nên dùng rsync --delete?
--delete sẽ xóa file ở destination nếu file đó không còn ở source.
Lệnh ví dụ:
rsync -avh --delete /var/www/example.com/ deploy@IP_VPS_MOI:/var/www/example.com/
Cảnh báo rất quan trọng
Ubuntu manpage của rsync cảnh báo --delete có thể nguy hiểm nếu dùng sai. Hãy luôn chạy --dry-run trước.
Không dùng --delete nếu destination chứa file chỉ tồn tại trên VPS mới mà bạn muốn giữ.
11. Permission và owner có thể khác
Sau rsync, kiểm tra:
ls -la /var/www/example.com
Tùy cách rsync và user, owner/group có thể không giống máy cũ.
Ví dụ app deploy bằng user deploy:
sudo chown -R deploy:www-data /var/www/example.com
Nhưng không có một owner chuẩn cho mọi framework. Hãy dùng quyền đúng theo stack của bạn.
12. Dump MySQL database
Ví dụ:
mysqldump -u website_user -p website_db > website_db.sql
Với database InnoDB lớn, có thể dùng:
mysqldump --single-transaction --quick -u website_user -p website_db > website_db.sql
MySQL ghi rõ --single-transaction phù hợp với transactional tables như InnoDB và giúp dump nhất quán mà không cần lock table trong toàn bộ thời gian dump.
Lưu ý
Nó không bảo đảm consistency tương tự cho MyISAM/MEMORY tables và không nên có DDL thay đổi table trong lúc dump.
13. Copy database dump sang VPS mới
rsync -avh website_db.sql deploy@IP_VPS_MOI:/tmp/
Hoặc:
scp website_db.sql deploy@IP_VPS_MOI:/tmp/
14. Tạo database/user ở VPS mới
Ví dụ:
CREATE DATABASE website_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'website_user'@'localhost' IDENTIFIED BY 'MAT_KHAU_MANH';
GRANT ALL PRIVILEGES ON website_db.* TO 'website_user'@'localhost';
FLUSH PRIVILEGES;
Không dùng root database account cho ứng dụng nếu không cần.
15. Import database
mysql -u website_user -p website_db < /tmp/website_db.sql
Kiểm tra:
mysql -u website_user -p -e "USE website_db; SHOW TABLES;"
16. Đồng bộ file cấu hình ứng dụng
Các file như:
.env;wp-config.php;- Nginx server block;
- systemd unit;
- supervisor config;
- queue config;
cần được kiểm tra riêng.
Không nên public các file chứa password hoặc secret.
17. Test website trên VPS mới trước khi đổi DNS
Cách rất hữu ích là sửa hosts file trên máy tính cá nhân để domain trỏ tạm tới IP mới chỉ với máy bạn.
Ví dụ:
203.0.113.20 example.com www.example.com
Sau đó mở trình duyệt và test site thật với hostname đúng.
Điều này tốt hơn test bằng IP vì nhiều app/nginx config phụ thuộc hostname.
18. Test những gì trên VPS mới?
- homepage;
- login;
- upload;
- form;
- checkout;
- API;
- email;
- queue;
- cron;
- SSL;
- redirect;
- static asset;
- database write;
- admin panel.
Với WordPress, kiểm tra thêm permalink, media và plugin cache.
19. Kiểm tra Nginx config
sudo nginx -t
Reload:
sudo systemctl reload nginx
Nginx hỗ trợ reload graceful: master process kiểm tra cấu hình, khởi động worker mới và shutdown worker cũ theo cách có kiểm soát nếu cấu hình hợp lệ.
20. Đừng chạy cron ở cả hai VPS cùng lúc
Nếu cả VPS cũ và mới đều chạy cron/queue worker, bạn có thể tạo:
- email trùng;
- job trùng;
- order xử lý hai lần;
- backup trùng;
- webhook trùng.
Trong giai đoạn test, hãy disable scheduler/worker trên VPS mới nếu chúng tác động production.
Chỉ bật ở bước cutover.
21. Chuẩn bị maintenance window ngắn
Khi mọi thứ trên VPS mới đã test xong, chọn thời điểm traffic thấp.
Nếu website có dữ liệu ghi liên tục, bật maintenance/read-only trong thời gian ngắn.
Mục tiêu: ngăn dữ liệu mới tiếp tục sinh ở VPS cũ trong lúc đồng bộ cuối.
22. Đồng bộ file lần cuối
Ví dụ:
rsync -avh --delete --dry-run /var/www/example.com/ deploy@IP_VPS_MOI:/var/www/example.com/
Kiểm tra output.
Sau đó bỏ --dry-run:
rsync -avh --delete /var/www/example.com/ deploy@IP_VPS_MOI:/var/www/example.com/
Chỉ dùng --delete nếu bạn hiểu chính xác destination cần mirror source.
23. Dump database lần cuối
Sau khi đã chặn ghi:
mysqldump --single-transaction --quick -u website_user -p website_db > final.sql
Copy sang máy mới và import lại.
Với website rất lớn hoặc yêu cầu gần-zero downtime, có thể dùng replication thay vì full dump ở bước cuối. Nhưng replication phức tạp hơn và là chủ đề riêng.
24. Bật cron/worker trên VPS mới
Sau khi import cuối:
- bật queue worker;
- bật cron;
- bật scheduler;
- restart service app nếu cần.
Đảm bảo các service tương ứng ở VPS cũ đã dừng để tránh xử lý trùng.
25. Đổi DNS sang IP mới
Sửa A/AAAA record:
example.com -> IP_VPS_MOI
Nếu dùng CDN/reverse proxy, cutover có thể thực hiện ở origin config thay vì public DNS tùy kiến trúc.
26. Theo dõi DNS propagation
Kiểm tra:
dig example.com
Hoặc:
nslookup example.com
Kiểm tra từ nhiều resolver nếu cần.
Do cache DNS, một số người dùng vẫn có thể đi tới VPS cũ trong một thời gian.
27. Không tắt VPS cũ ngay
Giữ VPS cũ chạy trong thời gian theo dõi, nhưng tránh nhận ghi dữ liệu mới nếu có thể.
Bạn có thể:
- giữ maintenance page;
- redirect trong kiến trúc phù hợp;
- chỉ để backup/rollback.
Đừng hủy máy cũ ngay sau khi đổi DNS.
28. Theo dõi log VPS mới
Nginx:
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
PHP/service:
sudo journalctl -u php8.x-fpm -f
Tên service phụ thuộc version.
Kiểm tra system:
free -h
df -h
uptime
29. Kiểm tra SSL trên VPS mới
Nếu certificate cũ được copy, kiểm tra private key permission và cấu hình.
Trong nhiều trường hợp, cách sạch hơn là cấp certificate mới sau khi DNS/cutover phù hợp.
Nếu dùng Let's Encrypt và HTTP challenge, domain phải resolve đúng nơi thực hiện challenge.
30. WordPress: lưu ý URL và cache
Nếu domain không đổi, thường không cần search-replace URL trong database.
Nếu domain đổi, hãy dùng công cụ WordPress phù hợp thay vì replace SQL thô vì serialized data có thể bị hỏng.
Sau cutover:
- purge plugin cache;
- purge object cache;
- purge CDN;
- regenerate nếu cần.
31. Laravel/PHP framework: lưu ý
Kiểm tra:
.env
storage/
bootstrap/cache/
queue worker
scheduler
APP_KEY
DB credentials
cache backend
Sau migrate có thể cần:
php artisan config:clear
php artisan cache:clear
Tùy ứng dụng production, hãy dùng đúng deployment procedure của dự án.
32. Docker website: migrate thế nào?
Nếu app chạy Docker Compose:
- copy
compose.yaml; - copy
.env/secrets an toàn; - backup/restore volume;
- pin image version;
docker compose pull;docker compose up -d;- test healthcheck.
Không chỉ copy container writable layer và coi đó là backup.
33. Email trên cùng VPS cần lưu ý gì?
Nếu VPS cũ cũng chạy mail server, migration phức tạp hơn nhiều vì DNS MX, SPF, DKIM, reverse DNS và queue mail.
Không nên gộp migration mail vào website nếu chưa có kế hoạch riêng.
34. Rollback nếu VPS mới có lỗi
Trước cutover, chuẩn bị:
- IP cũ;
- DNS record cũ;
- database backup;
- source backup;
- thời điểm đồng bộ cuối.
Nếu site mới lỗi nghiêm trọng, có thể đổi DNS/origin trở lại máy cũ, nhưng hãy cẩn thận với dữ liệu đã phát sinh trên máy mới sau cutover.
Đây là lý do nên theo dõi chặt ngay sau chuyển.
35. Những nguyên nhân downtime kéo dài
- chưa test site bằng hostname;
- thiếu PHP extension;
- permission sai;
- database credential sai;
- DNS TTL còn cao;
- SSL chưa sẵn;
- cron/queue chạy trùng;
- firewall chặn port;
- quên copy upload;
- app hard-code IP cũ.
36. Checklist trước cutover
- VPS mới đã update.
- Stack tương thích.
- Source đã rsync lần đầu.
- Database test import thành công.
- Hosts file test thành công.
- HTTPS sẵn sàng.
- Firewall đúng.
- Cron/worker chưa chạy trùng.
- TTL đã giảm trước đó.
- Có backup/rollback.
37. Checklist lúc cutover
- Bật maintenance/read-only.
- Dừng queue/cron máy cũ.
- Rsync lần cuối.
- Dump/import database cuối.
- Bật worker/cron máy mới.
- Đổi DNS/origin.
- Test từ ngoài.
- Tắt maintenance.
- Theo dõi log.
38. Checklist sau cutover
- Kiểm tra login/upload/order.
- Kiểm tra mail/webhook.
- Kiểm tra SSL.
- Kiểm tra CPU/RAM/disk.
- Theo dõi 4xx/5xx.
- Kiểm tra DNS nhiều resolver.
- Giữ VPS cũ để rollback trong thời gian hợp lý.
- Tăng TTL lại sau khi ổn định nếu phù hợp.
39. FAQ về chuyển website sang VPS mới
Có thể chuyển website mà không downtime không?
Có thể giảm downtime xuống rất thấp với rsync nhiều lần, replication hoặc proxy/cutover phù hợp. Với website có ghi dữ liệu, một maintenance window ngắn thường đơn giản và an toàn hơn.
Có nên dùng rsync --delete không?
Có thể, nhưng luôn chạy --dry-run trước vì tùy chọn này xóa file dư ở destination.
MySQL có cần stop khi dump không?
Không phải lúc nào. Với InnoDB, mysqldump --single-transaction có thể tạo consistent dump mà không lock table toàn thời gian, nhưng cần hiểu giới hạn.
Có cần đổi domain khi đổi VPS không?
Không. Bạn chỉ cần đổi A/AAAA record sang IP mới nếu domain giữ nguyên.
Tại sao đổi DNS nhưng vẫn thấy VPS cũ?
Do DNS cache/TTL hoặc CDN cache.
Có nên hủy VPS cũ ngay không?
Không. Nên giữ một thời gian để rollback và xác minh dữ liệu.
Chuyển website có ảnh hưởng SEO không?
Nếu domain, URL, nội dung và HTTP status giữ ổn định, migration hạ tầng thường không cần thay đổi SEO URL. Nhưng downtime dài, lỗi 5xx hoặc redirect sai có thể ảnh hưởng crawl/trải nghiệm.
Kết luận
Chuyển website sang VPS mới với downtime tối thiểu là bài toán đồng bộ và cutover, không chỉ copy dữ liệu. Hãy chuẩn bị VPS mới trước, rsync lần đầu khi site vẫn chạy, test bằng hosts file, giảm TTL từ sớm, rồi dùng một maintenance window ngắn để đồng bộ file/database lần cuối trước khi đổi DNS.
Rsync --dry-run, mysqldump --single-transaction, Nginx graceful reload và một kế hoạch rollback rõ ràng sẽ giúp giảm rủi ro đáng kể.
Nếu bạn đang cần VPS mới tại HUONG CLOUD để nâng cấu hình hoặc chuyển website sang hạ tầng mới, hãy chuẩn bị migration theo checklist trước khi đổi DNS để tránh downtime không cần thiết.
Nguồn tham khảo
- Ubuntu manpage – rsync: https://manpages.ubuntu.com/manpages/resolute/man1/rsync.1.html
- MySQL 8.4 Reference – mysqldump: https://dev.mysql.com/doc/refman/8.4/en/mysqldump.html
- Nginx – Controlling nginx / graceful reload: https://nginx.org/en/docs/control.html
- Ubuntu Server documentation: https://documentation.ubuntu.com/server/
Kết luận
Nếu chưa chắc cấu hình hoặc loại dịch vụ nào phù hợp, hãy gửi nhu cầu thực tế để đội ngũ hỗ trợ tư vấn trước khi mua.
Chưa biết nên chọn gói nào?
Xem bảng giá VPS hoặc liên hệ đội ngũ hỗ trợ để chọn cấu hình phù hợp.
Xem bảng giá VPS →