نئے VPS پر سرور کیسے منتقل کریں؟ مکمل طریقہ
لائیو سرور کی محفوظ منتقلی کے لیے inventory بنائیں، clone کے بجائے rebuild کریں، database dump اور 2 بار sync کریں، DNS TTL پہلے کم کریں اور switch سے پہلے تصدیق کریں۔
نئے VPS پر سرور کو rehearsed cutover کے طور پر منتقل کریں
نئے VPS پر سرور منتقل کرنے کے لیے اس منتقلی کو صرف copy کرنے کے بجائے rehearsed cutover سمجھیں۔ نیا سرور شروع سے تیار کریں، data کو 2 مرتبہ sync کریں، DNS کو تبدیل کرنے سے پہلے نئے سرور کو اس کے اپنے IP address پر آزادانہ طور پر کام کرتے ہوئے ثابت کریں، پھر records تبدیل کریں اور پرانے سرور کو اس وقت تک چلتا رہنے دیں جب تک آپ کو مکمل یقین نہ ہو جائے۔ bytes کو copy کرنا آسان حصہ ہے۔ کارروائیوں کی ترتیب طے کرتی ہے کہ منتقلی بغیر کسی رکاوٹ کے ہوگی یا مہنگی ثابت ہوگی۔
یہ guide ایک Linux server کا احاطہ کرتی ہے جس پر web application، database اور TLS (transport layer security) certificate چل رہا ہے۔ زیادہ تر single-server setups اسی میں شامل ہوتے ہیں۔ یہاں 2 hosts استعمال ہو رہے ہیں، اس لیے ہر مثال کے comment میں بتایا گیا ہے کہ وہ کس host پر چلتی ہے۔ addresses documentation ranges سے لیے گئے ہیں: 198.51.100.10 پرانا server ہے اور 203.0.113.20 نیا server ہے۔
شروع کرنے سے پہلے پورا runbook پڑھیں۔ پہلا مرحلہ، DNS TTL کم کرنا، اس مرحلے سے کئی دن پہلے کرنا ہوتا ہے جس کی آپ کو اصل میں ضرورت ہے۔
تعمیر شروع کرنے سے پہلے inventory تیار کریں
آپ ایسے server کو دوبارہ تعمیر نہیں کر سکتے جس کی تفصیل آپ نے درج نہ کی ہو۔ پرانے server کے کام لکھنے کے لیے ایک گھنٹہ صرف کریں، کیونکہ migration کے بعد ہمیشہ وہی چیز خراب ہوتی ہے جسے کوئی یاد نہیں رکھتا: کوئی cron job، firewall exception، یا application directory سے باہر موجود environment file۔
پرانے server پر یہ commands چلائیں اور output ایسی جگہ محفوظ کریں جہاں آپ اسے نئے server سے پڑھ سکیں۔
# old server: packages you asked for, not the dependencies they pulled in
apt-mark showmanual > ~/inv-packages.txt
# old server: what runs now, and what starts at boot
systemctl list-units --type=service --state=running --no-pager > ~/inv-services.txt
systemctl list-unit-files --state=enabled --no-pager >> ~/inv-services.txt
systemctl list-timers --all --no-pager > ~/inv-timers.txt
# old server: what is listening, on which address and port
sudo ss -tulpn > ~/inv-ports.txt
# old server: human accounts, skipping the system ones
awk -F: '$3 >= 1000 && $3 < 65534 {print $1, $3, $6, $7}' /etc/passwdapt-mark showmanual ایسی فہرست ہے جسے رکھنا مفید ہے، کیونکہ اس میں dependency کے طور پر شامل ہونے والی تمام چیزیں آ جاتی ہیں۔ پانچ سال پرانے server پر مکمل dpkg --get-selections چلانے سے دو ہزار lines حاصل ہو سکتی ہیں، لیکن ان سے مقصد کے بارے میں کچھ معلوم نہیں ہوتا۔
Scheduled work دو جگہوں پر موجود ہوتا ہے، اس لیے دونوں کو check کریں۔ جو job صرف ماہانہ چلتی ہے، migration کے چھ ہفتے بعد عموماً وہی دریافت ہوتی ہے۔
# old server: per-user crontabs, then the system drop-ins
for u in $(cut -d: -f1 /etc/passwd); do sudo crontab -lu "$u" 2>/dev/null | sed "s/^/$u: /"; done
sudo ls -la /etc/cron.d /etc/cron.daily /etc/cron.hourlyاس کے بعد ان چیزوں کی inventory بنائیں جو عام files نہیں ہیں: firewall rules، certificates، databases، اور حقیقت میں منتقل کیے جانے والے data کی مقدار۔
# old server
sudo ufw status verbose # or: sudo nft list ruleset
sudo certbot certificates
sudo -u postgres psql -c '\l' # or: sudo mysql -e 'SHOW DATABASES;'
sudo du -xh --max-depth=1 / | sort -hcertbot certificates ہر certificate کا name، اس کے دائرہ کار میں آنے والے domains، expiry date، اور disk پر موجود files کے paths دکھاتا ہے۔ یہ output آپ کی TLS checklist ہے۔ du -x صرف ایک filesystem کے اندر رہتا ہے، اس لیے mounted backup volume میں داخل ہو کر عدد کو دس گنا زیادہ رپورٹ نہیں کرے گا۔
دو چیزیں server سے باہر ہوتی ہیں اور ہر بار بھلا دی جاتی ہیں۔ پہلی، ہر وہ third party جو آپ کے server کے IP address کو allowlist کرتی ہے: payment gateway، managed database، SMTP relay، یا partner API۔ نئے server کا address نیا ہوگا، اس لیے cutover سے پہلے ان allowlists میں نیا IP شامل کریں، بعد میں نہیں۔ دوسری، وہ DNS records جو آپ نے خود نہیں بنائے، مثلاً MX record یا ایسا SPF record جس کے متن میں پرانا IP درج ہو۔
آپ پرانے root filesystem کی کلوننگ کے بجائے دوبارہ تعمیر کیوں کرتے ہیں
پورے root filesystem کو نئے VPS پر کلون کرنا بظاہر تیز طریقہ لگتا ہے، اور یہ واقعی تیز ہوتا ہے، جب تک مسائل سامنے نہ آئیں۔ ایسا root filesystem جو برسوں سے production میں رہا ہو، اس میں ایسی configuration شامل ہوتی ہے جس میں ہاتھ سے تبدیلی کی گئی ہو اور جس کی کسی نے دستاویز بندی نہ کی ہو، ایسے repository کے packages شامل ہوتے ہیں جو اب موجود نہیں، اور boot setup بھی پرانے platform کے virtual hardware کے لیے بنایا گیا ہوتا ہے۔ آپ یہ سب کچھ درآمد کر لیتے ہیں، بشمول وہ وجہ بھی جس کے باعث migration کرنا پڑا۔
دوبارہ تعمیر پہلے دن زیادہ وقت لیتی ہے، لیکن اس کے بعد ہر روز لاگت کم رہتی ہے۔ آپ موجودہ release install کرتے ہیں، اپنی بنیادی hardening لاگو کرتے ہیں، پھر صرف data copy کرتے ہیں: application directory، site configs، database dump، certificates اور user uploads۔ جس چیز کی وضاحت آپ نہیں کر سکتے، وہ منتقل نہیں ہوتی۔ نئے box کو اسی طرح شروع کریں جیسے کسی بھی box کو شروع کرتے ہیں، یعنی نئے VPS پر پہلے دس منٹ کے طریقہ کار کے مطابق۔ پھر inventory سے services ایک ایک کر کے شامل کریں، اور اگلی service شامل کرنے سے پہلے ہر service کی تصدیق کریں۔
جب image یا snapshot restore مناسب انتخاب ہو
دوبارہ build کرنے سے گریز کی ایک جائز صورت موجود ہے۔ اگر پرانا server boot نہ ہو، یا application ایسی ہو جسے اب source سے دوبارہ build نہ کیا جا سکے، تو provider image یا snapshot restore عملی حل ہے۔ اس کی حقیقی حدود ہیں۔ یہ عموماً صرف ایک provider کے اندر کام کرتا ہے، اور اکثر صرف ایک ہی plan family میں، کیونکہ restored disk اسی platform کے virtual devices اور network naming کی توقع رکھتی ہے۔
چلتے ہوئے server کا snapshot بھی live database کی کسی بھی دوسری file-level copy جیسا consistency مسئلہ رکھتا ہے۔ image restore کو migration plan کے بجائے recovery route سمجھیں، اور کوئی plan اس پر مبنی بنانے سے پہلے پڑھیں کہ snapshot backup کے برابر کیوں نہیں ہوتا۔
فائلیں کیسے منتقل ہوتی ہیں: SSH کے ذریعے rsync
پرانے سرور سے rsync چلائیں اور ڈیٹا نئے سرور پر بھیجیں۔ عموماً push کرنا آسان ہوتا ہے، کیونکہ ڈیٹا پہلے ہی پرانے سرور پر موجود ہوتا ہے اور وہاں sudo کے تحت تمام ڈیٹا پڑھا جا سکتا ہے۔
# old server: dry run first, and read what it says it will do
sudo rsync -aHAX --dry-run --itemize-changes \
-e 'ssh -i /root/.ssh/id_ed25519' \
/srv/app/ deploy@203.0.113.20:/srv/app/
# old server: the real bulk pass
sudo rsync -aHAX --info=progress2 \
-e 'ssh -i /root/.ssh/id_ed25519' \
/srv/app/ deploy@203.0.113.20:/srv/app/flags اہم ہیں۔ -a permissions، timestamps، symbolic links اور ownership برقرار رکھتا ہے۔ -H hard links کو الگ الگ copies میں تبدیل کرنے کے بجائے hard links ہی برقرار رکھتا ہے۔ -A POSIX ACLs (access control lists) کو copy کرتا ہے اور -X extended attributes کو copy کرتا ہے۔ ان آخری دونوں کے بغیر بظاہر یکساں فائل مختلف طریقے سے کام کر سکتی ہے، کیونکہ SELinux labels اور ACLs extended attributes میں محفوظ ہوتے ہیں اور انہیں ریکارڈ کرنے کا کوئی اور طریقہ نہیں ہوتا۔
یہاں زیادہ تر failures کی وجہ دو تفصیلات ہوتی ہیں۔
آخر میں موجود slash یہ طے کرتا ہے کہ ڈیٹا کہاں جائے گا۔ /srv/app/ کا مطلب اس directory کے contents ہیں۔ /srv/app کا مطلب خود directory ہے۔ غلطی کی صورت میں نئے سرور پر /srv/app/app بن جاتا ہے، پھر application start ہو کر missing files کی اطلاع دیتی ہے، کیونکہ اس میں configured paths اب ایک level کم گہرے ہو گئے ہیں۔
sudo کے اندر tilde، root کی home directory ہوتی ہے۔ کسی sudo rsync میں -e 'ssh -i ~/.ssh/id_ed25519' لکھنے سے key /root/.ssh میں تلاش کی جاتی ہے، آپ کی اپنی home directory میں نہیں۔ اگر key وہاں موجود نہ ہو تو SSH Permission denied (publickey) دکھاتا ہے، rsync rsync: connection unexpectedly closed دکھا کر non-zero status کے ساتھ بند ہو جاتا ہے۔ key کا path مکمل طور پر لکھیں۔ اگر path درست کرنے کے بعد بھی authentication کا یہ پیغام آتا رہے تو publickey failure کی وجوہات محدود ہیں، اور نئے سرور پر directory permissions اگلی چیز ہیں جنہیں چیک کرنا چاہیے۔
Ownership کے لیے ایک فیصلہ کرنا ضروری ہے۔ root کے طور پر چلانے پر rsync بطور default owner اور group کو name کے ذریعے map کرتا ہے، اس لیے پرانے server پر www-data کی ملکیت والی فائل نئے server پر www-data کی ملکیت بن جاتی ہے، اگرچہ numeric UID (user ID) مختلف ہو۔ rebuild کے لیے یہی مطلوب ہوتا ہے۔ --numeric-ids صرف اس وقت شامل کریں جب آپ ایسے filesystem کو copy کر رہے ہوں جس کے accounts target پر موجود نہ ہوں۔ اس کے بعد ls -ln سے نتیجہ چیک کریں، کیونکہ ایسے UID کی ملکیت والی فائل جس کا matching account نہ ہو، صرف ایک number کے طور پر دکھائی دیتی ہے اور اسے پڑھنے والی ہر service کو access denied ملتا ہے۔
bulk pass کئی دن پہلے چلائیں، جب پرانا server ابھی network traffic فراہم کر رہا ہو۔ اسے جتنی بار چاہیں دہرائیں: rsync صرف تبدیل شدہ چیزیں بھیجتا ہے، اس لیے دوسرا pass کئی گھنٹوں کے بجائے چند منٹ لیتا ہے۔ cutover window کے اندر آخری pass میں --delete شامل کریں، تاکہ پرانے server سے حذف کی گئی فائلیں نئے server سے بھی حذف ہو جائیں۔
# old server: final pass, inside the window, after the app has stopped writing
sudo rsync -aHAX --delete --info=progress2 \
-e 'ssh -i /root/.ssh/id_ed25519' \
/srv/app/ deploy@203.0.113.20:/srv/app/--delete destination سے وہ فائلیں حذف کرتا ہے جو source میں موجود نہیں رہیں، اس لیے غلط source path کے ساتھ --delete destination directory کو خالی کر دیتا ہے۔ ہر بار پہلے --dry-run کے ساتھ چلائیں۔ جب laptop کا SSH session منقطع ہو جائے تو طویل transfers بھی رک جاتے ہیں، اس لیے انہیں پرانے server پر tmux یا screen کے اندر شروع کریں۔ اگر پرانا server ابھی users کو service دے رہا ہو اور copy link کو مکمل طور پر مصروف کر دے تو --bwlimit=20M شامل کریں۔
ڈیٹا بیس کیسے منتقل ہوتا ہے: native dump
ڈیٹا بیس فائلوں کی ڈائریکٹری نہیں ہوتا، اگرچہ یہ بظاہر ایسا دکھائی دے سکتا ہے۔ یہ فائلوں، memory میں موجود state اور write-ahead log کا مجموعہ ہوتا ہے۔ یہ صرف ان لمحات میں consistent ہوتا ہے جنہیں خود ڈیٹا بیس متعین کرتا ہے۔ اس کے لیے اسی کا tool استعمال کریں۔
PostgreSQL کے لیے دو dumps درکار ہوتے ہیں، کیونکہ roles پورے cluster پر لاگو ہوتے ہیں اور pg_dump ان میں شامل نہیں کرتا:
# old server
sudo -u postgres pg_dumpall --globals-only -f /var/backups/globals.sql
sudo -u postgres pg_dump -Fc -f /var/backups/appdb.dump appdb# new server: restore in this order
sudo -u postgres psql -f /var/backups/globals.sql
sudo -u postgres createdb -O appuser appdb
sudo -u postgres pg_restore -d appdb --no-owner /var/backups/appdb.dumpglobals.sql کو چھوڑنے سے تمام tables restore ہو جاتے ہیں، لیکن کوئی application role انہیں پڑھ نہیں سکتا، کیونکہ GRANT statements ایسے user کا حوالہ دیتے ہیں جو موجود نہیں ہوتا۔ -Fc custom archive format میں لکھتا ہے۔ اسے صرف pg_restore پڑھتا ہے، اور اس format سے آپ بعد میں منتخب tables restore کر سکتے ہیں۔ اسی major version یا اس سے نئے version میں restore کریں۔ پچھلے version میں واپس جانا، مثلاً 17 سے 16 پر، supported نہیں ہے۔ pg_restore file header میں unsupported-version error کے ساتھ archive کو reject کر دیتا ہے، اور کچھ بھی write نہیں کرتا۔
MySQL اور MariaDB ایک command استعمال کرتے ہیں، جس میں چار options شامل کرنے پڑتے ہیں کیونکہ یہ default طور پر فعال نہیں ہوتے:
# old server
sudo mysqldump --single-transaction --routines --triggers --events \
--databases appdb > /var/backups/appdb.sql# new server
sudo mysql < /var/backups/appdb.sql--single-transaction writers کو block کیے بغیر consistent snapshot لیتا ہے، لیکن صرف InnoDB tables کے لیے۔ اسی database میں موجود MyISAM table کو اس guarantee کے بغیر copy کیا جاتا ہے، اس لیے dump پر اعتماد کرنے سے پہلے اپنے storage engines چیک کریں۔ --routines، --triggers اور --events default طور پر بند ہوتے ہیں۔ اس کا مطلب ہے کہ plain dump آپ کا data restore کر دیتا ہے، لیکن stored procedures اور scheduled events کو خاموشی سے چھوڑ دیتا ہے۔ Database users اور ان کے grants mysql system database میں موجود ہوتے ہیں۔ --databases appdb dump اس database کو کبھی شامل نہیں کرتا، اس لیے نئے server پر انہیں CREATE USER اور GRANT کے ذریعے دوبارہ بنائیں۔ MariaDB 11 میں یہی tool mariadb-dump کے نام سے شامل ہے اور mysqldump کو symbolic link کے طور پر برقرار رکھا گیا ہے، اس لیے August 2026 تک دونوں نام کام کرتے ہیں۔
SQLite ایک single file ہوتا ہے۔ اگر application کے write کرتے وقت اسے copy کیا جائے تو file کا کچھ حصہ پرانا اور کچھ حصہ نیا ہو سکتا ہے۔ اس کے لیے محفوظ طریقہ موجود ہے:
# old server
sqlite3 /var/lib/app/app.db ".backup '/var/backups/app.db'"Engine کوئی بھی ہو، dump پر اعتماد کرنے سے پہلے اسے چیک کریں۔ اگر disk بھرنے کی وجہ سے dump وقت سے پہلے رک گیا ہو تو restore بغیر کسی شکایت کے اس مقام تک مکمل ہو جائے گا جہاں dump truncate ہوا تھا۔
# old server: a complete mysqldump ends with a line reading "-- Dump completed on ..."
tail -n 3 /var/backups/appdb.sql
# new server: after restore, count rows in a table whose size you know
sudo mysql -e 'SELECT COUNT(*) FROM appdb.orders;'آپ running database کو rsync کیوں نہیں کر سکتے
rsync فائل بہ فائل copy کرتا ہے۔ running database بیک وقت کئی فائلوں میں لکھتا ہے، اس لیے جب تک rsync آخری فائل تک پہنچتا ہے، پہلی فائل پہلے ہی پرانی ہو چکی ہوتی ہے۔ copy میں مختلف اوقات کے صفحات شامل ہوتے ہیں، اور database کی حالت کبھی ایسی نہیں رہی ہوتی۔ نتیجہ یا تو ایسا server ہوتا ہے جو start ہونے سے انکار کر دیتا ہے، یا بدترین صورت میں ایسا server جو start ہو جاتا ہے، ایک ہفتے تک درست جوابات دیتا ہے، اور پھر اس وقت fail ہوتا ہے جب کوئی query آخرکار خراب page تک پہنچتی ہے۔ اس دوران کوئی warning نہیں آتی۔
خود فائلوں کو منتقل کرنے کے دو محفوظ طریقے ہیں۔ database کو stop کریں، copy کریں، پھر دوبارہ start کریں: یہ درست اور سادہ طریقہ ہے، لیکن downtime کی مدت copy مکمل ہونے میں لگنے والے وقت کے برابر ہوگی۔ یا running server کی physical copy کے لیے بنائے گئے tool کو استعمال کریں۔ PostgreSQL کے لیے یہ pg_basebackup ہے، جو server کے ساتھ coordination کرتا ہے تاکہ copy consistent رہے:
# new server: pull a physical copy from the old one
pg_basebackup -h 198.51.100.10 -U replicator -D /var/lib/postgresql/16/main -X stream -Pاس کے لیے REPLICATION attribute والا role اور پرانے server پر matching pg_hba.conf entry درکار ہوتی ہے، اس لیے یہ dump کے مقابلے میں زیادہ setup مانگتا ہے۔ جب database اتنا بڑا ہو کہ dump اور restore آپ کی maintenance window میں مکمل نہ ہو سکیں، تو یہ طریقہ مفید ہے۔ عام single-server migration کے لیے dump بہتر انتخاب ہے۔
کٹ اوور کے بعد نہیں، اس سے پہلے certificates دوبارہ بنائیں
TLS certificate، IP address کے بجائے domain name سے منسلک ہوتا ہے، اس لیے certificate file خود منتقل کرنے میں کوئی مسئلہ نہیں ہوتا۔ جو چیز درست طور پر منتقل نہیں ہوتی وہ renewal ہے۔ Certbot کا default HTTP-01 challenge certificate authority سے کہتا ہے کہ certified name پر port 80 کے ذریعے ایک file حاصل کرے۔ جب تک DNS نئے server کی طرف point نہیں کرتا، یہ درخواست پرانے server تک پہنچتی ہے اور نئے server کا renewal fail ہو جاتا ہے۔
پہلا طریقہ یہ ہے کہ موجودہ certificates اور ان کی renewal state copy کر دی جائے۔ یہ اپنی expiry date تک valid رہتے ہیں، چاہے وہ کسی بھی server پر موجود ہوں۔
# old server
sudo rsync -aHAX -e 'ssh -i /root/.ssh/id_ed25519' \
/etc/letsencrypt/ root@203.0.113.20:/etc/letsencrypt//etc/letsencrypt/renewal/ کے تحت موجود ہر file اس authenticator plugin کا نام بتاتی ہے جس نے certificate جاری کیا تھا۔ اس لیے نئے server پر وہی plugin install کریں، مثلاً python3-certbot-nginx، ورنہ پہلا renewal unknown authenticator کے بارے میں message کے ساتھ fail ہو جائے گا۔ اس پر انحصار کرنے سے پہلے ثابت کریں کہ renewal کام کرتا ہے:
# new server, after DNS has moved
sudo certbot renew --dry-runدوسرا طریقہ یہ ہے کہ نئے server پر DNS-01 challenge استعمال کرتے ہوئے نیا certificate جاری کیا جائے۔ یہ challenge TXT record کے ذریعے control ثابت کرتا ہے اور port 80 کو استعمال نہیں کرتا۔ یہ migration سے پہلے کام کرتا ہے، جب name اب بھی پرانے server پر resolve ہو رہا ہو۔ اگر آپ اپنے DNS provider کو automate کر سکتے ہیں تو یہ زیادہ صاف انتخاب ہے۔ DNS-01 challenge کے ساتھ certificates جاری کرنا میں plugin اور credentials کی setup بیان کی گئی ہے۔
دونوں صورتوں میں DNS تبدیل کیے بغیر دیکھیں کہ نیا server حقیقت میں کیا پیش کرتا ہے:
# your laptop
echo | openssl s_client -connect 203.0.113.20:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -subject -dates -issuer-servername SNI (server name indication) بھیجتا ہے۔ اسی سے web server درست virtual host منتخب کرتا ہے۔ اسے چھوڑ دیں تو اس IP کے لیے default certificate ملتا ہے اور mismatch ظاہر ہوتا ہے۔ یہ حقیقی مسئلے جیسا لگتا ہے، لیکن مسئلہ نہیں ہوتا۔
کٹ اوور سے چند دن پہلے DNS TTL کم کریں
DNS وہ مرحلہ ہے جہاں محتاط migration بھی ناکام ہو سکتی ہے، کیونکہ تاخیر پہلے سے شامل ہوتی ہے اور آپ اسے اسی دن کم نہیں کر سکتے۔ جس resolver نے آپ کا A record cache کیا ہو، وہ اسے اتنی مدت تک فراہم کرتا رہتا ہے جتنی مدت کا TTL (time to live) اسے دیا گیا تھا۔ ابھی TTL کم کرنے سے اس resolver پر کوئی اثر نہیں پڑتا جس نے 10 منٹ پہلے record کو پرانی قدر کے ساتھ cache کیا تھا۔ وہ پرانی قدر کو پرانے TTL کی باقی مدت تک برقرار رکھتا ہے، اور اس کے بعد ہی نئی، مختصر قدر حاصل کرتا ہے۔ اس لیے کٹ اوور سے کم از کم ایک پورے پرانے TTL period پہلے TTL کم کریں۔ ایک دن پہلے کرنا زیادہ اطمینان بخش طریقہ ہے۔ اگر یہاں شامل اجزا آپ کے لیے نئے ہیں تو records، resolvers اور caching کی وضاحت بنیادی معلومات فراہم کرتی ہے۔
ذیل کے اعداد TTL سے حاصل کردہ حساب ہیں، کسی پیمائش کا نتیجہ نہیں۔
The data behind this chart
[
{
"label": "TTL 3600 s (common default)",
"ttl_seconds": 3600,
"worst_case_stale_minutes": 60
},
{
"label": "TTL 900 s",
"ttl_seconds": 900,
"worst_case_stale_minutes": 15
},
{
"label": "TTL 300 s (lowered for cutover)",
"ttl_seconds": 300,
"worst_case_stale_minutes": 5
},
{
"label": "TTL 60 s (short window)",
"ttl_seconds": 60,
"worst_case_stale_minutes": 1
}
]3600 seconds کے TTL کے ساتھ شائع کیا گیا A record، اسے تبدیل کرنے کے بعد بھی 60 منٹ تک صارفین کو پرانے IP پر بھیج سکتا ہے۔ اسے 300 seconds تک کم کرنے سے یہ زیادہ سے زیادہ مدت 5 منٹ رہ جاتی ہے۔ ان اعداد کو کم از کم حد سمجھیں، ضمانت نہیں۔ کچھ resolvers اپنی minimum TTL نافذ کرتے ہیں اور اس سے کم قدر کو نظرانداز کر دیتے ہیں۔ کچھ application runtimes resolved address کو process کے اختتام تک cache کرتے ہیں۔ اس لیے آپ کی تبدیلی سے پہلے شروع ہونے والا client، restart ہونے تک دوبارہ lookup نہ کرے۔
کم TTL فعال ہونے کی تصدیق کرتے وقت اپنے cache کے بجائے authoritative answer پڑھیں:
# your laptop: ask the zone's own nameserver, so no cache is involved
dig +short NS example.com
dig +noall +answer @$(dig +short NS example.com | head -n1) example.com Aاس answer line کا دوسرا field seconds میں TTL ہوتا ہے۔ پھر ان records کو بھی دیکھیں جنہیں لوگ اکثر بھول جاتے ہیں: اگر پرانے server کے پاس IPv6 تھا تو AAAA record، جب www name الگ A record ہو نہ کہ CNAME، server کی طرف اشارہ کرنے والا کوئی MX record، پرانے IP کو درج کرنے والا SPF record، اور نئے address پر reverse DNS (PTR) record۔ اگر server mail بھیجتا ہے تو کٹ اوور سے پہلے اپنے provider کے control panel کے ذریعے PTR set کریں، کیونکہ receiving mail servers اسے check کرتے ہیں۔ Missing PTR کی وجہ سے باقی سب کچھ درست نظر آنے کے کئی گھنٹے بعد mail reject ہو سکتی ہے۔
نئے server کو DNS تبدیل کرنے سے پہلے اس کے IP پر verify کریں
DNS ابھی بھی پرانے server کی طرف اشارہ کر رہا ہو تو آپ نئی server پر پوری application test کر سکتے ہیں۔ ایک request کے لیے name lookup کو override کریں:
# your laptop: force one name to the new IP, for this request only
curl -sS --resolve example.com:443:203.0.113.20 \
-o /dev/null -w '%{http_code} %{ssl_verify_result}\n' https://example.com/--resolve صرف یہ تبدیل کرتا ہے کہ connection کہاں جائے۔ TLS certificate کی جانچ پھر بھی اصل name کے خلاف ہوتی ہے، اس لیے اس سے certificate اور service دونوں verify ہوتے ہیں۔ chain verify ہونے پر %{ssl_verify_result}، 0 دکھاتا ہے۔
Browser میں site کو click کر کے جانچنے کے لیے اپنے laptop پر /etc/hosts میں، یا Windows پر C:\Windows\System32\drivers\etc\hosts میں، ایک line شامل کر کے پوری machine کے لیے name override کریں:
203.0.113.20 example.com www.example.comپھر application کو اسی طرح استعمال کریں جیسے کوئی user کرے گا۔ Login کریں۔ ایسی page کھولیں جو database سے data پڑھتی ہو۔ ایسا form submit کریں جو database میں data لکھتا ہو۔ کوئی file upload کریں اور تصدیق کریں کہ وہ disk پر محفوظ ہوئی ہے۔ Email بھیجنے والی تمام functionality کو trigger کریں اور تصدیق کریں کہ email موصول ہو گئی ہے، کیونکہ نئی IP سے outbound SMTP ایک عام غیر متوقع مسئلہ ہے۔ کام مکمل ہوتے ہی hosts line حذف کر دیں۔ اسے موجود چھوڑنے سے آپ ایسی site کو debug کرنے میں ایک گھنٹہ صرف کر سکتے ہیں جسے باقی تمام لوگ بالکل درست دیکھ رہے ہوں۔
منتقلی، مرحلہ وار
- کئی دن پہلے: TTL کم کریں، bulk rsync چلائیں، نیا سرور تیار کریں، اور hosts override کے ذریعے اس کی جانچ کریں۔
- منتقلی کے دن، window شروع ہونے سے پہلے: ہر third-party allowlist میں نیا IP شامل کریں، اور تصدیق کریں کہ نئے سرور کا backup job configured ہے اور آپ کے repository کی طرف اشارہ کر رہا ہے۔
- window کھولیں: پرانے سرور پر application کو maintenance mode میں ڈالیں تاکہ وہ writes قبول کرنا بند کر دے۔
- آخری database dump لیں، پھر
--deleteکے ساتھ آخری rsync pass چلائیں۔ - نئے سرور پر dump restore کریں اور services شروع کریں۔
--resolveاور hosts override کے ذریعے دوبارہ جانچ کریں، جس میں ایک حقیقی write بھی شامل ہو۔- A اور AAAA records کو نئے IP پر تبدیل کریں۔
- دونوں سرورز کو monitor کریں۔ پرانے سرور کا access log دکھائے گا کہ اب بھی کون وہاں پہنچ رہا ہے، اور TTL کے دوران یہ تعداد کم ہو کر صفر کے قریب آنی چاہیے۔
- maintenance page ہٹا دیں۔
- پرانے سرور کو کم از کم ایک ہفتے تک چلتا ہوا اور بغیر تبدیلی کے رہنے دیں۔
maintenance mode کا مرحلہ وہ ہے جسے لوگ اکثر چھوڑ دیتے ہیں، حالانکہ یہی مرحلہ آپ کو تحفظ فراہم کرتا ہے۔ نئے database کے ایک write قبول کرنے کے بعد rollback کرنے کا مطلب یا تو وہ write ضائع کرنا ہے، یا نئے database کا dump لے کر اسے پرانے database میں دوبارہ load کرنا ہے۔ چند منٹ کی read-only window کم قیمت حل ہے۔ دو databases میں writes قبول ہو جانے کے بعد دستی reconciliation میں کئی دن لگ سکتے ہیں۔
واپسی کا منصوبہ
Rollback ایک ہی کارروائی ہے: DNS records کو دوبارہ 198.51.100.10 پر تبدیل کریں۔ یہ صرف اس لیے ممکن ہے کہ آپ نے پہلے چار کام کیے تھے۔
- پرانا سرور اب بھی چل رہا ہے، اس کی services فعال ہیں اور data درست حالت میں موجود ہے۔ آپ نے وہاں writes روک دی تھیں، اسے decommission نہیں کیا تھا۔
- TTL اب بھی کم ہے، اس لیے واپسی بھی اتنی ہی تیز ہوگی جتنی آگے بڑھنے کی کارروائی تھی۔
- آپ نے third-party allowlists میں پرانے IP کو replace کرنے کے بجائے نیا IP شامل کیا تھا۔ پرانا address ہٹانے سے payment gateway پر rollback path ناکام ہو جائے گا۔
- نئے سرور نے ایسی کوئی writes قبول نہیں کیں جن کی آپ شناخت نہ کر سکیں، کیونکہ اب تک صرف آپ کی اپنی test transactions نے writes کی ہیں۔
Window شروع ہونے سے پہلے طے کریں کہ rollback کس صورت میں کرنا ہے۔ دو triggers کافی ہیں: ایسی کوئی بھی error جس کی تشخیص مقررہ تعداد of minutes کے اندر نہ ہو سکے، اور data loss کی کوئی بھی مقدار۔ انہیں پہلے سے لکھ لینا ہی اس guessing کے ایک گھنٹے کو روکتا ہے جو دس منٹ کی outage کو طویل outage میں بدل دیتا ہے۔
مائیگریشن کامیاب ہونے کی تصدیق کریں
مائیگریشن اس وقت مکمل نہیں ہوتی جب سائٹ لوڈ ہو جائے۔ ان چیزوں کی جانچ کریں جو بعد میں ناکام ہوتی ہیں۔
# new server
systemctl --failed
journalctl -p err -b --no-pager | tail -n 40
sudo certbot certificates
sudo systemctl list-timers --all --no-pagersystemctl --failed رپورٹنگ 0 loaded units listed مطلوبہ نتیجہ ہے۔ certbot certificates میں متوقع expiry dates دکھائی دینی چاہییں، اور list-timers میں inventory کے مطابق ہر scheduled job کا حقیقی next-run وقت دکھائی دینا چاہیے، خالی نہیں۔
اس کے بعد نئے سرور کو جان بوجھ کر ایک بار reboot کریں اور اس دوران اسے monitor کریں۔ جو service کسی نے دستی طور پر start کی ہو لیکن کبھی enable نہ کی ہو، وہ صبح 3 بجے ہونے والے پہلے غیر منصوبہ بند reboot تک بالکل درست کام کرتی رہتی ہے۔
# new server
sudo reboot
# your laptop, once it comes back
curl -sS -o /dev/null -w '%{http_code}\n' https://example.com/اگر application containers میں چلتی ہے تو یہی مسئلہ مختلف صورت میں سامنے آتا ہے، کیونکہ reboot کے بعد واپس آنے کے لیے compose stack میں واضح restart policy درکار ہوتی ہے۔
آخری جانچ کو مؤخر کرنا سب سے آسان اور اسے انجام دینا سب سے اہم ہے: backup job۔ ایسی migration جس کا اختتام بغیر backup والے سرور پر ہو، ایک خطرے کو دوسرے خطرے سے بدل دیتی ہے۔ نئے server پر backup دستی طور پر چلائیں، پھر اس میں سے ایک file کو temporary directory میں restore کریں۔ ایسا restic repository جس کا restore آپ نے حقیقت میں test کیا ہو ضرورت کے وقت اسی کا مؤثر ورژن ہے۔ اگر آپ ایک ہفتے تک پرانے اور نئے servers کو ساتھ چلا رہے ہیں تو ہر host تک رسائی اور اسے configure کرنے کا مستقل طریقہ دونوں کے live ہونے کے دوران ان کی configuration کو ایک دوسرے سے مختلف ہونے سے روکتا ہے۔
کٹ اوور کے بعد: پرانا سرور اور آخری کام
پرانا سرور ایک سے دو ہفتے تک برقرار رکھیں۔ اس پر اس plan کی ایک ماہ کی لاگت آئے گی جسے آپ ویسے بھی منسوخ کرنے والے تھے، اور یہی آپ کے پاس واحد rollback ہے۔ اس کے بعد باقی کام مکمل کریں۔
- نئے سرور کے لیے اپنے
~/.ssh/configمیں وہی hostname دوبارہ استعمال کرنے سے پہلی connection پرWARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!دکھائی دے گا، کیونکہ اب وہ نام مختلف host key کے ساتھ جواب دیتا ہے۔ جب آپ کو تبدیلی کی وجہ معلوم ہو جائے توssh-keygen -R example.comسے پرانی entry صاف کریں۔ یہ کام محض عادتاً نہ کریں، کیونکہ یہی warning interception attack کی علامت بھی ہو سکتی ہے۔ migration اس بات کا جائزہ لینے کا بھی اچھا موقع ہے کہ کون سی keys کن وسائل تک رسائی حاصل کر سکتی ہیں؛ اسی مقصد کے لیے چھوٹے fleet میں SSH key management موجود ہے۔ - پرانے سرور کا ایک آخری snapshot یا backup لیں اور اسے ایسی جگہ محفوظ کریں جو پرانے provider سے مختلف ہو۔
- پرانے IP کو monitoring checks، SPF records اور third-party allowlists سے اسی ترتیب میں، اور سب سے آخر میں، ہٹا دیں۔
- پرانے plan کو صرف اس وقت cancel کریں جب اس آخری copy کے کسی دوسری جگہ readable ہونے کی تصدیق ہو جائے۔
FAQ
نئے VPS پر سرور منتقل کرنے میں کتنا وقت لگتا ہے؟
صارف کو نظر آنے والی بندش عموماً آخری database dump، آخری rsync pass اور service start تک محدود ہوتی ہے، اس لیے چھوٹی application کے لیے 10 سے 30 منٹ کافی ہوتے ہیں۔ مکمل منتقلی میں زیادہ وقت لگتا ہے، کیونکہ switch سے کم از کم ایک پرانے TTL کی مدت پہلے DNS TTL کم کرنا ضروری ہے، اور ایک دن پہلے ایسا کرنا زیادہ محفوظ ہے۔ بڑی مقدار میں data copy کرنے کا منصوبہ بھی کئی دن پہلے بنائیں۔ یہ عمل live server کے خلاف چلتا ہے، اور بعد میں اسے دوبارہ چلانے پر صرف آخری pass کے بعد تبدیل ہونے والا data منتقل ہوتا ہے۔
کیا dump بنانے کے بجائے چلتے ہوئے MySQL یا PostgreSQL database کو rsync کر سکتا ہوں؟
نہیں۔ rsync فائل بہ فائل copy کرتا ہے، جبکہ database بیک وقت متعدد فائلوں میں لکھتا ہے۔ اس لیے copy میں مختلف لمحات کے pages شامل ہوتے ہیں اور ایسی state بنتی ہے جو database میں کبھی موجود نہیں تھی۔ database شاید start ہونے سے انکار کر دے، یا start ہو کر بعد میں اس وقت fail ہو جب کوئی query خراب page تک پہنچے۔ pg_dump کو pg_dumpall --globals-only کے ساتھ، یا mysqldump --single-transaction استعمال کریں، یا پہلے database روکیں اور پھر فائلیں copy کریں۔ بڑے PostgreSQL cluster کے لیے pg_basebackup چلتے ہوئے server کی consistent physical copy بناتا ہے۔
DNS تبدیل کرنے سے پہلے نئے VPS کی جانچ کیسے کروں؟
اپنی machine پر name lookup کو override کریں۔ ایک request کے لیے curl --resolve example.com:443:203.0.113.20 https://example.com/ connection کو نئے IP پر بھیجتا ہے، جبکہ certificate کی جانچ اصل name کے خلاف جاری رہتی ہے۔ Browser testing کے لیے اپنے laptop کی /etc/hosts میں 203.0.113.20 example.com شامل کریں، login، database read، form write اور file upload آزما لیں، پھر یہ line ہٹا دیں۔ صرف certificate کا معائنہ کرنے کے لیے openssl s_client -connect 203.0.113.20:443 -servername example.com چلائیں۔
مجھے کون سا TTL مقرر کرنا چاہیے، اور اسے کب کم کرنا چاہیے؟
A اور AAAA records کو 300 seconds پر کم کریں، اور cutover سے کم از کم ایک مکمل پرانے TTL کی مدت پہلے ایسا کریں۔ جو resolver آپ کی تبدیلی سے پہلے record کو cache کر چکا ہو، وہ پرانے TTL کی باقی مدت تک پرانی value رکھتا ہے۔ اس لیے اگر پرانا TTL 86400 تھا تو ایک گھنٹہ پہلے اسے کم کرنے سے کوئی فائدہ نہیں ہوگا۔ Migration کے چند دن بعد، جب پرانے server کا access log خاموش ہو جائے، TTL کو اپنی معمول کی value پر واپس بڑھا دیں۔
کیا مجھے TLS certificate copy کرنا چاہیے یا نئے server پر نیا certificate جاری کرنا چاہیے؟
دونوں طریقے درست ہیں۔ /etc/letsencrypt/ copy کرنے سے certificate اپنی موجودہ expiry تک valid رہتا ہے، لیکن نئے server پر وہی certbot authenticator plugin install کرنا ہوگا، ورنہ پہلی renewal fail ہو جائے گی۔ اس لیے DNS switch کے بعد تصدیق کے لیے certbot renew --dry-run چلائیں۔ جب DNS-01 challenge استعمال کرنا ممکن ہو تو نیا certificate جاری کرنا زیادہ صاف طریقہ ہے، کیونکہ یہ TXT record کے ذریعے control ثابت کرتا ہے اور DNS کو نئے server کی طرف point کرنے سے پہلے بھی کام کرتا ہے۔ نئے server پر HTTP-01 challenge اس وقت تک استعمال نہیں کیا جا سکتا جب تک DNS منتقل نہ ہو جائے، کیونکہ validation request پرانے server تک پہنچے گی۔