विषय-सूची
परिचय
एक VPS से दूसरे VPS पर माइग्रेट करना, जहाँ Virtualmin 10+ WordPress डोमेन चल रहे हों, सिद्धांत में आसान लगता है—पुराने सर्वर पर बैकअप लें, नए पर रीस्टोर करें, हो गया। असल में यह छिपी हुई सिस्टम सीमाओं, फ़ाइल डिस्क्रिप्टर की कमी और डिस्क स्पेस की समस्याओं का माइनफ़ील्ड है, जहाँ आप घंटों तक फँसे रह सकते हैं।
मैंने हाल ही में एक चुनौतीपूर्ण Virtualmin माइग्रेशन पूरा किया, फ़्रांस के एक Debian 12 वाले VPS से नीदरलैंड्स के नए Debian 13 VPS तक, 10+ डोमेन का 4.4GB से ज़्यादा बैकअप डेटा ले जाते हुए। इस दौरान Virtualmin एडमिनिस्ट्रेटर के सामने आने वाली हर बड़ी त्रुटि मुझे मिली—और मैंने सब हल कीं। यह लेख ठीक वही समस्याएँ और समाधान दर्ज करता है, ताकि आपको उन्हें मुश्किल तरीके से न सीखना पड़े।
चाहे आप अपना VPS प्रोवाइडर बदल रहे हों, हॉरिज़ॉन्टल स्केलिंग कर रहे हों, या किसी फेल हुए सर्वर से रिकवर कर रहे हों, यह गाइड आपको असली दुनिया की त्रुटियों और उनके समाधानों से ले जाएगी।

भाग 1: माइग्रेशन से पहले की योजना और तैयारी
अपने लक्ष्य VPS के स्पेसिफिकेशन चुनना
अपने मौजूदा सर्वर पर कुछ भी बदलने से पहले सुनिश्चित करें कि नए VPS में पर्याप्त संसाधन हैं। आम ग़लती यह मान लेना है कि सिर्फ़ डिस्क स्पेस मायने रखता है—ऐसा नहीं है।
10+ डोमेन वाले Virtualmin के लिए न्यूनतम स्पेसिफिकेशन:
- डिस्क स्पेस: 100GB (50GB नहीं—बैकअप के साथ WordPress साइटें तेज़ी से बढ़ती हैं)
- CPU: 6+ कोर (10+ डोमेन के लिए 8+ कोर की सलाह दी जाती है)
- RAM: कम से कम 8GB (प्रोडक्शन के लिए 15GB+)
- Swap: 4GB (अगर पहले से कॉन्फ़िगर नहीं है तो OS इंस्टॉलेशन के बाद जोड़ें)
आपके नए सर्वर का CPU और RAM पुराने सर्वर के बराबर या उससे ज़्यादा होना चाहिए, और डिस्क स्पेस भी ज़्यादा। रीस्टोर के दौरान Virtualmin CPU और I/O दोनों पर भारी पड़ता है—कमज़ोर प्रोसेसर रीस्टोर को बहुत धीमा कर देगा।
माइग्रेशन से पहले की चेकलिस्ट
अपने पुराने सर्वर पर (माइग्रेशन से 48 घंटे पहले):
- DNS TTL घटाकर 300 सेकंड करें (5 मिनट) ताकि कैश से जुड़ी समस्याएँ कम हों:
virtualmin modify-dns --all-domains --ttl 300
- एक नया बैकअप बनाएँ Virtualmin’s अनुशंसित फ़ॉर्मेट के साथ:
mkdir /backup
virtualmin backup-domain \
--dest /backup/ \
--all-domains \
--all-features \
--newformat
- बैकअप की अखंडता जाँचें ट्रांसफ़र करने से पहले:
tar -tzf /backup/backup_*.tar.gz > /dev/null && echo "Backup OK" || echo "Backup corrupted"
- अपने डेटाबेस के आकार नोट करें योजना बनाने के लिए:
mysql -e "SELECT table_schema AS 'Database', ROUND(SUM(data_length+index_length)/1024/1024,2) AS 'Size_MB' FROM information_schema.TABLES GROUP BY table_schema;"
- कस्टम कॉन्फ़िगरेशन जाँचें जो ट्रांसफ़र नहीं होंगे:
- कस्टम PHP वर्ज़न
- संशोधित NGINX कॉन्फ़िग
- /etc/cron.d/ में Cron जॉब
- कस्टम SSL सर्टिफ़िकेट
भाग 2: माइग्रेशन की प्रक्रिया
चरण 1: बैकअप फ़ाइल ट्रांसफ़र करें
उपयोग चेकसम के साथ SCP फ़ाइल की अखंडता जाँचने के लिए:
# On old server, generate checksum
sha256sum /backup/backup_*.tar.gz > /backup/backup.sha256
# Transfer backup and checksum
scp /backup/backup_*.tar.gz [email protected]:/Files/
scp /backup/backup.sha256 [email protected]:/Files/
# On new server, verify
cd /Files/
sha256sum -c backup.sha256
अगर चेकसम मेल न खाएँ, तुरंत रुक जाएँ. ट्रांसफ़र के दौरान फ़ाइल खराब हो गई है। फिर से ट्रांसफ़र करें या चेकसम के साथ rsync इस्तेमाल करें:
rsync -avz --checksum /backup/backup_*.tar.gz [email protected]:/Files/
चरण 2: नए सर्वर पर Virtualmin इंस्टॉल करें
Virtualmin’s आधिकारिक इंस्टॉलर इस्तेमाल करें:
curl https://software.virtualmin.com/gpl/scripts/virtualmin-install.sh | sh
ज़रूरी: वही OS वर्ज़न इंस्टॉल करें (या उसके करीब)—यह लोगों के अनुमान से ज़्यादा मायने रखता है। मैंने Debian 12 से Debian 13 पर माइग्रेट किया (सुझाया नहीं जाता, लेकिन काम चल जाता है)। हो सके तो वही मेजर वर्ज़न रखें।
चरण 3: रीस्टोर से पहले सिस्टम कॉन्फ़िगरेशन
यहीं पर ज़्यादातर माइग्रेशन फ़ेल होते हैं। रीस्टोर शुरू करने से पहले इन तीन अहम सीमाओं को ठीक करें:
फ़िक्स 1: ओपन फ़ाइल डिस्क्रिप्टर बढ़ाएँ
यह रीस्टोर के दौरान #1 कारण है “No space left on device” एरर का, तब भी जब डिस्क स्पेस भरपूर हो।
# Check current limit
ulimit -n
# Likely shows: 1024 (too low for Virtualmin)
# Increase for current session
ulimit -n 65536
# Verify
ulimit -n
# Should show: 65536
# Make permanent
cat >> /etc/security/limits.conf << EOF
* soft nofile 65536
* hard nofile 65536
root soft nofile 65536
root hard nofile 65536
EOF
65536 क्यों? हर खुली फ़ाइल, सॉकेट, पाइप और डेटाबेस कनेक्शन एक फ़ाइल डिस्क्रिप्टर लेता है। 10+ WordPress साइट, मेल सर्वर, NGINX वर्कर और MySQL कनेक्शन के साथ आप आसानी से 1024 से ऊपर निकल जाते हैं। OVH और दूसरे प्रोवाइडर सुरक्षा के लिए यह रूढ़िवादी डिफ़ॉल्ट रखते हैं—इसे हर एप्लिकेशन के हिसाब से बढ़ाना होता है।
फ़िक्स 2: /tmp (tmpfs) बड़ा करें
रीस्टोर के दौरान Virtualmin MySQL डंप बनाता है /tmp/. डिफ़ॉल्ट रूप से, /tmp एक tmpfs (RAM डिस्क) है जो कुल RAM के ~50% तक सीमित रहता है। 11GB RAM के साथ, /tmp ~5.8GB पर अधिकतम हो जाता है। लेकिन Virtualmin रीस्टोर के दौरान आसानी से 5-6GB की अस्थायी फ़ाइलें बना सकता है।
# Check current /tmp size
df -h /tmp
# Dynamically resize without unmounting
mount -o remount,size=8G /tmp
# Verify
df -h /tmp
# Make permanent
echo "tmpfs /tmp tmpfs size=8G,mode=1777 0 0" >> /etc/fstab
फ़िक्स 3: स्वैप स्पेस जोड़ें
अगर रीस्टोर सारी RAM खा जाए तो सिस्टम जवाब देना बंद कर देता है। 4GB स्वैप एक सुरक्षा बफ़र देता है:
# Create 4GB swap file
fallocate -l 4G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
# Make permanent
echo '/swapfile none swap sw 0 0' >> /etc/fstab
# Verify
swapon --show
भाग 3: रीस्टोर प्रक्रिया और आम त्रुटियाँ
त्रुटि 1: “Checking contents of the backup ..” 20+ मिनट तक हैंग रहता है
यह ऐसा दिखता है:
बैकअप की सामग्री जाँची जा रही है ..
[15-30 मिनट तक बिना किसी प्रगति के अटका रहता है]
मूल कारण: यह हैंग नहीं हो रहा—यह सचमुच धीमा है। Virtualmin’s tar -tzf वेरिफ़िकेशन पूरा 4.4GB का कंप्रेस्ड आर्काइव पढ़ता है, हर फ़ाइल हेडर जाँचता है और tar की अखंडता जाँचता है। पुराने CPU (जैसे Haswell) पर 4GB बैकअप के लिए इसमें 20+ मिनट लग सकते हैं।
समाधान:
- घबराएँ नहीं। जाँचें कि tar वास्तव में चल रहा है या नहीं:
ps aux | grep tar
iostat -x 1 # Check disk activity
- वेब UI के बजाय CLI रीस्टोर का उपयोग करें (वेरिफ़िकेशन टाइमआउट को बायपास करता है):
screen -S restore
virtualmin restore-domain \
--source /Files/backup_*.tar.gz \
--all-domains \
--all-features \
--reuid
यह --reuid यह फ़्लैग user/group IDs को अपने आप समायोजित करता है—अलग-अलग सिस्टम पर रीस्टोर करते समय यह बहुत ज़रूरी है।
त्रुटि 2: “/bin/tar: Cannot write: No space left on device”
यह ऐसा दिखता है:
/bin/tar: ./seo.grahammiranda.com_mail_users: Cannot write: No space left on device
/bin/tar: ./esim.grahammiranda.com_virtualmin_ssl_key: Cannot write: No space left on device
[ऐसी और दर्जनों त्रुटियाँ]
/bin/tar: Exiting with failure status due to previous errors
उलझाने वाली बात यह है: आपके पास 75GB खाली है, फिर भी यह कहता है “No space left on device.”
मूल कारण (संभावना के क्रम में):
- फ़ाइल डिस्क्रिप्टर की सीमा पूरी हो जाना (सबसे आम)
- लक्षण: त्रुटियाँ रीस्टोर शुरू होने पर नहीं, बल्कि 5-10 मिनट बाद दिखती हैं
- समाधान:
ulimit -n 65536(ऊपर बताया गया है)
- /tmp भर जाता है (दूसरा सबसे आम)
- लक्षण: त्रुटियों में MySQL या temp फ़ाइलों का ज़िक्र होता है
- जाँचें:
df -h /tmpरीस्टोर के दौरान—इसे 100% तक भरते हुए देखें - समाधान:
mount -o remount,size=8G /tmp(ऊपर बताया गया है)
- असल में डिस्क स्पेस खत्म हो जाना (कम आम, लेकिन संभव)
- जाँचें:
df -h /shows <5GB free - समाधान:
- जाँचें:
# Clean up failed restore
rm -rf /home/*
rm -rf /var/lib/virtualmin/*
rm -rf /tmp/*
rm -rf /extract_test/
# If backup is still in /Files, consider moving it
mv /Files/backup_*.tar.gz /mnt/ # Move to another partition if available
- inode खत्म हो जाना (दुर्लभ)
- जाँचें:
df -i />90% iUsed दिखाता है - कारण: फ़ाइलसिस्टम बहुत कम inodes के साथ बनाया गया
- समाधान: फ़ाइलसिस्टम को अधिक inodes के साथ फिर से फ़ॉर्मेट करें (डेटा मिट जाएगा)
- जाँचें:
रीस्टोर के दौरान निदान का तरीका:
दूसरा टर्मिनल खोलें और रीयल-टाइम में निगरानी करें:
watch -n 2 'df -h / && echo "---" && df -h /tmp && echo "---" && du -sh /tmp/* 2>/dev/null | sort -rh | head -5'
इससे ठीक-ठीक पता चलता है कि सीमा कब और कहाँ पहुँची।
त्रुटि 3: रीस्टोर के बाद NGINX शुरू नहीं होता
त्रुटि संदेश:
nginx[34392]: [emerg] 34392#34392: open() "/etc/nginx/snippets/block-manager.conf" failed (2: No such file or directory)
nginx: configuration file /etc/nginx/nginx.conf test failed
मूल कारण: रीस्टोर आंशिक रूप से विफल रहा, या कुछ फ़ाइलें ठीक से ट्रांसफ़र नहीं हुईं। NGINX कॉन्फ़िग उन फ़ाइलों को संदर्भित करते हैं जो मौजूद नहीं हैं।
समाधान:
- गुम फ़ाइल बनाएँ:
mkdir -p /etc/nginx/snippets
touch /etc/nginx/snippets/block-manager.conf
- NGINX कॉन्फ़िग जाँचें:
nginx -t
- NGINX शुरू करें:
systemctl start nginx
systemctl status nginx
अगर फ़ाइल में असली कंटेंट चाहिए, तो अपने पुराने सर्वर पर जाँचें:
scp old-server.com:/etc/nginx/snippets/block-manager.conf /etc/nginx/snippets/

भाग 4: उन्नत समाधान और ऑप्टिमाइज़ेशन
एक बार में एक डोमेन रीस्टोर करना (सबसे सुरक्षित तरीका)
अगर सारे फ़िक्स लगाने के बाद भी पूरा रीस्टोर बार-बार फ़ेल हो रहा है, तो चुन-चुन कर रीस्टोर करें:
# Clean previous failed attempts
rm -rf /home/*
rm -rf /var/lib/virtualmin/*
# Restore just the main domain first
virtualmin restore-domain \
--source /Files/backup_*.tar.gz \
--domain grahammiranda.com \
--all-features \
--reuid
इससे पता चलता है कि किन डोमेन में दिक्कत है। अगर एक डोमेन सफलतापूर्वक रीस्टोर हो जाता है, तो वही तरीका बाक़ी डोमेन के लिए भी काम करता है।
Debian 12 से Debian 13 पर माइग्रेशन से जुड़ी बातें
मैंने Debian 12 से Debian 13 पर माइग्रेट किया। आम तौर पर ये एक-दूसरे के साथ चलते हैं, पर इन बातों पर ध्यान दें:
- PHP वर्ज़न का अंतर: Debian 12 में PHP 8.1 हो सकता है, Debian 13 में 8.3 है
- जाँचें:
php -vदोनों सर्वर पर - दिक्कत: पुराने PHP एक्सटेंशन के साथ कभी-कभार कम्पैटिबिलिटी की दिक्कत
- समाधान: पुराना PHP वर्ज़न ज़बरदस्ती सेट करें:
virtualmin modify-web --domain example.com --php-version 8.1
- जाँचें:
- NGINX/Apache कॉन्फ़िग सिंटैक्स: आम तौर पर कम्पैटिबल रहता है, पर रीस्टोर के बाद टेस्ट करें
- टेस्ट:
nginx -tऔरapache2ctl configtest
- टेस्ट:
- MySQL/MariaDB कम्पैटिबिलिटी: आम तौर पर आगे के वर्ज़न के साथ भी चलता है
- जाँचें:
mysql --versionदोनों सर्वर पर - डंप फ़ॉर्मैट में अंतर: कम ही होता है, पर नए Debian में SQL मोड ज़्यादा सख़्त हो सकते हैं
- जाँचें:
- SSL सर्टिफ़िकेट कम्पैटिबिलिटी: Debian वर्ज़न के बीच कोई दिक्कत नहीं आती, पर जाँच लें:
certbot certificates # Check Let's Encrypt certs
भाग 5: माइग्रेशन के बाद का सत्यापन
लाइव जाने से पहले ज़रूरी जाँचें
रीस्टोर पूरा होने के बाद जाँचें कि सब कुछ ठीक चल रहा है:
# 1. List all restored domains
virtualmin list-domains
# 2. Test web connectivity
curl -I https://yourdomain.com
# 3. Check mail functionality
mysql -u root -p'password' -e "SELECT user FROM mysql.user;"
# 4. Verify DNS
dig yourdomain.com @localhost
# 5. Check Virtualmin module
virtualmin test-domain --domain yourdomain.com
# 6. Monitor logs for errors
journalctl -f
tail -f /var/log/nginx/error.log
DNS रिकॉर्ड अपडेट करें
जब सभी डोमेन सफलतापूर्वक रीस्टोर हो जाएँ:
- रजिस्ट्रार में नेमसर्वर अपडेट करें ताकि वे नए सर्वर की ओर पॉइंट करें
- TTL की उलटी गिनती पर नज़र रखें (घटाए गए TTL के साथ यह 5 मिनट होनी चाहिए)
- कई जगहों से टेस्ट करें:
nslookup yourdomain.com
dig yourdomain.com +short
- DNS TTL को सामान्य पर वापस लाएँ 24-48 घंटे बाद:
virtualmin modify-dns --all-domains --ttl 3600
भाग 6: सिस्टम सीमाओं का संदर्भ
आगे काम आए, इसलिए इस माइग्रेशन में जाँची गई सभी सिस्टम सीमाएँ यहाँ दी गई हैं:
# User/process limits
ulimit -a # All limits
ulimit -n # Open files
ulimit -u # Max processes
ulimit -v # Virtual memory
# System-wide limits
cat /proc/sys/fs/file-max # System-wide open files
cat /proc/sys/kernel/pid_max # Max process IDs
cat /proc/sys/vm/max_map_count # Memory map limit
# Current resource usage
df -h # Disk space
df -i # Inode usage
free -h # RAM and swap
ps aux | wc -l # Running processes
lsof | wc -l # Open file descriptors
# Filesystem specifics
mount | grep /dev/sda1 # Mount options
quota -s # Disk quotas
tune2fs -l /dev/sda1 # Filesystem properties
मुख्य बातें
- OVH (और ज़्यादातर प्रोवाइडर) सुरक्षा के लिहाज़ से कम डिफ़ॉल्ट सेट करते हैं। Virtualmin बैकअप रीस्टोर करने से पहले फ़ाइल डिस्क्रिप्टर की सीमा बढ़ानी ज़रूरी है।
- असली दुश्मन डिस्क स्पेस नहीं, सिस्टम की सीमाएँ हैं। 75GB जगह खाली होने पर भी आपको “No space left on device” दिखेगा, अगर
/tmpभर जाए या फ़ाइल डिस्क्रिप्टर ख़त्म हो जाएँ। - बढ़ाएँ
/tmpका साइज़ रीस्टोर से पहले बढ़ाएँ। बैकअप रीस्टोर करते समय Virtualmin 5-6GB तक टेम्पररी फ़ाइलें बनाता है। डिफ़ॉल्ट tmpfs आवंटन काफ़ी नहीं होता। - वेब UI नहीं, CLI से रीस्टोर करें। बड़े बैकअप पर वेब UI में टाइमआउट की समस्याएँ आती हैं। कमांड-लाइन रीस्टोर अधिक भरोसेमंद है और असली प्रगति दिखाता है।
- Debian 12 से Debian 13 पर माइग्रेशन काम करता है, लेकिन एक ही वर्ज़न रहना अधिक सुरक्षित है। माइनर वर्ज़न के अंतर से शायद ही कभी समस्या होती है, लेकिन हो सके तो एक ही मेजर वर्ज़न के भीतर रहें।
- ट्रांसफ़र करने से पहले बैकअप की अखंडता जाँचें। यह सुनिश्चित करने के लिए SHA256 चेकसम का उपयोग करें कि ट्रांसफ़र के दौरान बैकअप फ़ाइल ख़राब नहीं हुई।
- माइग्रेशन से पहले योजना बनाने से घंटों का समय बचता है। DNS TTL कम करना, डेटाबेस का आकार जाँचना और टारगेट सर्वर तैयार करना—इनसे ज़्यादातर समस्याएँ टल जाती हैं।
निष्कर्ष
Virtualmin का माइग्रेशन मुश्किल नहीं है—बस थोड़ा नखरीला है। ज़्यादातर विफलताएँ खुद Virtualmin की वजह से नहीं होतीं, बल्कि होस्टिंग प्रोवाइडरों द्वारा तय की गई छिपी सिस्टम सीमाओं के कारण होती हैं। इन सीमाओं को समझकर और यहाँ बताए गए फ़िक्स लगाकर आप 10+ WordPress साइटों को सर्वरों के बीच भरोसेमंद तरीके से माइग्रेट कर सकते हैं।
मेरे सामने आई ख़ास त्रुटियाँ (फ़ाइल डिस्क्रिप्टर सीमाएँ, /tmp उनका ख़त्म हो जाना, NGINX स्निपेट्स का गायब होना) आम हैं और दोबारा पैदा हो सकती हैं। अगर आपको इनमें से कोई भी त्रुटि मिले, तो इस गाइड पर लौटें—आपको सटीक समाधान मिल जाएगा।
आपके माइग्रेशन के लिए शुभकामनाएँ। आपके बैकअप तेज़ी से रीस्टोर हों और आपके डोमेन बिना किसी हंगामे के ऑनलाइन आ जाएँ।
लेखक परिचय
यह गाइड एक वास्तविक Virtualmin माइग्रेशन का ब्योरा देती है, जो फ़रवरी 2026 में पूरा हुआ और जिसके तहत 10+ प्रोडक्शन डोमेन को Debian 12 VPS (फ़्रांस) से Debian 13 VPS (नीदरलैंड्स) पर माइग्रेट किया गया। इसके समाधान व्यवहार में परखे गए हैं और फ़ील्ड में सत्यापित हैं।



