backup زمانی مفید است که بازیابی آن کار کند. امشب database، uploads، کد و تنظیمات را به یک مجموعهٔ سازگار تبدیل می‌کنیم و اجرای زمان‌بندی‌شدهٔ WordPress را از ترافیک سایت جدا می‌کنیم.

این جلسه بخشی از دورهٔ انجین‌اکس در ۵۰ شب است. قرارداد آزمایشگاه، مسیرها و روال اعمال تغییر در راهنمای دوره آمده است.

محیط: WordPress شب ۳۲، database محلی nginx_wp و کاربر wpapp؛ برای قطع نوشتن، پنجرهٔ نگه‌داری و Snapshot داری. فضای backup خارج public است.

تهیه و بازیابی#

برای VM آزمایشگاه، سایت را موقتاً در نگه‌داری بگذار و cron، upload و نوشتن مدیریتی را متوقف کن. در shell ریشه با umask محدود:

sudo -i
umask 077
mkdir -p /var/backups/nginx-wordpress
mariadb-dump --single-transaction --routines --triggers nginx_wp > /var/backups/nginx-wordpress/database.sql
tar --acls --xattrs --selinux -czf /var/backups/nginx-wordpress/files.tar.gz \
  /var/www/nginx-wordpress /etc/nginx
sha256sum /var/backups/nginx-wordpress/database.sql /var/backups/nginx-wordpress/files.tar.gz \
  > /var/backups/nginx-wordpress/SHA256SUMS
exit

--single-transaction برای جدول‌های transactional مناسب است؛ با تغییر schema یا موتور دیگر تضمین سازگاری کامل ندارد. این archive راز و کلید خصوصی دارد: دسترسی محدود، نسخهٔ رمزگذاری‌شده خارج VM و سیاست retention لازم است. فایل قبلی را در backup بعدی overwrite نکن؛ برای هر اجرا پوشهٔ timestamp مستقل بساز.

در clone قطع از شبکهٔ اصلی، فایل‌ها و database را برگردان. نسخهٔ PHP، WordPress و افزونه‌ها را ثبت کن، مالکیت و SELinux را بازیابی کن و nginx -t بگیر. ورود مدیر، permalink، تصویر و یک رکورد تازهٔ database را با همین URL آزمایشگاه بررسی کن. نصب یک WordPress خالی، restore موفق محسوب نمی‌شود.

اجرای cron با systemd#

پیش از افزودن define('DISABLE_WP_CRON', true); در wp-config، سرویس زیر را آزمایش کن. در /etc/systemd/system/nginx-wordpress-cron.service:

[Unit]
Description=WordPress scheduled tasks for Nginx lab
After=network.target mariadb.service

[Service]
Type=oneshot
User=wpapp
Group=wpapp
WorkingDirectory=/var/www/nginx-wordpress/public
ExecStart=/usr/bin/php /var/www/nginx-wordpress/public/wp-cron.php
NoNewPrivileges=true
PrivateTmp=true

در Debian/Ubuntu با چند نسخهٔ PHP، ExecStart را صریحاً به /usr/bin/php8.4 یا /usr/bin/php8.3 مطابق FPM تغییر بده. /etc/systemd/system/nginx-wordpress-cron.timer:

[Unit]
Description=Run WordPress scheduled tasks every five minutes

[Timer]
OnBootSec=2min
OnUnitActiveSec=5min
Persistent=true

[Install]
WantedBy=timers.target
sudo systemd-analyze verify /etc/systemd/system/nginx-wordpress-cron.service /etc/systemd/system/nginx-wordpress-cron.timer
sudo systemctl daemon-reload
sudo systemctl start nginx-wordpress-cron.service
sudo journalctl -u nginx-wordpress-cron.service -n 30 --no-pager
sudo systemctl enable --now nginx-wordpress-cron.timer
systemctl list-timers nginx-wordpress-cron.timer

Persistent برای timerهای تقویمی معنای catch-up دارد؛ این timer monotonic تضمین اجرای همهٔ رویدادهای هنگام خاموشی نیست. افزونهٔ نیازمند درخواست HTTP/HTTPS، محیط CLI یا امکان نوشتن اضافی را جدا بررسی کن. صفر بودن exit code PHP به‌تنهایی اثبات اجرای همهٔ jobها نیست؛ یک کار زمان‌بندی‌شدهٔ آزمایشی و نتیجه‌اش را ببین.

به‌روزرسانی#

در staging با backup، artifact جدید را دریافت و checksum هسته را بررسی کن. به‌روزرسانی را با حساب استقرار اجرا کن؛ DISALLOW_FILE_MODS در مدل ما dashboard را می‌بندد و به فرایند استقرار مجوز نمی‌دهد. برای WP-CLI ابتدا اصالت خود ابزار و نیاز به بارگذاری plugin/config را بررسی کن؛ فرمان‌ها را با هویت لازم اجرا کن و رازها را چاپ نکن. بعد owner/mode کد را برگردان، cache را پاک/invalid کن و migration database را آزمایش کن.

بازگشت: اگر schema عوض شده، بازگرداندن کد به‌تنهایی کافی نیست؛ restore سازگار کد و database لازم است. برای برگرداندن cron داخلی، ابتدا timer را stop/disable و سپس DISABLE_WP_CRON را بردار.

منبع: backup WordPress ، زمان‌بندی wp-cron ، سخت‌سازی WordPress .