SSD Nodes Learn Hosting plans →
تعلیمی Matt Connorتحریر: Matt Connor · اپ ڈیٹ شدہ 2026-08-30

WordPress میں WP-Cron کو غیر فعال اور System Cron استعمال

WP-Cron صرف پیج لوڈ ہونے پر چلتا ہے جو سائٹ کی رفتار کم کرتا ہے۔ WP-CLI کے ذریعے اسے System Cron پر منتقل کریں اور یقینی بنائیں کہ آپ کے شیڈول کردہ ٹاسک درست چل رہے ہیں۔

wp-cron کیا ہے، اور system cron اسے کیوں تبدیل کرتا ہے

WP-Cron ورڈپریس میں شامل ایک task scheduler ہے، جو صرف تب چلتا ہے جب کوئی صارف ویب پیج کی درخواست کرتا ہے۔ ورڈپریس کے اندر کوئی بھی چیز خود بخود متحرک نہیں ہوتی۔ ہر ایسی درخواست پر جو cache سے پوری نہ ہو، ورڈپریس شیڈول شدہ کاموں کی فہرست پڑھتا ہے، اور اگر کوئی کام وقت پر ہو تو وہ کام مکمل کرنے کے لیے /wp-cron.php پر خود کو ایک دوسری HTTP درخواست بھیجتا ہے۔ اس کام کو system cron پر منتقل کرنے سے آپ کو ایک مقررہ وقت پر کام چلنے کی ضمانت ملتی ہے، چاہے اس منٹ میں سائٹ پر ہزاروں وزیٹرز ہوں یا کوئی بھی نہ ہو۔

اصل کام دو لائنیں کرتی ہیں: wp-config.php میں ایک constant، اور ایک crontab entry۔ اس گائیڈ میں باقی سب کچھ وہ تفصیلات ہیں جو یہ دو لائنیں نہیں بتاتیں۔ مثلاً یہ کہ کام کس user کے تحت چلنا چاہیے، شیڈول شدہ ایونٹس کے چلنے کا ثبوت کیسے ملے، اور وہ تین طریقے جن سے یہ سیٹ اپ سائٹ پر کچھ ظاہر کیے بغیر ناکام ہو سکتا ہے۔

مثالوں میں /srv/www/example.com کو ورڈپریس ڈائریکٹری اور www-data کو ویب سرور user کے طور پر استعمال کیا گیا ہے۔ ہر جگہ اپنے paths اور user کا استعمال کریں۔

مصروف سائٹ پر کون سا وزیٹر cron کے اخراجات کا باعث بنتا ہے

ہر uncached درخواست چیکنگ کی قیمت ادا کرتی ہے۔ WordPress cron آپشن لوڈ کرتا ہے، ٹائم اسٹیمپس کا موازنہ کرتا ہے، اور جب کوئی کام واجب الادا ہوتا ہے تو یہ spawn_cron() کو کال کرتا ہے، جو /wp-cron.php کو ایک نان بلاکنگ لوپ بیک درخواست بھیجتا ہے۔ وزیٹر نتیجے کا انتظار نہیں کرتا، لیکن ایک PHP ورکر ایسا کرتا ہے۔ pm.max_children = 5 کے ساتھ PHP-FPM چلانے والے ایک چھوٹے VPS پر، ایک سست شیڈولڈ جاب آپ کی PHP صلاحیت کا پانچواں حصہ اتنی دیر تک روکے رکھتی ہے جتنا اسے مکمل ہونے میں لگتا ہے، اور اس کے آپ کے مصروف ترین منٹ کے دوران ٹرگر ہونے کا امکان سب سے زیادہ ہوتا ہے، کیونکہ تب ہی سب سے زیادہ پیج لوڈز ہوتے ہیں۔

WordPress ڈپلیکیٹس کو محدود کرتا ہے۔ یہ ایک لاک لیتا ہے جس کی لائف ٹائم WP_CRON_LOCK_TIMEOUT ہے، جو بائی ڈیفالٹ 60 سیکنڈ ہے، تاکہ بیک وقت آنے والے وزیٹرز میں سے ہر ایک رن شروع نہ کر دے۔ لاک ڈپلیکیشن کو محدود کرتا ہے، لیکن یہ کام کو درخواست کے راستے سے نہیں ہٹاتا۔

فیصلہ کرنے سے پہلے کہ آیا یہ اہم ہے، اپنے سرور پر گنیں کہ یہ کتنی بار چلتا ہے۔ ہر لوپ بیک ویب سرور کے ایکسیس لاگ میں ظاہر ہوتا ہے:

sudo grep -c 'wp-cron.php' /var/log/nginx/access.log

Apache اس کے بجائے /var/log/apache2/access.log میں لکھتا ہے۔ روزانہ ہزاروں کی تعداد میں گنتی ایک حقیقی لاگت ہے، اور یہ وہ نمبر ہے جسے آپ کو کسی مضمون میں پڑھنے کے بجائے اپنے باکس پر خود ماپنا چاہیے، بالکل اسی طرح جیسے آپ کسی بھی دوسری تبدیلی سے پہلے VPS کو بینچ مارک کرتے ہیں۔

کیشنگ صورتحال کو بدل دیتی ہے۔ اگر پیج کیش زیادہ تر درخواستوں کو بطور سٹیٹک HTML پیش کرتا ہے، تو ان درخواستوں کے لیے PHP کبھی نہیں چلتا، اس لیے cron چیک کبھی نہیں ہوتا۔ ایک بھاری کیشڈ مصروف سائٹ نیچے دی گئی خاموش سائٹ کی طرح برتاؤ کرنے لگتی ہے۔

جب وزٹرز کی کمی cron کو غیر فعال کر دیتی ہے

اگر سائٹ پر وزٹرز نہ ہوں تو cron بھی نہیں چلتا۔ ایسی سائٹ جس پر دن میں چند وزٹرز آتے ہوں، اس کے شیڈول کردہ کام بھی دن میں صرف چند بار ہی انجام پاتے ہیں، اور وہ بھی تب جب کوئی وزٹر سائٹ لوڈ کرتا ہے۔

اس مسئلے کی علامات ایک جیسی ہوتی ہیں۔ 09:00 بجے شیڈول کی گئی پوسٹ تب تک Missed schedule کے طور پر مارک رہتی ہے جب تک کوئی صارف صفحہ لوڈ نہ کرے۔ بیک اپ پلگ انز رات کا کام چھوڑ دیتے ہیں۔ اپ ڈیٹ چیکس میں تاخیر ہو جاتی ہے، جس کی وجہ سے ڈیش بورڈ پر کوئی اپ ڈیٹ نظر نہیں آتی حالانکہ سیکیورٹی ریلیز آ چکی ہوتی ہے۔ آرڈر ای میلز، تجدید کے نوٹسز اور میعاد ختم ہونے کی وارننگز تاخیر سے بھیجی جاتی ہیں۔

اس میں سے کسی بھی عمل کا کوئی error لاگ نہیں بنتا۔ WordPress کے نزدیک کام کبھی لیٹ نہیں ہوتا، کیونکہ وہ کبھی شروع ہی نہیں ہوا ہوتا۔

مرحلہ 1: wp-config.php میں وزٹر ٹرگر کو بند کریں

/srv/www/example.com/wp-config.php کو کھولیں اور یہ کانسٹنٹ شامل کریں:

define( 'DISABLE_WP_CRON', true );

اسے اس لائن کے اوپر رکھیں جو /* That's all, stop editing! Happy publishing. */ پڑھتی ہے، کیونکہ اس تبصرے کے بالکل نیچے والی لائن کو wp-settings.php کی ضرورت ہوتی ہے، اور wp-settings.php وہ جگہ ہے جہاں WordPress کرون چیک کو init پر ہک کرتا ہے۔ اس require کے بعد ڈیفائن کیا گیا کانسٹنٹ بہت دیر سے سیٹ ہوتا ہے اور کسی چیز کو تبدیل نہیں کر سکتا، اور فائل درست نظر آتی ہے جبکہ ٹرگر چلتا رہتا ہے۔

تصدیق کریں کہ لائن وہیں ہے جہاں آپ کا خیال ہے:

grep -n "DISABLE_WP_CRON\|stop editing" /srv/www/example.com/wp-config.php

یہ کانسٹنٹ ایونٹس کو شیڈول ہونے سے نہیں روکتا۔ پلگ انز پہلے کی طرح قطار میں جابز شامل کرتے رہتے ہیں۔ یہ صرف پیج لوڈز کو اس قطار کو چلانے سے روکتا ہے، جس کا مطلب ہے کہ قطار اب کبھی نہیں چلے گی جب تک آپ مرحلہ 3 مکمل نہیں کر لیتے۔

یہ /wp-cron.php پر براہ راست درخواستوں کو بھی بلاک نہیں کرتا۔ کوئی بھی اب بھی اس URL کی درخواست کر سکتا ہے، اور یہ عام طور پر بے ضرر ہے کیونکہ فائل صرف وہی کچھ چلاتی ہے جو واجب الادا ہو۔ اسے اپنے ویب سرور کنفیگریشن میں بلاک کرنا اختیاری ہے۔ اگر آپ اسے بلاک کرتے ہیں، تو اس گائیڈ کے آخر میں موجود curl فال بیک بھی کام کرنا چھوڑ دے گا۔

مرحلہ 2: WP-CLI انسٹال کریں

WP-CLI ورڈپریس کے لیے آفیشل کمانڈ لائن ٹول ہے۔ اسے PHP کمانڈ لائن بائنری کی ضرورت ہوتی ہے، جو ویب سرور کے PHP ماڈیول سے ایک الگ پیکیج ہے۔

php -v
sudo apt install -y php-cli

WP-CLI کو phar بلڈ سے انسٹال کریں، جیسا کہ آفیشل انسٹال گائیڈ تجویز کرتی ہے:

cd /tmp
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
php wp-cli.phar --info
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
wp --info

php wp-cli.phar --info PHP بائنری پاتھ، PHP ورژن اور WP-CLI ورژن پرنٹ کرتا ہے۔ اگر یہ تینوں چیزیں پرنٹ ہو جائیں تو phar درست کام کر رہا ہے۔ اگست 2026 تک انسٹال گائیڈ PHP 7.2.24 کو کم از کم ضرورت قرار دیتی ہے، اور Ubuntu 24.04 میں PHP 8.3 موجود ہے، لہذا موجودہ سرور اس حد سے کافی اوپر ہے۔ بعد میں sudo wp cli update کے ساتھ اپ ڈیٹ کریں۔

WP-CLI کو سائٹ کے یوزر کے طور پر چلائیں، کبھی بھی root کے طور پر نہ چلائیں:

sudo -u www-data /usr/local/bin/wp --path=/srv/www/example.com core version

root کے طور پر، WP-CLI شروع ہونے سے انکار کر دیتا ہے:

Error: YIKES! It looks like you're running this as root.

یہ --allow-root تجویز کرتا ہے۔ یہاں اس کا استعمال نہ کریں۔ اس کی وجہ نیچے دی گئی پہلی ناکامی کی حالت میں موجود ہے۔

یہ بھی نوٹ کریں کہ sudo -u www-data -i کام نہیں کرتا، کیونکہ اس اکاؤنٹ کی لاگ ان شیل /usr/sbin/nologin ہے اور آپ کو This account is currently not available. ملتا ہے۔ کمانڈ کو براہ راست sudo -u میں پاس کرنے سے لاگ ان شیل بائی پاس ہو جاتا ہے، اس لیے یہ ٹھیک کام کرتا ہے۔

اب تصدیق کریں کہ ورڈپریس خود مرحلہ 1 سے کانسٹنٹ (constant) کو دیکھ رہا ہے:

sudo -u www-data /usr/local/bin/wp --path=/srv/www/example.com eval 'var_dump( DISABLE_WP_CRON );'

یہ bool(true) پرنٹ کرتا ہے۔ غیر متعین کانسٹنٹ (undefined constant) کے بارے میں ایک مہلک غلطی (fatal error) کا مطلب ہے کہ define() لائن تک رسائی نہیں ہو رہی، جس کا عام طور پر مطلب یہ ہے کہ یہ require کے نیچے موجود ہے۔

مرحلہ 3: درست صارف کے طور پر cron اندراج شامل کریں

درست صارف وہی ہے جو ان فائلوں کا مالک ہے جنہیں PHP لکھتا ہے۔ دونوں اطراف کی جانچ کریں:

stat -c '%U %G' /srv/www/example.com/wp-content/uploads
grep -E '^(user|group) = ' /etc/php/8.3/fpm/pool.d/www.conf

Ubuntu کی ڈیفالٹ تنصیب پر دونوں کا جواب www-data ہوتا ہے۔ اگر آپ نے سائٹ کو اس کا اپنا PHP-FPM پول اور اپنا صارف دیا ہے، جو کہ Ubuntu 24.04 پر LAMP stack پر فی سائٹ سیٹ اپ کا عام انجام ہے، تو نیچے دی گئی ہر چیز کے لیے اسی صارف کا استعمال کریں۔

ایک ایسی log ڈائریکٹری بنائیں جس میں وہ صارف لکھ سکے:

sudo install -d -o www-data -g www-data -m 750 /var/log/wp-cron

اس صارف کا crontab ایڈٹ کریں:

sudo crontab -u www-data -e

ایک لائن شامل کریں:

*/5 * * * * /usr/bin/flock -n /run/lock/wp-cron-example.lock /usr/local/bin/wp --path=/srv/www/example.com cron event run --due-now >> /var/log/wp-cron/example.log 2>&1

ایک ایک حصے کی وضاحت: */5 اسے ہر پانچ منٹ بعد چلاتا ہے۔ flock -n ایک lock فائل لیتا ہے اور اگر پچھلی رن ابھی تک اسے ہولڈ کیے ہوئے ہو تو فوراً رک جاتا ہے۔ /usr/local/bin/wp مکمل پاتھ ہے، جس کی cron کو ضرورت ہوتی ہے۔ --path کمانڈ کو کسی بھی ورکنگ ڈائریکٹری سے چلنے دیتا ہے۔ --due-now صرف ان ایونٹس کو چلاتا ہے جن کا وقت آ چکا ہو، بجائے اس کے کہ قطار میں موجود ہر ایونٹ کو چلائے۔ ری ڈائریکٹ عام آؤٹ پٹ اور غلطیوں کو ایک ایسی فائل میں بھیجتا ہے جسے آپ پڑھ سکتے ہیں۔

عملی طور پر وہ ری ڈائریکٹ اختیاری نہیں ہے۔ Cron جاب کی آؤٹ پٹ کو اپنے صارف کو میل کرتا ہے، زیادہ تر VPS امیجز میں کوئی mail transfer agent انسٹال نہیں ہوتا، اور پھر cron (CRON) info (No MTA installed, discarding output) لاگ کرتا ہے اور آؤٹ پٹ کو ضائع کر دیتا ہے۔ ایک فائل ثبوت کو محفوظ رکھتی ہے۔

محفوظ شدہ فائل کو چیک کریں:

sudo crontab -u www-data -l

متعدد سائٹس کے لیے، ہر ایک کے لیے ایک لائن استعمال کریں جس میں منٹ مختلف ہوں تاکہ وہ سب ایک ساتھ شروع نہ ہوں:

*/5 * * * * /usr/bin/flock -n /run/lock/wp-cron-one.lock /usr/local/bin/wp --path=/srv/www/one.example.com cron event run --due-now >> /var/log/wp-cron/one.log 2>&1
2-59/5 * * * * /usr/bin/flock -n /run/lock/wp-cron-two.lock /usr/local/bin/wp --path=/srv/www/two.example.com cron event run --due-now >> /var/log/wp-cron/two.log 2>&1

لاگ ہمیشہ بڑھتا رہتا ہے جب تک کہ آپ اسے rotate نہ کریں۔ /etc/logrotate.d/wp-cron لکھیں:

/var/log/wp-cron/*.log {
    weekly
    rotate 4
    missingok
    notifempty
    compress
    create 640 www-data www-data
}

چیک کریں کہ یہ بغیر کسی چیز کو چھوئے پارس (parse) ہوتا ہے: sudo logrotate --debug /etc/logrotate.d/wp-cron۔

مرحلہ 4: تصدیق کریں کہ شیڈول شدہ ایونٹس واقعی چل گئے ہیں

crontab کی ایک لائن کا کامیابی سے محفوظ ہو جانا کچھ ثابت نہیں کرتا۔ سب سے آسان جانچ سے شروع کریں اور اس تک پہنچیں جو اصل صورتحال واضح کرے۔

پہلے، کیا cron نے کمانڈ شروع کی؟ Cron اپنے یونٹ کے تحت journal میں لاگ لکھتا ہے:

journalctl -u cron.service --since "15 min ago" | grep wp

ایک درست اندراج کچھ اس طرح نظر آتا ہے، جس میں ٹائم اسٹیمپ اور ہوسٹ کا نام شروع سے ہٹا دیا گیا ہے:

CRON[24913]: (www-data) CMD (/usr/bin/flock -n /run/lock/wp-cron-example.lock /usr/local/bin/wp --path=/srv/www/example.com cron event run --due-now >> /var/log/wp-cron/example.log 2>&1)

اس لائن کا مطلب ہے کہ cron نے آپ کی کمانڈ کو www-data کے طور پر شروع کیا۔ یہ اس بارے میں کچھ نہیں بتاتی کہ آیا کمانڈ نے کام کیا یا نہیں۔

دوسرے، کیا WordPress نے کچھ ایگزیکیوٹ کیا؟ لاگ فائل پڑھیں:

sudo tail -n 20 /var/log/wp-cron/example.log

WP-CLI ہر ایونٹ کے لیے ایک لائن پرنٹ کرتا ہے، پھر کل تعداد:

Executed the cron event 'wp_version_check' in 0.418s.
Success: Executed a total of 2 cron events.

غلطیاں اسی فائل میں آتی ہیں، جو کہ 2>&1 کا اصل مقصد ہے۔ زیادہ تر بار کچھ بھی واجب الادا نہیں ہوگا اور بہت کم لکھا جائے گا، لہذا فائل کو اس وقت پڑھیں جب آپ کو معلوم ہو کہ کام انتظار میں تھا۔

تیسرے، اسے مکمل طور پر ثابت کریں۔ ایک مارکر ایونٹ شیڈول کریں اور اسے غائب ہوتے ہوئے دیکھیں:

sudo -u www-data /usr/local/bin/wp --path=/srv/www/example.com cron event schedule wp_cli_cron_check now
sudo -u www-data /usr/local/bin/wp --path=/srv/www/example.com cron event list --fields=hook,next_run_relative --format=csv | grep wp_cli_cron_check

ایک وقفے کا انتظار کریں، پھر لسٹ کمانڈ دوبارہ چلائیں۔ ہک ختم ہو چکا ہوگا، کیونکہ ایک بار چلنے والا ایونٹ چلنے کے بعد قطار سے ہٹا دیا جاتا ہے۔ کوئی پلگ ان اس ہک نام پر کال بیک رجسٹر نہیں کرتا، لہذا اسے چلانے سے سائٹ پر کوئی اور اثر نہیں پڑے گا۔ اگر دو وقفوں کے بعد بھی ہک لسٹ میں موجود ہے، تو قطار نہیں چل رہی ہے، اور پہلی دو جانچیں آپ کو بتائیں گی کہ مسئلہ cron کا ہے یا WP-CLI کا۔

اس کے لیے wp cron test استعمال نہ کریں۔ وہ کمانڈ چیک کرتی ہے کہ آیا وزیٹر کے ذریعے ٹرگر ہونے والا spawning کام کر رہا ہے، اور جب DISABLE_WP_CRON درست (true) ہو تو یہ ایرر دیتی ہے۔ ایک صحیح طریقے سے کنفیگر شدہ سرور پر یہ ایرر متوقع آؤٹ پٹ ہے، نہ کہ کوئی خرابی۔

systemd timer کا متبادل

اگر سرور کے دیگر طے شدہ کام پہلے ہی systemd services and timers کے طور پر چل رہے ہیں، تو WordPress کو بھی وہیں منتقل کر دیں۔ ہر رن systemctl list-timers میں نظر آئے گا، اور آؤٹ پٹ کسی ایسی فائل کے بجائے journal میں جائے گی جسے آپ کو rotate کرنا پڑے۔

/etc/systemd/system/wp-cron-example.service لکھیں:

[Unit]
Description=Run due WordPress cron events for example.com

[Service]
Type=oneshot
User=www-data
Group=www-data
ExecStart=/usr/local/bin/wp --path=/srv/www/example.com cron event run --due-now

پھر /etc/systemd/system/wp-cron-example.timer کریں:

[Unit]
Description=Run WordPress cron for example.com every 5 minutes

[Timer]
OnCalendar=*:0/5
AccuracySec=30s
Persistent=true

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now wp-cron-example.timer
systemctl list-timers wp-cron-example.timer
journalctl -u wp-cron-example.service -n 20

Systemd ایک ہی سروس کی دو کاپیاں بیک وقت نہیں چلائے گا، لہذا اس ورژن کو flock کی ضرورت نہیں ہے۔ Persistent=true اسے اس رن کو مکمل کرنے کے قابل بناتا ہے جو مشین بند ہونے کے دوران چھوٹ گیا ہو، جو کہ crontab اندراج نہیں کر سکتا۔

Crontab یا timer میں سے کسی ایک کا انتخاب کریں۔ دونوں کو ایک ہی سائٹ پر چلانے کا مطلب ہے کہ queue دو بار خالی ہو رہی ہے، اور ای میل یا آرڈر جاب کے ڈپلیکیٹ رن آپ کے صارفین کو نظر آئیں گے۔

cron job کو root کے طور پر کیوں نہیں چلنا چاہیے

یہ ان تین طریقوں میں سے پہلا ہے جن سے یہ سیٹ اپ ناکام ہوتا ہے۔ اگر آپ اس جاب کو root کے crontab میں ڈال دیں تو WP-CLI کوئی بھی کام کرنے سے پہلے رک جاتا ہے:

Error: YIKES! It looks like you're running this as root.

کیو (queue) کبھی نہیں چلتی، اور اگر آپ نے آؤٹ پٹ کو ری ڈائریکٹ نہیں کیا تو آپ کو پیغام کبھی نظر نہیں آئے گا۔ اس کا خطرناک حل --allow-root کا اضافہ کرنا ہے، کیونکہ اس صورت میں اس رن کے دوران پلگ ان جو بھی فائل لکھتا ہے وہ root کی ملکیت بن جاتی ہے۔ اگلی ویب ریکویسٹ www-data کے طور پر چلتی ہے، ان ڈائریکٹریز میں لکھ نہیں پاتی، اور سائٹ اس طرح کے پیغامات دکھانا شروع کر دیتی ہے:

Unable to create directory wp-content/uploads/2026/08. Is its parent directory writable by the server?

فائل کی ملکیت (ownership) کو درست کریں، پھر جاب کو منتقل کریں:

sudo chown -R www-data:www-data /srv/www/example.com/wp-content

root کا crontab اور www-data کا crontab الگ الگ فائلیں ہیں، لہذا ایک سے لائن ڈیلیٹ کرنے کا اثر دوسرے پر نہیں پڑتا۔ دونوں کو چیک کریں:

sudo crontab -u root -l
sudo crontab -u www-data -l

cron wp: not found کی رپورٹ کیوں دیتا ہے

یہ دوسری ناکامی ہے۔ Cron صارف کے جابز کو بہت مختصر PATH، /usr/bin:/bin فراہم کرتا ہے۔ WP-CLI کو /usr/local/bin میں انسٹال کیا جاتا ہے، جو اس فہرست میں شامل نہیں ہے۔ جاب شروع ہوتی ہے، ایک سیکنڈ کے کچھ حصے میں ناکام ہو جاتی ہے، اور لاگ میں صرف ایک لائن درج ہوتی ہے:

/bin/sh: 1: wp: not found

اندازہ لگانے کے بجائے خود cron کا ماحول دیکھیں۔ ایک عارضی لائن شامل کریں:

*/5 * * * * env > /tmp/cron-env.txt 2>&1

ایک وقفے کے بعد /tmp/cron-env.txt کو پڑھیں، پھر اس لائن کو حذف کر دیں۔ اس فائل میں موجود PATH= کی قدر بالکل وہی ہے جو آپ کی جاب کو ملتی ہے۔

اس کے دو حل ہیں۔ مرحلہ 3 کی طرح مکمل پاتھ /usr/local/bin/wp استعمال کریں۔ یا پھر crontab کے اوپری حصے میں، ہر جاب لائن سے اوپر، ایک بار PATH سیٹ کریں:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

یہی مسئلہ ایک سطح نیچے بھی موجود ہے۔ wp phar کا آغاز #!/usr/bin/env php سے ہوتا ہے، لہذا شیل کو php کو تلاش کرنے کے قابل ہونا چاہیے۔ اگر PHP /usr/bin کے باہر موجود ہو، جو کہ کسٹم بلڈز اور کنٹرول پینل بلڈز کے ساتھ ہوتا ہے، تو آپ کو یہ ملے گا:

/usr/bin/env: 'php': No such file or directory

اس صورت میں انٹرپریٹر کو واضح طور پر کال کریں، مثال کے طور پر /usr/local/bin/php /usr/local/bin/wp --path=/srv/www/example.com cron event run --due-now۔

ایک منٹ کا وقفہ اصل مسئلہ دوبارہ کیوں پیدا کرتا ہے

یہ تیسری ناکامی ہے۔ * * * * * پانچ منٹ کے مقابلے میں زیادہ محفوظ محسوس ہوتا ہے، لیکن ایک مصروف سائٹ پر یہ آپ کو وہیں واپس لے جاتا ہے جہاں سے آپ نے شروع کیا تھا۔ اگر ایک رن وقفے سے زیادہ وقت لے، تو پہلا رن جاری رہنے کے دوران ہی دوسرا شروع ہو جاتا ہے۔ دس منٹ بعد وہاں دس PHP پروسیسز موجود ہوتے ہیں، جن میں سے ہر ایک اپنی میموری اور اپنا ڈیٹا بیس کنکشن سنبھالے ہوئے ہوتا ہے۔

پائل اپ (pileup) کو براہ راست تلاش کریں:

ps -eo etimes,user,args | grep '[c]ron event run'

etimes سیکنڈز میں پروسیس کی عمر ہے۔ ایک لائن کا مطلب ہے کہ سب ٹھیک ہے۔ کئی لائنیں جن کی عمر آپ کے وقفے سے کہیں زیادہ ہو، اس کا مطلب ہے کہ رنز ایک دوسرے کے اوپر جمع ہو رہے ہیں، اور ایک چھوٹی VPS پر یہ MySQL Too many connections ایرر پر ختم ہوتا ہے، یا کرنل کی جانب سے میموری واپس حاصل کرنے کے لیے PHP کو ختم کرنے پر، جس کی تصدیق آپ sudo dmesg -T | grep -i 'killed process' سے کر سکتے ہیں۔

WP-CLI ایونٹ کال بیکس کو براہ راست چلاتا ہے بجائے اس کے کہ wp-cron.php کی درخواست کرے، لہذا وہ 60 سیکنڈ کا لاک جو WordPress ڈپلیکیٹ اسپونز کے خلاف استعمال کرتا ہے، یہاں لاگو نہیں ہوتا۔ مرحلہ 3 کی انٹری میں flock -n وہ چیز ہے جو اب اوورلیپ کو روکتی ہے۔ ایک اسکیپڈ (skipped) رن ڈیزائن کے مطابق فوری اور خاموشی سے ایگزٹ ہو جاتا ہے۔ اوورلیپ ایک ایسا مسئلہ ہے جسے آپ کو crontab میں حل کرنا ہوگا، نہ کہ وہ جسے ہوسٹ کرنل آپ کے لیے حل کر دے: یہاں تک کہ Linux kernel 7.2 میں شامل cache aware task placement بھی صرف یہ فیصلہ کرتا ہے کہ پروسیس کس کور (core) پر جائے گا، یہ کبھی نہیں کہ آپ نے ان میں سے کتنے شروع کیے ہیں۔

وقفے کا انتخاب اس مختصر ترین شیڈول سے کریں جس پر آپ واقعی انحصار کرتے ہیں، اور پہلے ایک رن کی پیمائش کریں:

time sudo -u www-data /usr/local/bin/wp --path=/srv/www/example.com cron event run --due-now

پانچ منٹ ایک مناسب ڈیفالٹ ہے: 09:00 بجے کے لیے شیڈول کردہ پوسٹ 09:05 تک شائع ہو جاتی ہے۔ پندرہ منٹ ایسی سائٹ کے لیے ٹھیک ہے جس پر کوئی وقت کی پابندی والی چیز نہ ہو۔ ایک منٹ کا وقفہ ان اسٹورز اور قطار پر مبنی پلگ انز کے لیے ہے جنہیں واقعی اس کی ضرورت ہے، اور صرف تب جب آپ جان لیں کہ ایک رن چند سیکنڈز میں مکمل ہو جاتا ہے۔

اگر آپ WP-CLI انسٹال نہیں کر سکتے

کچھ ہوسٹس شیل ٹولز کو بلاک کر دیتے ہیں۔ wp-cron.php پر ایک سادہ HTTP درخواست وہی قطار (queue) چلاتی ہے، بس یہ پورے ویب اسٹیک کے ذریعے گزرتی ہے:

*/5 * * * * /usr/bin/curl -sS --max-time 120 "https://example.com/wp-cron.php?doing_wp_cron" > /dev/null

آپ واضح طور پر جن چیزوں سے محروم رہتے ہیں:

  • یہ عمل ویب سرور اور PHP-FPM کے request timeouts کی وجہ سے محدود ہوتا ہے، لہذا ایک طویل کام درمیان میں ہی رک سکتا ہے۔
  • سرٹیفکیٹ کا درست ہونا ضروری ہے ورنہ curl، SSL certificate problem کے ساتھ رک جائے گا، لہذا Certbot on nginx کے ساتھ تجدید (renewals) کو فعال رکھیں۔
  • پیج کیشنگ (page caching) کو wp-cron.php کو کیش نہیں کرنا چاہیے، ورنہ کرون (cron) درخواستوں کو کیش شدہ جواب ملے گا اور کوئی کام نہیں ہوگا۔
  • آپ کو فی ایونٹ کوئی آؤٹ پٹ نہیں ملتا، لہذا اس بات کا واحد ثبوت کہ کوئی کام مکمل ہوا، وہ اثر ہے جو اس نے مرتب کیا۔

-sS کامیابی کی صورت میں curl کو خاموش رکھتا ہے جبکہ غلطیوں کو پرنٹ کرتا رہتا ہے، جو کہ کرون جاب میں آپ کی ضرورت ہوتی ہے۔

سرور کے شیڈول میں اور کیا شامل ہونا چاہیے

ایک بار جب WordPress کی قطار (queue) سسٹم cron کے پاس آ جائے، تو سرور کے باقی معمول کے کاموں کو بھی اسی جگہ رکھیں جہاں آپ انہیں دیکھ سکیں۔ آپریٹنگ سسٹم کی سیکیورٹی پیچز (security patches) کو unattended upgrades کے ذریعے ہینڈل کرنا چاہیے، نہ کہ ایسی cron لائن کے ذریعے جسے آپ خود مینٹین کرتے ہیں۔ WordPress پلگ ان اور تھیم کے اپ ڈیٹس کا معاملہ مختلف ہے: crontab میں wp plugin update --all کا استعمال کسی بھی وقت لائیو سائٹ کو خراب کر سکتا ہے، خاص طور پر رات کے 3 بجے جب کوئی اسے دیکھ نہ رہا ہو۔ لہذا، ایسے کام جان بوجھ کر کریں، یا انہیں پہلے staging مرحلے اور بیک اپ کے بعد چلائیں۔

FAQ

کیا WP-Cron کو غیر فعال کرنے سے شیڈول شدہ پوسٹس کی اشاعت رک جاتی ہے؟

نہیں، جب تک کہ کوئی اور چیز قطار (queue) کو چلاتی رہے۔ DISABLE_WP_CRON صرف پیج لوڈز کو قطار شروع کرنے سے روکتا ہے۔ ایونٹس بالکل پہلے کی طرح شیڈول ہوتے ہیں۔ 09:00 بجے کے لیے سیٹ کی گئی پوسٹ 09:00 بجے کے بعد پہلے کرون رن پر شائع ہوتی ہے، لہذا پانچ منٹ کا وقفہ اسے 09:05 تک شائع کر دیتا ہے۔ اگر آپ کانسٹنٹ سیٹ کر دیں اور کرون انٹری شامل نہ کریں، تو پوسٹ لسٹ میں Missed schedule کے نشان کے ساتھ پڑی رہے گی جب تک کہ کوئی چیز قطار کو نہ چلائے۔

ورڈپریس کرون جاب کس صارف کو چلانی چاہیے؟

وہ صارف جو ان فائلوں کا مالک ہو جنہیں PHP لکھتا ہے، جو کہ ڈیفالٹ Ubuntu انسٹالیشن پر www-data ہوتا ہے۔ stat -c '%U %G' /srv/www/example.com/wp-content/uploads کے ساتھ چیک کریں اور اس کا موازنہ اپنی PHP-FPM پول کنفیگریشن میں user = لائن سے کریں۔ جاب کو root کے طور پر چلانے سے WP-CLI ایک YIKES ایرر کے ساتھ رک جاتا ہے، اور --allow-root کے ذریعے اسے زبردستی چلانے سے wp-content کے اندر root کی ملکیت والی فائلیں رہ جاتی ہیں جنہیں ویب سرور بعد میں نہیں لکھ سکتا۔

سسٹم کرون کو کتنی بار ورڈپریس کرون چلانا چاہیے؟

ہر پانچ منٹ کا وقفہ زیادہ تر سائٹس کے لیے موزوں ہے۔ وقفے کو اس مختصر ترین شیڈول سے ملائیں جس پر آپ واقعی انحصار کرتے ہیں، اور اسے اس وقت سے کافی زیادہ رکھیں جو ایک بار چلنے میں لگتا ہے، جسے آپ WP-CLI کمانڈ کے سامنے time لگا کر ماپ سکتے ہیں۔ ایک منٹ کے وقفے مصروف سائٹ پر ایک دوسرے کے اوپر رن جمع کر دیتے ہیں جب تک کہ flock انہیں محفوظ نہ رکھے۔

WP-Cron کو غیر فعال کرنے کے بعد wp cron test کیوں ناکام ہو جاتا ہے؟

کیونکہ وہ کمانڈ وزیٹر کے ذریعے شروع ہونے والے اسپننگ (visitor triggered spawning) کو ٹیسٹ کرتی ہے، اور جب DISABLE_WP_CRON کو true پر سیٹ کیا جاتا ہے تو یہ ایرر رپورٹ کرتی ہے۔ اس طرح کنفیگر کیے گئے سرور پر یہ درست نتیجہ ہے۔ اس کے بجائے سسٹم کرون پاتھ چیک کریں: /var/log/wp-cron/example.log پڑھیں، یا wp cron event schedule کے ساتھ ایک مارکر ایونٹ شیڈول کریں اور تصدیق کریں کہ اگلی بار چلنے کے بعد یہ wp cron event list سے غائب ہو گیا ہے۔

کیا مجھے WP-CLI کی ضرورت ہے، یا wp-cron.php پر curl کافی ہے؟

Curl کام کرتا ہے، اور جب آپ WP-CLI انسٹال نہیں کر سکتے تو یہ درست جواب ہے۔ یہ سست ہے، کیونکہ یہ ویب سرور کے ذریعے ورڈپریس کو لوڈ کرتا ہے، اور یہ ریکویسٹ ٹائم آؤٹ کی وجہ سے محدود ہے۔ WP-CLI ایونٹس کو کمانڈ لائن PHP پروسیس میں بغیر کسی ویب ٹائم آؤٹ کے چلاتا ہے، اور ہر ایونٹ کے لیے اس کے دورانیے کے ساتھ ایک لائن پرنٹ کرتا ہے، لہذا لاگ آپ کو بالکل بتاتا ہے کہ کیا چلا اور کتنا وقت لگا۔