وردپرس

نصب و انتقال وردپرس روی سرور مجازی — راهنمای کامل

نصب وردپرس روی سرور مجازی به ترتیب مرحله‌ها: آماده‌سازی پشته‌ی Nginx و PHP و MariaDB، ساخت دیتابیس، انتقال فایل و دیتابیس از هاست اشتراکی، تست با فایل hosts و در پایان سوئیچ رکورد A با TTL کم

نصب وردپرس روی سرور مجازی معمولاً وقتی به صرافتش می‌افتید که سایت از هاست اشتراکی بزرگ‌تر شده: دیر بارگذاری‌شدن در ساعت‌های شلوغ، خطای ۵۰۳ وسط کمپین فروش و محدودیت منابعی که معلوم نیست کجا تمام می‌شود. راه‌حل، سروری است که همه‌ی CPU و رم و دیسکش مال شماست. در این راهنما هر دو مسیر را قدم‌به‌قدم می‌رویم: نصب تمیز از صفر روی یک پشته‌ی LEMP، و انتقال کامل سایت فعلی بدون قطعی — به‌علاوه‌ی محدودیت‌های پیش‌فرضی که بیشتر مهاجرت‌ها را همان ساعت اول خراب می‌کنند.

چرا وردپرس روی سرور مجازی بهتر نفس می‌کشد؟

در هاست اشتراکی، سایت شما با ده‌ها سایت دیگر سرِ یک سفره نشسته: اگر همسایه‌تان زیر حمله برود یا اسکریپت سنگینی اجرا کند، سایت شما کند می‌شود. یک VPS معمولی با Nginx و PHP-FPM همان کارایی را می‌دهد، به شرطی که یک بار درست راه‌اندازی‌اش کنید:

  • منابع اختصاصی: رم و CPU فقط برای سایت شما کار می‌کند؛ کش شیءگرا (Redis) و تعداد پروسه‌های PHP-FPM را هم می‌توانید دقیقاً برای بار خودتان تنظیم کنید.
  • کنترل کامل: نسخه‌ی PHP، ماژول‌های Nginx، فایروال — همه دست شماست، نه تیکتِ پشتیبانی هاست.
  • مقیاس‌پذیری: جشنواره‌ی فروش دارید؟ منابع سرور را موقتاً بالا ببرید و بعد برگردانید.

اما یک صداقت لازم هم هست: با رفتن روی VPS، نقش «مدیر سرور» را هم می‌خرید. به‌روزرسانی سیستم‌عامل، تمدید SSL، پشتیبان‌گیری و بستن پورت‌ها دیگر کار کسی نیست جز شما.

💡 نکته: اگر مطمئن نیستید VPS برایتان جواب می‌دهد، صورتحساب ساعتی مهران هاست دقیقاً برای همین سناریوست: یک سرور بسازید، مهاجرت را چند ساعت تمرین کنید و اگر راضی نبودید فقط پول همان چند ساعت را داده‌اید.

سرور برای وردپرس امروز چه چیزهایی باید داشته باشد؟

پیش از اولین دستور بدانید وردپرس چه می‌خواهد؛ این اعداد تغییر کرده‌اند و کپی‌کردن یک آموزش قدیمی همین‌جا شما را زمین می‌زند. طبق صفحه‌ی رسمی پیش‌نیازها، امروز سه چیز لازم است: PHP نسخه‌ی 8.3 یا بالاتر، MariaDB نسخه‌ی 10.11 به بالا یا MySQL نسخه‌ی 8.0 به بالا، و HTTPS برای هر نصب — HTTPS دیگر «توصیه» نیست، الزام است.

این مستقیماً روی انتخاب توزیع اثر می‌گذارد. مخزن رسمی اوبونتو ۲۴٫۰۴ دقیقاً PHP 8.3 و MariaDB 10.11 دارد؛ با apt ساده و بدون مخزن جانبی هر دو شرط را می‌گذرانید. اما اوبونتو ۲۲٫۰۴ هنوز PHP 8.1 و MariaDB 10.6 می‌دهد و هر دو زیر حداقل امروزند؛ آموزشی که php8.1-fpm نصب می‌کند کهنه است.

⚠️ نسخه‌ی PHP فقط یک عدد نیست، تاریخ انقضا هم دارد. طبق جدول رسمی پشتیبانی PHP، نسخه‌های 8.4 و 8.5 در پشتیبانی کامل‌اند و 8.3 و 8.2 فقط وصله‌ی امنیتی می‌گیرند. یعنی نصب امروز روی PHP 8.3 سالم است، ولی برنامه‌ی ارتقا را از همین حالا داشته باشید؛ سروری که روی نسخه‌ی خارج از پشتیبانی می‌ماند ماه‌به‌ماه بدهی امنیتی جمع می‌کند.

پیش‌نیاز دوم، خودِ پشته است: Nginx نصب و فعال، دامنه‌ای که رکورد A آن به آی‌پی سرور اشاره می‌کند، و یک گواهی SSL. این‌ها را در راهنمای راه‌اندازی سایت با Nginx روی اوبونتو کامل گفته‌ایم — اول آن را انجام دهید، بعد برگردید.

مسیر اول: نصب وردپرس روی VPS از صفر

دیتابیس و افزونه‌های PHP

افزونه‌های PHP را یک‌جا نصب کنید: gd و imagick برای تصویر، mbstring برای متن فارسی، zip برای نصب افزونه و قالب، و curl برای ارتباط با api.wordpress.org:

apt install mariadb-server php8.3-fpm php8.3-mysql php8.3-curl \
  php8.3-gd php8.3-mbstring php8.3-xml php8.3-zip php8.3-imagick -y
mysql_secure_installation

سپس یک دیتابیس و کاربر اختصاصی بسازید. روی اوبونتو کاربر root دیتابیس با احراز هویت سوکت کار می‌کند، پس بدون رمز و با sudo وارد می‌شوید:

sudo mysql
CREATE DATABASE wpdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'YOUR-STRONG-PASSWORD';
GRANT ALL PRIVILEGES ON wpdb.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;

روی utf8mb4 کوتاه نیایید: کدگذاری قدیمی utf8 فقط سه بایت در هر نویسه جا دارد و نویسه‌های چهاربایتی مثل ایموجی را می‌شکند.

دانلود وردپرس و مالکیت فایل‌ها

cd /var/www/example.ir/html
wget https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz --strip-components=1
rm latest.tar.gz
chown -R www-data:www-data /var/www/example.ir/html

این آرشیو همیشه به آخرین نسخه‌ی پایدار اشاره می‌کند. سطح دسترسی را مطابق راهنمای سخت‌سازی وردپرس تنظیم کنید: پوشه‌ها 755 و فایل‌ها 644. برای wp-config.php همان راهنما 400 یا 440 را پیشنهاد می‌کند، چون تنها فایلی است که رمز دیتابیس داخلش نوشته می‌شود.

بلوک Nginx و پایان کار نصاب

Nginx فایل .htaccess را نمی‌خواند، پس قانون پیوند یکتا باید مستقیم در بلوک server باشد — مستندات وردپرس هم همین try_files را می‌دهد:

server {
    server_name example.ir www.example.ir;
    root /var/www/example.ir/html;
    index index.php;
    client_max_body_size 64m;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }
    location = /wp-config.php { deny all; }
}
nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
systemctl reload nginx

حالا دامنه را در مرورگر باز کنید؛ نصاب پنج‌دقیقه‌ای وردپرس بالا می‌آید، مشخصات دیتابیس را می‌گیرد و wp-config.php را خودش می‌سازد. نصب وردپرس روی VPS واقعاً بیشتر از یک ربع طول نمی‌کشد — بخش سختِ ماجرا بعد از آن است.

تنظیم‌های wp-config.php که همان روز اول لازم دارید

نصاب حداقلِ لازم را می‌نویسد، نه چیزی که سایت واقعی می‌خواهد. طبق مرجع wp-config.php چند ثابت ارزش اضافه‌کردن دارند:

define( 'WP_MEMORY_LIMIT', '256M' );
define( 'DISALLOW_FILE_EDIT', true );
define( 'FS_METHOD', 'direct' );
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

هر کدام دلیل مشخصی دارد. WP_MEMORY_LIMIT پیش‌فرض وردپرس فقط ۴۰ مگابایت برای نصب تک‌سایتی (و ۶۴ مگابایت برای چندسایتی) است و سقف بالادستی‌اش ۲۵۶ مگابایت؛ صفحه‌ی سفید هنگام نصب یک افزونه‌ی سنگین اغلب از همین‌جاست. DISALLOW_FILE_EDIT ویرایشگر قالب و افزونه را می‌بندد — مستندات وردپرس آن را معادل گرفتن قابلیت‌های edit_themes، edit_plugins و edit_files از همه‌ی کاربران می‌داند. FS_METHOD با مقدار direct جلوی پرسش «مشخصات FTP» را هنگام به‌روزرسانی می‌گیرد. سه‌گانه‌ی دیباگ هم خطاها را به‌جای صفحه‌ی کاربر در wp-content/debug.log می‌ریزد.

یک کار دیگر هم هست: هشت کلید امنیتی (SALT) که وردپرس با آن‌ها کوکی نشست را امضا می‌کند. وردپرس‌داتارگ یک سرویس تولید تصادفی رسمی دارد:

curl https://api.wordpress.org/secret-key/1.1/salt/
define('AUTH_KEY',         'q7>Vb...');
define('SECURE_AUTH_KEY',  'H2!dR...');
define('LOGGED_IN_KEY',    'x9%Lm...');
define('NONCE_KEY',        'Tf4@z...');

هشت خط خروجی را جایگزین هشت خط متناظر کنید. عوض‌کردن این کلیدها همه‌ی نشست‌های باز را بی‌اعتبار می‌کند؛ بعد از هر شکِ امنیتی، تولید دوباره‌شان اولین کار است.

مسیر دوم: انتقال وردپرس به سرور مجازی

انتقال وردپرس به سرور جدید سه جزء دارد: فایل‌ها، دیتابیس و تنظیمات. اگر همین ترتیب را رعایت کنید، بدون حتی یک دقیقه قطعی مهاجرت می‌کنید.

قدم ۱: انتقال فایل‌ها

اگر هاست قدیمی دسترسی SSH می‌دهد، rsync سریع‌ترین و امن‌ترین راه است — از روی سرور جدید اجرا کنید:

rsync -avz --progress user@old-host.com:public_html/ /var/www/example.ir/html/

sending incremental file list
wp-content/uploads/2026/05/hero.webp
wp-content/plugins/woocommerce/woocommerce.php
sent 41.02M bytes  received 118.71K bytes  1.63M bytes/sec

مزیت rsync تکرارپذیری است: امروز کل فایل‌ها را بیاورید و لحظه‌ی سوئیچ دوباره اجرایش کنید تا فقط تفاوت‌ها منتقل شوند. اگر روی هاست قبلی فقط پنل گرافیکی دارید، از فایل‌منیجر یک بایگانی ZIP بسازید و با scp بفرستید (آموزش اتصال با SSH):

scp backup.zip root@203.0.113.10:/var/www/example.ir/html/
ssh root@203.0.113.10
cd /var/www/example.ir/html && unzip backup.zip && rm backup.zip

قدم ۲: انتقال دیتابیس

روی هاست قدیمی از phpMyAdmin خروجی SQL بگیرید، یا اگر SSH دارید:

mysqldump --single-transaction --default-character-set=utf8mb4 \
  -u olduser -p old_database > db-backup.sql

دو پرچم اضافه بی‌دلیل نیستند. --single-transaction خروجی را از یک عکس لحظه‌ای سازگار و بدون قفل‌کردن جدول‌ها می‌گیرد، یعنی سایت قدیمی از کار نمی‌افتد. --default-character-set=utf8mb4 هم جلوی تبدیل نویسه‌ها به علامت سؤال را می‌گیرد. فایل را منتقل و وارد کنید:

mysql -u wpuser -p wpdb < db-backup.sql

قدم ۳: هماهنگ‌کردن wp-config.php

در فایل wp-config.php سرور جدید، چهار مقدار را با دیتابیس جدید یکی کنید:

define( 'DB_NAME', 'wpdb' );
define( 'DB_USER', 'wpuser' );
define( 'DB_PASSWORD', 'YOUR-STRONG-PASSWORD' );
define( 'DB_HOST', 'localhost' );

قدم ۴: تست قبل از تغییر DNS

بدون دست‌زدن به DNS می‌توانید سایت را روی سرور جدید ببینید: به فایل hosts سیستم خودتان (در لینوکس و مک /etc/hosts) یک خط اضافه کنید:

203.0.113.10  example.ir www.example.ir

حالا مرورگر شما سایت را از سرور جدید می‌خواند ولی بقیه‌ی دنیا هنوز هاست قدیمی را می‌بینند. صفحه‌ی اصلی، چند نوشته، پیشخوان، جست‌وجو، سبد خرید و آپلود تصویر را تست کنید، بعد آن خط را حذف کنید. تقریباً هر خطایی که بعد از سوئیچ DNS می‌ترساند، همین‌جا قابل کشف است.

قدم ۵: سوئیچ DNS با TTL کم

حداقل ۲۴ ساعت قبل از مهاجرت، TTL رکورد A را به ۳۰۰ ثانیه کاهش دهید تا لحظه‌ی سوئیچ، تغییر ظرف چند دقیقه پخش شود نه چند ساعت. بعد آی‌پی رکورد A را عوض کنید و وقتی همه‌چیز آرام شد TTL را برگردانید. اگر با TTL راحت نیستید، آموزش رکوردهای DNS را ببینید.

⚠️ هاست قدیمی را حداقل یک هفته فعال نگه دارید؛ برخی کاربران به‌خاطر کش DNS هنوز به سرور قدیم می‌رسند. خطر بزرگ‌تر: اگر در همین بازه کسی روی سرور قدیمی سفارش ثبت کند یا دیدگاه بگذارد، آن رکورد در دیتابیس قدیمی می‌ماند و هرگز به سرور جدید نمی‌رسد. برای فروشگاه‌ها، سفارش‌گیری را چند ساعت قبل از سوئیچ ببندید.

تله‌های رایج بعد از انتقال و راه‌حلشان

۱) همه‌ی صفحه‌ها به‌جز صفحه‌ی اصلی ۴۰۴ می‌دهند

در هاست اشتراکی فایل .htaccess پیوندهای یکتا را مدیریت می‌کرد و Nginx آن را نمی‌خواند. بخش location / باید همان try_filesای باشد که بالاتر آوردیم؛ بعد nginx -t && systemctl reload nginx.

۲) خطا در آپلود تصویر یا نصب افزونه

فایل‌هایی که با root منتقل کرده‌اید متعلق به root هستند، ولی PHP با کاربر www-data اجرا می‌شود. مالکیت و سطح دسترسی را یک‌جا درست کنید:

chown -R www-data:www-data /var/www/example.ir/html
find /var/www/example.ir/html -type d -exec chmod 755 {} \;
find /var/www/example.ir/html -type f -exec chmod 644 {} \;
chmod 440 /var/www/example.ir/html/wp-config.php

۳) محتوای مختلط (Mixed Content) بعد از SSL

اگر سایت قبلاً روی http بود، آدرس‌های قدیمی داخل دیتابیس قفل مرورگر را می‌شکنند. با WP-CLI جایگزینی امن انجام دهید؛ مستندات این ابزار می‌گوید داده‌های سریالایزشده‌ی PHP را هوشمندانه مدیریت می‌کند و کلید اصلی جدول‌ها را دست نمی‌زند — برخلاف جایگزینی مستقیم SQL:

sudo -u www-data wp search-replace 'http://example.ir' 'https://example.ir' \
  --skip-columns=guid --report-changed-only --dry-run

Success: 412 replacements to be made.

sudo -u www-data wp search-replace 'http://example.ir' 'https://example.ir' \
  --skip-columns=guid

دو نکته. اول --skip-columns=guid: مستندات مهاجرت وردپرس درباره‌ی این ستون می‌نویسد «حیاتی است که محتوای این فیلد را تغییر ندهید»، چون خبرخوان‌ها با همین مقدار تشخیص می‌دهند کدام نوشته را قبلاً نشان داده‌اند. دوم، WP-CLI عمداً با کاربر root اجرا نمی‌شود و پیام «Error: YIKES! It looks like you're running this as root.» می‌دهد؛ راه درست sudo -u www-data است، نه دور زدن هشدار.

۴) آپلود رسانه با خطای ۴۱۳ یا «فایل از حد مجاز بزرگ‌تر است» رد می‌شود

این تله دو لایه دارد و معمولاً فقط یکی‌اش را درست می‌کنند. لایه‌ی اول Nginx است: طبق مستندات ماژول اصلی Nginx پیش‌فرض client_max_body_size فقط 1m است و درخواست بزرگ‌تر خطای HTTP 413 می‌گیرد — و همان مستندات هشدار می‌دهد مرورگرها این خطا را درست نمایش نمی‌دهند. لایه‌ی دوم PHP است: upload_max_filesize برابر 2M و post_max_size برابر 8M.

۵) ایمپورت دیتابیس وسط کار قطع می‌شود

روی جدول‌های بزرگ، ایمپورت گاهی با قطع ارتباط متوقف می‌شود. علتش تقریباً همیشه max_allowed_packet است: بسته‌ی بزرگ‌تر از این حد اتصال را می‌بندد. مستندات MySQL این متغیر را هم سمت کلاینت و هم سمت سرور می‌داند (کلاینت ۱۶ و سرور ۶۴ مگابایت) و می‌گوید باید هر دو بالا بروند:

mysql --max_allowed_packet=256M -u wpuser -p wpdb < db-backup.sql

جدول زیر نشانه‌ها را به علت و کار بعدی وصل می‌کند:

نشانهعلت محتملکار بعدی
آپلود رسانه با خطای HTTP 413client_max_body_size روی پیش‌فرض 1mدر بلوک server به 64m ببرید و ریلود کنید
پیام «فایل بزرگ‌تر از حد مجاز»upload_max_filesize و post_max_size کم‌اندهر دو را بالا ببرید؛ دومی همیشه بزرگ‌تر از اولی
منوی بزرگ ناقص ذخیره می‌شودmax_input_vars روی 1000 ماندهافزایش دهید و PHP-FPM را ریلود کنید
فقط صفحه‌ی اصلی باز می‌شود، بقیه ۴۰۴قانون پیوند یکتا در Nginx نیستtry_files را به location / اضافه کنید
خطای Error establishing a database connectionمقادیر DB در wp-config.php غلط استبا mysql -u wpuser -p wpdb دستی وارد شوید
قفل مرورگر شکسته و تصویرها نمی‌آیندآدرس‌های http:// در دیتابیس ماندهwp search-replace با --skip-columns=guid
پیشخوان باز است ولی آپلود رد می‌شودمالکیت فایل‌ها root استchown -R www-data:www-data روی ریشه‌ی سایت
متن فارسی به علامت سؤال تبدیل شدهخروجی SQL غیر utf8mb4 گرفته شدهبا --default-character-set=utf8mb4 دوباره بگیرید
تغییر فایل PHP دیده نمی‌شودبایت‌کد قدیمی در OPcache ماندهsystemctl reload php8.3-fpm
سایت برای شما باز است ولی برای بقیه نهرکورد A هنوز آی‌پی قدیمی استبا dig +short example.ir A بررسی کنید

PHP-FPM و OPcache — جایی که سرور مجازی واقعاً جلو می‌زند

روی هاست اشتراکی این دو لایه دست شما نیست؛ روی VPS هست. مهم‌ترین عدد PHP-FPM، pm.max_children است: بیشترین تعداد درخواست PHP که هم‌زمان اجرا می‌شوند. میانگین مصرف رم هر پروسه را اندازه بگیرید و رم قابل‌تخصیص را بر آن تقسیم کنید:

ps -ylC php-fpm8.3 --no-headers | awk '{sum+=$8; n++} END {print sum/n/1024 " MB avg"}'
58.4 MB avg

اگر روی سروری با ۲ گیگابایت رم حدود ۱٫۲ گیگابایت را برای PHP کنار بگذارید و هر پروسه ۶۰ مگابایت بخورد، pm.max_children حدود ۲۰ منطقی است. عدد بزرگ‌تر سرور را به سمت حافظه‌ی مجازی می‌برد و عدد کوچک درخواست‌ها را در صف نگه می‌دارد. پیام «server reached pm.max_children setting» در لاگ یعنی عدد کم است.

لایه‌ی دوم OPcache است که بایت‌کد کامپایل‌شده را در حافظه نگه می‌دارد. پیش‌فرض‌ها معقول‌اند — opcache.memory_consumption برابر ۱۲۸ مگابایت و opcache.max_accelerated_files برابر ۱۰۰۰۰ — اما وردپرس با یک قالب و بیست افزونه از ده هزار فایل رد می‌شود و کش شروع به بیرون‌انداختن فایل‌ها می‌کند. PHP این عدد را به اولین عدد اولِ بزرگ‌تر گرد می‌کند (۷۹۶۳، ۱۶۲۲۹ و ۳۲۵۳۱ سه عضو آن مجموعه‌اند)، پس نوشتن ۱۲۰۰۰ عملاً یعنی ۱۶۲۲۹.

⚠️ OPcache می‌تواند ویرایش‌های شما را «قورت بدهد». پیش‌فرض opcache.validate_timestamps روشن است و opcache.revalidate_freq برابر ۲ ثانیه. اما اگر برای کارایی بیشتر validate_timestamps را خاموش کرده باشید، بازدیدکننده تا ریلود شدن سرویس نسخه‌ی قدیمی را می‌بیند — در حالی که PHP خط فرمان فایل تازه را می‌خواند و شما فکر می‌کنید تغییر اعمال شده.

چرا ایمیل وردپرس روی سرور مجازی نمی‌رسد؟

علتش یک سوءتفاهم ساده است: یک سرور مجازی خام هیچ سرویس ایمیلی ندارد. روی هاست اشتراکی، تابع wp_mail() به سرویس ارسال محلی وصل بود که هاستینگ نصب کرده بود؛ روی VPS چنین چیزی نیست، پس فرم تماس و ایمیل «بازیابی رمز» بی‌صدا شکست می‌خورند. تازه اگر خودتان یک سرویس ارسال نصب کنید، بسیاری از شبکه‌ها پورت خروجی 25 را می‌بندند و ایمیل فرستاده‌شده از آی‌پی تازه شانس بالایی برای افتادن در اسپم دارد.

راه درست، فرستادن از طریق SMTP یک سرویس ایمیل واقعی است: یک افزونه‌ی SMTP نصب کنید و مشخصات صندوق پستی دامنه‌تان را به آن بدهید — معمولاً پورت 587 با STARTTLS یا پورت 465 با TLS مستقیم. رکورد MX دامنه دست‌نخورده می‌ماند، چون MX فقط درباره‌ی دریافت ایمیل است. قدم آخر، تحویل به اینباکس به‌جای پوشه‌ی اسپم است که به رکوردهای TXT دامنه بستگی دارد؛ ترتیب ساختن SPF و DKIM و DMARC را در راهنمای رفع اسپم‌شدن ایمیل دامنه آورده‌ایم.

پشتیبان‌گیری: روی سرور مجازی کسی جز شما بکاپ نمی‌گیرد

این تفاوت اصلی VPS با هاست اشتراکی است. یک بکاپ کامل دو تکه دارد: پوشه‌ی سایت (که wp-content/uploads بزرگ‌ترین بخشش است) و دیتابیس. با WP-CLI هر دو در چند خط جمع می‌شوند:

cd /var/www/example.ir/html
sudo -u www-data wp db export --default-character-set=utf8mb4
Success: Exported to 'wpdb-2026-09-08-3f9a1c2.sql'.

tar -czf /var/backups/wp-$(date +%F).tar.gz wp-content wp-config.php wpdb-*.sql

اگر نام فایل را ندهید، wp db export خودش الگوی «نام دیتابیس + تاریخ + هش تصادفی» را می‌سازد، پس بکاپ‌های پشت‌سرهم روی هم نمی‌نویسند. سه قاعده: بکاپ را خارج از سرور نگه دارید، گرفتنش را زمان‌بندی کنید، و یک بار بازگردانی را تمرین کنید — بکاپ تست‌نشده فقط یک فایل بزرگ است. الگوهای چرخش نسخه‌ها در راهنمای پشتیبان‌گیری در لینوکس آمده است.

چک‌لیست بعد از مهاجرت

وقتی وردپرس روی سرور مجازی جدید بالا آمد، قبل از اعلام پایان کار این موارد را یکی‌یکی تیک بزنید:

  1. صفحه‌ی اصلی، چند نوشته، برگه‌ی تماس و جست‌وجو را باز کنید؛
  2. ورود به پیشخوان، آپلود رسانه و ذخیره‌ی یک پیش‌نویس را تست کنید؛
  3. یک فرم ثبت کنید و مطمئن شوید ایمیلش از مسیر SMTP می‌رسد؛
  4. افزونه‌ی کش را دوباره فعال و کش قدیمی را پاک کنید؛
  5. تمدید خودکار SSL را با certbot renew --dry-run بسنجید — از نسخه‌ی ۴٫۰٫۰ به بعد، Certbot وقتی تمدید می‌کند که کمتر از یک‌سومِ عمر گواهی مانده باشد، یعنی برای گواهی ۹۰ روزه حدود ۳۰ روز پیش از انقضا؛
  6. پشتیبان‌گیری خودکار راه بیندازید و یک بازگردانی آزمایشی بگیرید؛
  7. امنیت پایه‌ی سرور را طبق راهنمای امنیت سرور لینوکس ببندید: فایروال، Fail2ban و غیرفعال‌کردن ورود با رمز؛
  8. چند روز /var/log/nginx/error.log و wp-content/debug.log را زیر نظر بگیرید و بعد WP_DEBUG را خاموش کنید.

وردپرس روی سرور ابری مهران هاست

سرور ابری اینجا یک ماشین KVM با دیسک NVMe در دیتاسنتر داخل ایران است و صورتحسابش ساعتی از کیف پول کم می‌شود. دو نکته‌ی مالی: اول، خاموش‌کردن سرور صورتحساب را متوقف نمی‌کند — ماشین خاموشِ فعال با درصدی از نرخ ساعتی محاسبه می‌شود چون هنوز رم و دیسکش رزرو مانده، و تنها چیزی که هزینه را صفر می‌کند حذف سرور است. دوم، اگر موجودی کیف پول به صفر برسد سرورهای فعال خودکار تعلیق می‌شوند — نه وقتی منفی شد، بلکه همان لحظه‌ی تمام‌شدن اعتبار.

سمت شبکه هم دو چیز کار مهاجرت را کوتاه می‌کند. مدیریت DNS همان‌جا هشت نوع رکورد A، AAAA، CNAME، MX، TXT، NS، SRV و CAA را پوشش می‌دهد و کمترین TTL قابل‌انتخاب ۶۰ ثانیه است. و کنار هر رکورد A یک کلید CDN هست: با روشن‌کردنش پاسخ عمومی به نزدیک‌ترین نود لبه — داخل ایران یا اروپا — تغییر می‌کند و آی‌پی مبدأ پنهان می‌ماند، بدون هزینه‌ی جداگانه روی دامنه‌ای که DNS آن همان‌جا مدیریت می‌شود.

و اگر به این نتیجه رسیدید که سایتتان هنوز به VPS نیاز ندارد، این هم تصمیم درستی است: هاست وردپرس روی cPanel و DirectAdmin همان سایت را بدون هیچ‌کدام از کارهای این مقاله بالا نگه می‌دارد.

قدم بعدی

کل کار در سه جمله خلاصه می‌شود: یک پشته‌ی امروزی بالا بیاورید (PHP 8.3 و MariaDB 10.11 به بالا)، فایل و دیتابیس را با ابزار درست منتقل کنید، و پیش از سوئیچ DNS همه‌چیز را با فایل hosts تست کنید. یک سرور ابری بسازید و مهاجرت را با پرداخت ساعتی تمرین کنید.

سؤالات پرتکرار

برای نصب وردپرس روی سرور مجازی چه پیش‌نیازهایی لازم است؟

وردپرس امروز رسماً به PHP نسخه‌ی 8.3 یا بالاتر، MariaDB نسخه‌ی 10.11 به بالا یا MySQL نسخه‌ی 8.0 به بالا، و HTTPS روی هر نصب نیاز دارد؛ وب‌سرور پیشنهادی Apache یا Nginx است. مخزن رسمی اوبونتو ۲۴٫۰۴ هر دو شرط نرم‌افزاری را بدون مخزن جانبی برآورده می‌کند، ولی اوبونتو ۲۲٫۰۴ با نسخه‌های قدیمی‌تر زیر این حداقل می‌ماند.

انتقال وردپرس به سرور جدید چقدر قطعی به همراه دارد؟

اگر ترتیب درست را رعایت کنید، عملاً صفر. راز کار این است که پیش از دست‌زدن به DNS سایت را کامل روی سرور جدید بالا بیاورید و با یک خط در فایل hosts کامپیوتر خودتان تستش کنید؛ در این حالت فقط شما سرور جدید را می‌بینید. حداقل ۲۴ ساعت قبل هم TTL رکورد A را به ۳۰۰ ثانیه کم کنید.

چرا بعد از انتقال وردپرس همه‌ی صفحه‌ها به‌جز صفحه‌ی اصلی خطای ۴۰۴ می‌دهند؟

چون قانون پیوندهای یکتا منتقل نشده است. روی هاست اشتراکی این قانون در فایل .htaccess بود و آپاچی آن را می‌خواند، اما Nginx چنین فایلی را نمی‌خواند: در بلوک server و بخش location / خط try_files $uri $uri/ /index.php?$args; را بگذارید و سرویس را ریلود کنید.

برای مدیریت وردپرس روی سرور مجازی به کنترل‌پنل مثل cPanel نیاز دارم؟

خیر، لازم نیست. وردپرس خودش پیشخوان کامل دارد و کارهای سطح سرور — ساخت دیتابیس، پیکربندی Nginx، گرفتن گواهی SSL و پشتیبان‌گیری — با چند دستور خط فرمان انجام می‌شود. کنترل‌پنل فقط لایه‌ای گرافیکی روی همین کارهاست و خودش رم و CPU مصرف می‌کند. اگر چند سایت مشتری را مدیریت می‌کنید ممکن است وقتتان را ذخیره کند، وگرنه یک وابستگی اضافه است.

چرا فرم تماس سایت وردپرسی روی سرور مجازی ایمیل نمی‌فرستد؟

چون یک سرور مجازی خام هیچ سرویس ارسال ایمیلی ندارد و تابع wp_mail() بی‌صدا شکست می‌خورد. راه‌حل، نصب یک افزونه‌ی SMTP و دادن مشخصات یک صندوق پستی واقعی به آن است — معمولاً پورت 587 با STARTTLS یا پورت 465 با TLS. رکورد MX را عوض نکنید؛ MX فقط مسیر دریافت را تعیین می‌کند.

آموزش‌های مرتبط

آماده‌ی تمرین عملی هستید؟

سرور ابری ساعتی مهران هاست در ۶۰ ثانیه تحویل می‌شود — تمرین کنید و فقط بابت همان ساعت‌ها پرداخت کنید. هزینه را پیش از ثبت‌نام با محاسبه‌گر برآورد کنید.