WP-CLI ile Toplu WordPress Güncellemesi: Çoklu Site Rehberi
Onlarca WordPress sitesini tek tek güncellemek, her sistem yöneticisinin korkulu rüyasıdır. Bir sitenin eklentisini güncellerken öbür sitenin temasını unutursun, üçüncü sitede PHP uyumsuzluğu çıkar ve sabah 09:00’daki toplantıdan önce her şey çökmüş olur. WP-CLI tam da bu kaosa düzen getirmek için var. Bu yazıda, çoklu WordPress sitelerini toplu olarak nasıl güncelleyeceğini, hangi senaryolarda ne yapman gerektiğini ve işleri nasıl otomatize edebileceğini adım adım ele alacağız.
WP-CLI Nedir ve Neden Toplu Güncelleme İçin İdealdir?
WP-CLI, WordPress’i komut satırından yönetmeni sağlayan resmi araçtır. Tarayıcı açmana, admin paneline girip tıklamanı gerektirmez. Bir script içine gömebildiğin, cron job’a bağlayabildiğin, SSH üzerinden uzaktan çalıştırabildiğin bir araçtır.
Toplu güncelleme söz konusu olduğunda WP-CLI’nin avantajları şunlardır:
- Betik yazılabilirlik: Bash scriptleri içinde kullanılabilir, döngülere sokulabilir
- Non-interaktif çalışma: Onay beklemeden, GUI olmadan çalışır
- Çıktı yönetimi: JSON, CSV veya düz metin formatında çıktı üretir, log tutmak kolaylaşır
- Uzak erişim: SSH alias ile uzak sunuculara bağlanıp yerel gibi komut çalıştırırsın
- Geri alınabilirlik: Güncelleme öncesi veritabanı yedeği, güncelleme sonrası doğrulama adımlarını script içine ekleyebilirsin
Ortamı Hazırlamak
Başlamadan önce birkaç şeyin yerli yerinde olması gerekiyor.
WP-CLI Kurulumu
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
wp --info
Eğer sunucuda birden fazla PHP sürümü varsa, WP-CLI’nin hangi PHP ile çalıştığını kontrol etmek önemlidir:
wp --info | grep "PHP binary"
# Farklı bir PHP sürümü kullanmak için:
/usr/bin/php8.1 /usr/local/bin/wp --info
Site Listeni Oluşturmak
Yönettiğin sitelerin bir listesini tutman işleri çok kolaylaştırır. Ben genellikle şu yapıyı kullanırım:
# /etc/wp-sites.conf dosyası
# Format: site_adi:webroot_yolu:linux_kullanici
site1:/var/www/site1.com/public_html:www-data
site2:/var/www/site2.com/public_html:www-data
site3:/var/www/blog.sirket.com/public_html:blog_user
site4:/home/musteri1/public_html:musteri1
Bu dosyayı daha sonra tüm scriptlerde okuyacağız. Hassas bilgi içermediği için erişim hakları konusunda çok da paranoyak olmana gerek yok ama yine de:
chmod 640 /etc/wp-sites.conf
chown root:www-data /etc/wp-sites.conf
Temel WP-CLI Güncelleme Komutları
Toplu güncellemeye geçmeden önce temel komutları iyi bilmek lazım.
WordPress Core Güncelleme
# Tek bir site için
wp --path=/var/www/site1.com/public_html core update
# Belirli bir sürüme güncelleme
wp --path=/var/www/site1.com/public_html core update --version=6.4.2
# Güncelleme var mı diye kontrol et, güncelleme yapma
wp --path=/var/www/site1.com/public_html core check-update
# Minor update'leri otomatik uygula, major'ları atlat
wp --path=/var/www/site1.com/public_html core update --minor
Eklenti Güncelleme Komutları
# Tüm eklentileri güncelle
wp --path=/var/www/site1.com/public_html plugin update --all
# Sadece belirli eklentileri güncelle
wp --path=/var/www/site1.com/public_html plugin update woocommerce yoast-seo
# Güncellenebilir eklentileri listele
wp --path=/var/www/site1.com/public_html plugin list --update=available --fields=name,version,update_version
# Belirli bir eklentiyi belirli sürüme güncelle
wp --path=/var/www/site1.com/public_html plugin update woocommerce --version=8.3.1
Tema Güncelleme Komutları
# Tüm temaları güncelle
wp --path=/var/www/site1.com/public_html theme update --all
# Güncelleme gereken temaları listele
wp --path=/var/www/site1.com/public_html theme list --update=available
Gerçek Dünya Senaryosu 1: Basit Toplu Güncelleme Scripti
En basit haliyle, tüm sitelerini güncelleyen bir script yaz ve bunu haftada bir çalıştır. İşte başlangıç noktası:
#!/bin/bash
# wp-bulk-update.sh
# Tüm WordPress sitelerini günceller, log tutar
SITES_CONFIG="/etc/wp-sites.conf"
LOG_FILE="/var/log/wp-updates/update-$(date +%Y%m%d).log"
WP_BIN="/usr/local/bin/wp"
MAIL_RECIPIENT="[email protected]"
mkdir -p /var/log/wp-updates
echo "=== WordPress Toplu Güncelleme Başladı: $(date) ===" | tee -a "$LOG_FILE"
while IFS=: read -r site_name site_path site_user; do
# Yorum satırlarını ve boş satırları atla
[[ "$site_name" =~ ^#.*$ ]] && continue
[[ -z "$site_name" ]] && continue
echo "" | tee -a "$LOG_FILE"
echo "--- Site: $site_name ($site_path) ---" | tee -a "$LOG_FILE"
# WordPress kurulumu var mı kontrol et
if ! sudo -u "$site_user" "$WP_BIN" --path="$site_path" core is-installed 2>/dev/null; then
echo "[HATA] $site_name: WordPress kurulu değil veya erişilemiyor" | tee -a "$LOG_FILE"
continue
fi
# Veritabanı yedeği al
BACKUP_DIR="/var/backups/wp-pre-update/$site_name"
mkdir -p "$BACKUP_DIR"
sudo -u "$site_user" "$WP_BIN" --path="$site_path" db export
"$BACKUP_DIR/db-$(date +%Y%m%d-%H%M%S).sql" 2>&1 | tee -a "$LOG_FILE"
# Core güncelle
echo "[INFO] Core güncelleniyor..." | tee -a "$LOG_FILE"
sudo -u "$site_user" "$WP_BIN" --path="$site_path" core update 2>&1 | tee -a "$LOG_FILE"
# Veritabanı şemasını güncelle
sudo -u "$site_user" "$WP_BIN" --path="$site_path" core update-db 2>&1 | tee -a "$LOG_FILE"
# Eklentileri güncelle
echo "[INFO] Eklentiler güncelleniyor..." | tee -a "$LOG_FILE"
sudo -u "$site_user" "$WP_BIN" --path="$site_path" plugin update --all 2>&1 | tee -a "$LOG_FILE"
# Temaları güncelle
echo "[INFO] Temalar güncelleniyor..." | tee -a "$LOG_FILE"
sudo -u "$site_user" "$WP_BIN" --path="$site_path" theme update --all 2>&1 | tee -a "$LOG_FILE"
echo "[OK] $site_name güncelleme tamamlandı" | tee -a "$LOG_FILE"
done < "$SITES_CONFIG"
echo "" | tee -a "$LOG_FILE"
echo "=== Güncelleme Tamamlandı: $(date) ===" | tee -a "$LOG_FILE"
# Özet maili gönder
mail -s "WordPress Toplu Güncelleme Raporu - $(date +%Y-%m-%d)"
"$MAIL_RECIPIENT" < "$LOG_FILE"
Bu scripti cron’a eklemek için:
chmod +x /usr/local/bin/wp-bulk-update.sh
# Her Salı sabahı 03:00'da çalıştır
echo "0 3 * * 2 root /usr/local/bin/wp-bulk-update.sh" >> /etc/crontab
Gerçek Dünya Senaryosu 2: Maintenance Mode ile Güvenli Güncelleme
Canlı sitede güncelleme yaparken ziyaretçilerin yarım kalmış bir sayfayla karşılaşmasını istemezsin. WP-CLI’nin maintenance mode özelliği burada devreye girer:
#!/bin/bash
# wp-safe-update.sh - Maintenance mode ile güvenli güncelleme
SITE_PATH="/var/www/site1.com/public_html"
SITE_USER="www-data"
WP="sudo -u $SITE_USER /usr/local/bin/wp --path=$SITE_PATH"
# Maintenance modunu aç
$WP maintenance-mode activate
echo "Maintenance mode açıldı, ziyaretçiler 503 alacak"
# 2 saniye bekle, mod kesinleşsin
sleep 2
# Cache'i temizle (varsa)
$WP cache flush 2>/dev/null || true
# Güncelleme yap
$WP core update && $WP core update-db
$WP plugin update --all
$WP theme update --all
# Güncelleme sonrası doğrulama
echo "Core sürümü: $($WP core version)"
echo "Eklenti durumu:"
$WP plugin list --status=active --fields=name,version
# Maintenance modunu kapat
$WP maintenance-mode deactivate
echo "Maintenance mode kapatıldı, site tekrar erişilebilir"
# Object cache'i yenile
$WP cache flush 2>/dev/null || true
Gerçek Dünya Senaryosu 3: Seçici Güncelleme – Risk Sınıflandırması
Her güncellemeyi körü körüne uygulamak bazen felaket olabilir. WooCommerce major sürüm geçişini müşteri habersizken yapamazsın. Bu senaryo için güncelleme tipine göre akıllı bir yaklaşım gerekir:
#!/bin/bash
# wp-smart-update.sh - Risk bazlı güncelleme
SITE_PATH=$1
SITE_USER=$2
WP="sudo -u $SITE_USER /usr/local/bin/wp --path=$SITE_PATH"
if [[ -z "$SITE_PATH" || -z "$SITE_USER" ]]; then
echo "Kullanım: $0 /site/yolu linux_kullanici"
exit 1
fi
# Riskli eklentiler listesi - major update uyarısı verir
RISKY_PLUGINS="woocommerce elementor elementor-pro wpml"
echo "=== Güncelleme Analizi ==="
# Güncellenebilir eklentileri JSON formatında al
UPDATES=$($WP plugin list --update=available --format=json 2>/dev/null)
if [[ -z "$UPDATES" || "$UPDATES" == "[]" ]]; then
echo "Güncellenecek eklenti yok."
else
echo "$UPDATES" | python3 -c "
import sys, json
data = json.load(sys.stdin)
for p in data:
name = p['name']
current = p['version']
new = p.get('update_version', 'bilinmiyor')
# Major versiyon kontrolü
curr_major = current.split('.')[0] if current else '0'
new_major = new.split('.')[0] if new else '0'
if curr_major != new_major:
print(f'[MAJOR] {name}: {current} -> {new} *** DİKKAT: Major güncelleme!')
else:
print(f'[minor] {name}: {current} -> {new}')
"
fi
# Riskli eklentileri major update'ten koru
for PLUGIN in $RISKY_PLUGINS; do
CURRENT=$($WP plugin get "$PLUGIN" --field=version 2>/dev/null)
if [[ -n "$CURRENT" ]]; then
AVAILABLE=$($WP plugin list --name="$PLUGIN" --fields=update_version --format=csv 2>/dev/null | tail -1)
CURR_MAJOR=$(echo "$CURRENT" | cut -d. -f1)
NEW_MAJOR=$(echo "$AVAILABLE" | cut -d. -f1)
if [[ "$CURR_MAJOR" != "$NEW_MAJOR" && -n "$NEW_MAJOR" ]]; then
echo "[UYARI] $PLUGIN major güncelleme ($CURRENT -> $AVAILABLE) - atlanıyor, manuel onay gerekli"
# Bu eklentiyi exclude listesine ekle
EXCLUDE_LIST="$EXCLUDE_LIST --exclude=$PLUGIN"
fi
fi
done
# Güvenli eklentileri güncelle
echo ""
echo "=== Güncelleme Başlıyor ==="
$WP plugin update --all $EXCLUDE_LIST
SSH Alias ile Uzak Sunucu Yönetimi
Birden fazla fiziksel sunucuda WordPress sitelerin varsa, WP-CLI’nin SSH desteği hayat kurtarır. Yerel makinenden uzak sunucuya bağlanıp WP-CLI komutları çalıştırabilirsin.
SSH alias tanımlamak için ~/.ssh/config dosyasına:
Host wp-server1
HostName 192.168.1.100
User deploy
IdentityFile ~/.ssh/id_rsa_servers
Host wp-server2
HostName 203.0.113.50
User ubuntu
IdentityFile ~/.ssh/id_rsa_prod
WP-CLI SSH alias için ~/.wp-cli/config.yml dosyası:
# WP-CLI SSH alias tanımları
@prod-site1:
ssh: wp-server1
path: /var/www/site1.com/public_html
@prod-site2:
ssh: wp-server2
path: /var/www/site2.com/public_html
@staging:
ssh: wp-server1
path: /var/www/staging.site1.com/public_html
Artık uzak siteleri yerel gibi yönetebilirsin:
# Uzak sitede güncelleme
wp @prod-site1 plugin update --all
wp @prod-site2 core update
# Tüm alias'lara aynı anda komut gönder
wp @prod-site1 @prod-site2 core check-update
# Sürüm bilgilerini karşılaştır
for alias in @prod-site1 @prod-site2 @staging; do
echo "$alias:"
wp "$alias" core version
wp "$alias" plugin list --update=available --fields=name --format=count
done
Güncelleme Sonrası Doğrulama
Güncelleme yaptın, iyi. Peki her şey yolunda mı? Bunu da WP-CLI ile kontrol edebilirsin:
#!/bin/bash
# wp-post-update-check.sh - Güncelleme sonrası doğrulama
SITE_PATH=$1
WP="sudo -u www-data /usr/local/bin/wp --path=$SITE_PATH"
ERRORS=0
echo "=== Güncelleme Sonrası Doğrulama ==="
# WordPress dosya bütünlüğü kontrolü
echo "[1/5] Core dosya bütünlüğü..."
if ! $WP core verify-checksums 2>&1; then
echo "[HATA] Core dosyalarında tutarsızlık var!"
ERRORS=$((ERRORS + 1))
fi
# Aktif eklentilerin hepsinin yüklenip yüklenmediğini kontrol et
echo "[2/5] Eklenti yükleme kontrolü..."
INACTIVE_AFTER=$($WP plugin list --status=inactive --fields=name,status --format=csv 2>/dev/null | wc -l)
echo "Pasif eklenti sayısı: $((INACTIVE_AFTER - 1))"
# PHP hata logunu kontrol et
echo "[3/5] PHP hata logu taraması (son 50 satır)..."
if [[ -f "$SITE_PATH/wp-content/debug.log" ]]; then
FATAL_COUNT=$(tail -50 "$SITE_PATH/wp-content/debug.log" | grep -c "Fatal error" || true)
if [[ "$FATAL_COUNT" -gt 0 ]]; then
echo "[HATA] debug.log içinde $FATAL_COUNT adet Fatal error var!"
tail -20 "$SITE_PATH/wp-content/debug.log" | grep "Fatal error"
ERRORS=$((ERRORS + 1))
fi
fi
# Veritabanı durumu
echo "[4/5] Veritabanı kontrolü..."
$WP db check 2>&1 | grep -E "(Error|OK)" | head -20
# Cron sağlığı
echo "[5/5] WP Cron kontrolü..."
$WP cron event list --fields=hook,next_run --format=table 2>/dev/null | head -10
echo ""
if [[ "$ERRORS" -eq 0 ]]; then
echo "Tüm kontroller geçti. Site sağlıklı görünüyor."
else
echo "[UYARI] $ERRORS adet sorun tespit edildi! Loglara bak."
exit 1
fi
WordPress Multisite (Ağ) Güncellemesi
Eğer WordPress Multisite (ağ kurulumu) kullanıyorsan, güncelleme biraz farklı çalışır. Bir kurulumda onlarca alt site olabilir ve eklentiler ağ genelinde aktive edilebilir:
# Multisite kurulumda tüm siteleri listele
wp --path=/var/www/network.com/public_html site list --fields=blog_id,url,archived
# Core güncelle (multisite için aynı komut çalışır)
wp --path=/var/www/network.com/public_html core update
# Ağ genelinde aktif eklentileri listele
wp --path=/var/www/network.com/public_html plugin list --network --fields=name,version,update_version
# Tüm eklentileri güncelle
wp --path=/var/www/network.com/public_html plugin update --all --network
# Her alt site için cache temizle
wp --path=/var/www/network.com/public_html site list --field=blog_id | while read blog_id; do
wp --path=/var/www/network.com/public_html --url=$(wp --path=/var/www/network.com/public_html site url "$blog_id") cache flush
echo "Blog $blog_id cache temizlendi"
done
Pratik İpuçları ve Sık Yapılan Hatalar
Yetki sorunları: WP-CLI’yi her zaman site dosyalarının sahibi olan kullanıcı ile çalıştır. Root olarak çalıştırmak dosya izinlerini bozabilir. sudo -u www-data wp ... kullanımını alışkanlık haline getir.
--allow-root tuzağı: Root olarak çalışmak zorunda kaldığında --allow-root flag’ini eklemen gerekir ama bu durumda oluşan dosyalar root’a ait olur ve web sunucusu okuyamaz.
Güncelleme öncesi yedek almayı unutma: Script içinde wp db export adımını asla atlatma. 5 dakika alan bu adım, 5 saatlik kurtarma işinden seni kurtarabilir.
--skip-themes ve --skip-plugins parametreleri: Bazen bozuk bir tema veya eklenti WP-CLI’nin çalışmasını engeller. Bu durumlarda:
wp --path=/var/www/site/public_html --skip-themes --skip-plugins core update
Log rotasyonu: Update logları zamanla büyür. /etc/logrotate.d/wp-updates dosyasına şunu ekle:
/var/log/wp-updates/*.log {
weekly
rotate 12
compress
missingok
notifempty
}
Timeout sorunları: Büyük WooCommerce sitelerinde güncelleme sırasında veritabanı migrasyonları uzun sürebilir. PHP’nin max_execution_time değerini geçici olarak artır veya WP-CLI’yi şu şekilde çalıştır:
WP_CLI_PHP_ARGS="-d max_execution_time=300" wp plugin update woocommerce
Cron ile Tam Otomatizasyon
Tüm bunları bir araya getirince, haftalık otomatik güncelleme sistemi şu şekilde görünür:
- Pazar 02:00: Tüm siteler için veritabanı yedeği al
- Salı 03:00: Core ve eklenti güncellemelerini uygula
- Salı 03:30: Doğrulama scriptini çalıştır
- Salı 04:00: Sonuç raporunu mail olarak gönder
Crontab için:
0 2 * * 0 root /usr/local/bin/wp-backup-all.sh
0 3 * * 2 root /usr/local/bin/wp-bulk-update.sh
30 3 * * 2 root /usr/local/bin/wp-post-update-check.sh >> /var/log/wp-updates/verify.log
Sonuç
WP-CLI ile toplu WordPress güncellemesi, başta karmaşık görünse de bir kez kurduğun sistem sayesinde aylarca ellini taşın altına koymadan her şeyi otomatik yönetebilirsin. Önemli olan birkaç temel ilkeyi unutmamak: güncelleme öncesi yedek al, riskli eklentileri ayrı değerlendir, güncelleme sonrası doğrulama yap ve tüm bu adımları logla.
Anlattığım scriptleri kendi ortamına göre uyarlamalısın. Her sunucu konfigürasyonu, her site yapısı biraz farklıdır. Ama temel akış her zaman aynıdır: kontrol et, yedekle, güncelle, doğrula, raporla.
Eğer yönettiğin site sayısı 10’u geçtiyse WP-CLI olmadan bu işi yapmaya çalışmak gereksiz zaman kaybıdır. 20 sitenin eklentilerini admin panelinden tıklayarak güncellemek için harcayacağın sürede bu otomasyonu kurabilir ve bir daha bu işe vakit ayırmazsın.
