Teknoloji

cPanel ve DirectAdmin Cron: Yedek ve Bakım Rehberi

Cron job ile tekrar eden işleri akıllıca devretmek

Web siteniz büyüdükçe yapılması gereken işler de artıyor: dosya ve veritabanı yedekleri, log temizliği, rapor üretimi, önbellek temizleme, WordPress veya Laravel görevlerinin tetiklenmesi… Bunların hepsini elle yapmak, iş yükü arttıkça zorlaşıyor. İşte bu noktada cron job devreye giriyor ve sunucunuza “şu işi şu saatte, her gün/hafta/ay kendin yap” deme şansı veriyor.

Paylaşımlı hosting veya VPS/dedicated sunucu seçerken, tekrarlı görevler için gereken zamanlama imkânlarını değerlendirmek gerekir. cPanel veya DirectAdmin kullanılan bir ortamda, cron arayüzüne erişim ve izin verilen çalışma sıklığı planlama açısından önemlidir. Yanlış ayarlanan bir cron job hem performansı etkileyebiliyor hem de yedeklerin eksik veya bozuk olmasına neden olabiliyor. Bu yazıda, pratik örneklerle cPanel ve DirectAdmin’de cron job kullanımını, özellikle yedekleme, rapor ve bakım görevlerini adım adım anlatacağız.

Eğer daha önce cron kullanmadıysanız, gözünüz korkmasın. Mantığı bir kez oturttuktan sonra, uygun scriptlerle web sitenizin arka plandaki rutinlerini zamanlayabilirsiniz. Aşağıdaki örnekler, yedekleme, raporlama ve bakım görevlerini güvenlik ve performans noktalarıyla birlikte ele alıyor.

Cron job nedir ve temel mantığı nasıl çalışır?

Cron, Linux/Unix tabanlı sistemlerde zamanlanmış görevleri çalıştıran bir servistir. Kullanıcı bazında crontab dosyaları vardır ve bu dosyalarda “hangi komutun, ne zaman” çalışacağını tanımlarsınız. cPanel ve DirectAdmin, bu işi komut satırına inmeden, web arayüzü üzerinden yapmanızı sağlar.

Bir cron satırı kabaca şöyle görünür:

*/5 * * * * /usr/bin/php /home/kullanici/public_html/script.php >/dev/null 2>&1

Bu tam kullanıcı crontab satırı, PHP dosyasını dakikanın 0, 5, 10… değerlerinde çalıştırır ve hem standart çıktıyı hem hataları atar. Panelde ilk beş alanı zamanlamaya, yalnızca komut kısmını Command alanına girin. İlk denemelerde çıktıyı kaydedin; /dev/null başarı takibi değildir. İş atanan kullanıcıyla çalışır; PHP yolu, dosya izinleri ve panelin izin verdiği en kısa aralık doğrulanmalıdır.

  • Dakika: 0–59
  • Saat: 0–23
  • Ayın günü: 1–31
  • Ay: 1–12
  • Haftanın günü: 0–7 (0 ve 7 Pazar)

Örneğin:

  • 0 3 * * * → Her gün saat 03:00’de
  • 0 2 * * 1 → Her Pazartesi 02:00’de
  • */15 * * * * → Her 15 dakikada bir

Saatler cron hizmetinin veya destekleniyorsa cron tablosunun zaman dilimine göredir; UTC dosya adı kullanmak zamanlamayı UTC yapmaz. Yaz/kış saati davranışı cron uygulamasına göre kontrol edilmelidir. Ayın günü ve haftanın günü birlikte kısıtlanırsa yaygın Vixie/Cronie sözdiziminde koşullardan birinin eşleşmesi yeterlidir. */5, önceki iş bittikten beş dakika sonra demek değildir.

VPS veya dedicated sunucu tarafında, cron alternatifi olarak systemd timer gibi daha modern mekanizmalar da kullanmak mümkün. Bu konuyu daha derine inmek isterseniz, cron mu systemd timer mı rehberimizde iki yaklaşımı teknik açıdan karşılaştırıyoruz.

cPanel’de cron job arayüzü ve pratik kullanım

cPanel’de cron job oluşturmak için genellikle “Cron Jobs” menüsünü kullanırsınız. Arayüz, komut satırında yazmanız gereken crontab satırını sizin yerinize oluşturur.

cPanel’de zamanlama alanlarını doğru doldurmak

cPanel, işinizi kolaylaştırmak için bazı hazır zamanlama seçenekleri sunar:

  • Once Per Minute
  • Once Per Hour
  • Once Per Day
  • Once Per Week
  • Once Per Month

Hazır seçenekler ilgili zaman alanlarını doldurur; arayüzdeki sonuçları kontrol edin. Örneğin günlük 02:30 için dakika 30, saat 2 ve kalan üç alan yıldızdır. Panel menüsü veya preset adları sürüm/temaya göre değişebilir; @daily gibi bir crontab kısayolunun panel komut alanında desteklendiğini varsaymayın.

cPanel’de PHP scriptlerini cron ile çalıştırmak

PHP yorumlayıcısının doğru CLI sürümünü seçin. Yol bazı kurulumlarda /usr/bin/php, cPanel EasyApache ortamında sürüme özel /opt/cpanel/ea-php82/root/usr/bin/php olabilir. Web PHP sürümünü seçmek CLI yolunu kendiliğinden doğrulamaz; kurulu sürümün yolunu ve eklentilerini sunucu yöneticisinden veya hosting sağlayıcısından teyit edin.

Örnek bir tam crontab satırı aşağıdadır. cPanel’de zamanlamayı ayrı alanlara girin; komut alanına yalnızca PHP yolu ile başlayan kısmı yazın:

*/10 * * * * /usr/bin/php /home/kullanici/public_html/cron/tetikleyici.php >> /home/kullanici/logs/app-cron.log 2>&1

Burada:

  • */10 * * * *: Her on dakikalık saat alanında tetikleme.
  • /usr/bin/php: Kurulu uygulama için doğrulanması gereken CLI yorumlayıcı yolu.
  • /home/kullanici/public_html/cron/tetikleyici.php: Mevcut örnek script; yalnızca cron içinse web kökü dışına taşıyın.
  • >> ... 2>&1: Standart çıktı ve hataları günlüğe ekler. Önce hesap sahibine ait logs dizinini oluşturun ve log rotasyonu uygulayın.

PHP’de -q CGI HTTP başlıklarıyla ilgilidir; CLI uygulama hatalarını sessize alan bir seçenek değildir.

E-posta bildirimlerini yönetmek

cPanel’de her cron job varsayılan olarak çıktısını e-posta ile gönderebilir. Bu, özellikle ilk kurulum aşamasında hata yakalamak için çok faydalıdır. Fakat sık çalışan görevlerin çıktısını e-postayla almak istemiyorsanız, aşağıdaki yönlendirme standart çıktıyı ve hata çıktısını atar:

>/dev/null 2>&1

İlk kurulumda bu yönlendirmeyi kaldırarak çıktıları inceleyin. Özellikle yedekleme görevlerinde, sonraki hataları başka bir günlük veya izleme mekanizmasıyla takip etmeden hata çıktısını atmayın.

DirectAdmin’de cron job arayüzü

Panelde Cron Jobs bölümünü arama veya Advanced Features/Tools menüsünden bulun; menü adı sürüm ve temaya göre değişebilir. Temel alanlar zamanlama ve çalıştırılacak komuttur.

DirectAdmin cron ekranında, zamanlama alanları ve komut alanı net şekilde ayrılmıştır. Örneğin, günlük 03:15 yedeği için şu değerleri girebilirsiniz:

  • Minute: 15
  • Hour: 3
  • Day of Month: *
  • Month: *
  • Day of Week: *
  • Command: Aşağıdaki PHP komutu

Zamanlamayı yukarıdaki alanlara girin. Aşağıdaki komut mevcut bir PHP scriptini gösterir; dosya adının yedek çağrıştırması çalışan bir yedekleme uygulaması sağlamaz. Doğru CLI PHP yolunu ve scripti seçin, günlük dizinini önceden oluşturun. Aşağıdaki bölüm bağımsız dosya ve veritabanı yedek scriptlerini verir.

/usr/bin/php /home/kullanici/domains/site.com/public_html/cron/gece-yedek.php >> /home/kullanici/logs/night-job.log 2>&1

DirectAdmin’de de komut sonundaki yönlendirme, standart çıktının ve hata çıktısının nereye gideceğini belirler. Yönlendirilmemiş çıktının e-postayla gönderilmesi ise cron ve posta ayarlarına da bağlıdır.

Yedekleme işlerini cron job ile otomatikleştirmek

Cron job, yedek almayı unutma riskini azaltır. Ancak otomatik zamanlama, yedeğin eksiksiz veya geri yüklenebilir olduğunu tek başına garanti etmez. Görev sonuçlarını izlemek ve geri yükleme denemeleri yapmak da yedekleme sürecinin parçasıdır.

Yedekleme stratejisine yaklaşımınızı planlarken, mutlaka 3-2-1 yedekleme stratejisi rehberimize göz atmanızı tavsiye ederim. Orada genel stratejiyi anlatıyoruz, burada ise cron tarafındaki somut örneklere odaklanacağız.

public_html dizini dosya yedeği (tar.gz)

Aşağıdaki Bash örneği yalnızca public_html dosyalarını alır; tam hosting hesabı, e-posta veya veritabanı yedeği değildir. Örneklerin tamamında USERNAME, DBNAME ve BACKUP_USER yer tutucularını değiştirin. Ayrıca source_dir değerini sitenin gerçek dosya köküne uyarlayın: DirectAdmin’de bu yol /home/USERNAME/domains/site.com/public_html olabilir; alan adını ve dizini doğrulayın. Bash, GNU tar/coreutils/findutils, gzip ve util-linux flock yollarını doğrulayın. Script, log, kimlik bilgisi ve yedek dizinleri web kökü dışında, cron hesabına ait olmalıdır. İzinleri mevcut dosyalarda da kontrol edin; shared hosting araç veya sıklık limitleri sağlayıcıya bağlıdır.

umask 077
mkdir -p /home/USERNAME/scripts /home/USERNAME/logs \
    /home/USERNAME/.config /home/USERNAME/backups/mysql \
    /home/USERNAME/backups/files
chmod 700 /home/USERNAME/scripts /home/USERNAME/logs \
    /home/USERNAME/.config /home/USERNAME/backups \
    /home/USERNAME/backups/mysql /home/USERNAME/backups/files
# After creating the credential file with an editor:
chmod 600 /home/USERNAME/.config/backup-client.cnf

Kimlik bilgisi dosyasını aşağıdaki veritabanı bölümünde gösterildiği gibi editörle oluşturduktan sonra izin satırını çalıştırın. Dosya yedeğini /home/USERNAME/scripts/files-backup.sh adıyla kaydedin ve sadece hesap sahibine çalıştırma izni verin:

#!/bin/bash
set -euo pipefail
umask 077

source_dir=/home/USERNAME/public_html
backup_dir=/home/USERNAME/backups/files
test -d "$source_dir"
test -d "$backup_dir"
exec 9>"$backup_dir/.files-backup.lock"
/usr/bin/flock -n 9 || { echo "Backup already running" >&2; exit 75; }
work=$(/usr/bin/mktemp -d -- "$backup_dir/.files-work.XXXXXX")
cleanup() {
    /usr/bin/rm -f -- "$work/archive.tar.gz"
    /usr/bin/rmdir -- "$work"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM

/usr/bin/tar -czf "$work/archive.tar.gz" -C "$source_dir" .
/usr/bin/gzip -t -- "$work/archive.tar.gz"
/usr/bin/tar -tzf "$work/archive.tar.gz" > /dev/null
stamp=$(/usr/bin/date -u +%Y%m%dT%H%M%SZ)
final="$backup_dir/site-$stamp-${work##*.}.tar.gz"
/usr/bin/ln -T -- "$work/archive.tar.gz" "$final"
printf 'Backup completed: %s\n' "$final"
chmod 700 /home/USERNAME/scripts/files-backup.sh
# Full crontab entry; the panel Command field starts with /home/USERNAME:
0 2 * * * /home/USERNAME/scripts/files-backup.sh >> /home/USERNAME/logs/files-backup.log 2>&1

Script yeni ve özel bir geçici dizinde arşiv üretir, gzip bütünlüğünü ve tar listesinin okunabildiğini kontrol eder, sonra aynı dosya sisteminde hard link ile son adı oluşturur. ln -T var olan hedefi değiştirmez; UTC zaman damgası ve rastgele ek aynı gün tekrarlarında ayrı ad sağlar. Başarısızlıkta son arşiv yayımlanmaz, yalnızca scriptin kendi geçici dosyası temizlenir. Ani güç kaybı dayanıklılığı veya uygulama tutarlılığı bu mekanizmadan çıkmaz; değişen dosyalar/veritabanı için uygulamayla eşgüdümlü yedek veya uygun snapshot yöntemi gerekir.

Dikkat edilmesi gereken noktalar:

  • Alan ve erişim: Kaynakla geçici/tamamlanan yedekler için yeterli alan bırakın. Dizin 700 ve dosya 600 yalnızca sahibine erişim verir; 750 yetkili gruba da erişim açar.
  • Geri yükleme: Sıkıştırma kontrolü gerçek restore testi değildir. İzinleri, bağlantıları, yüklemeleri ve veritabanıyla tutarlılığı ayrı bir ortamda doğrulayın.
  • Kilit: flock çakışan çalışmayı reddeder. Kilit dosyasını çalışırken silmeyin; paylaşımlı/NFS dosya sisteminde kilit ve hard link davranışını önceden doğrulayın.

MySQL/MariaDB veritabanı yedeği

MySQL 8.4 için mysqldump, MariaDB 11.4 için mariadb-dump kullanın; kurulu istemcinin sürümünü ve seçeneklerini doğrulayın. Uzun komutu panel alanına yapıştırmak yerine Bash scripti çağırın. Doğrudan crontab komutunda yüzde işareti özel olduğundan date +\%F gerekir; aşağıdaki script dosyasının içindeki date +%Y%m%dT%H%M%SZ ise Bash tarafından işlendiği için bu cron kaçışını kullanmaz.

/home/USERNAME/scripts/db-backup.sh dosyası:

#!/bin/bash
set -euo pipefail
umask 077

backup_dir=/home/USERNAME/backups/mysql
credentials=/home/USERNAME/.config/backup-client.cnf
# MySQL 8.4 client; use the MariaDB alternative only with MariaDB.
dump_client=/usr/bin/mysqldump
dump_options=(--no-login-paths --set-gtid-purged=OFF)
# MariaDB 11.4 alternative (replace the two assignments above):
# dump_client=/usr/bin/mariadb-dump
# dump_options=()

test -d "$backup_dir"
test -r "$credentials"
exec 9>"$backup_dir/.db-backup.lock"
/usr/bin/flock -n 9 || { echo "Backup already running" >&2; exit 75; }
work=$(/usr/bin/mktemp -d -- "$backup_dir/.db-work.XXXXXX")
cleanup() {
    /usr/bin/rm -f -- "$work/archive.sql.gz"
    /usr/bin/rmdir -- "$work"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM

if ! "$dump_client" --defaults-file="$credentials" "${dump_options[@]}" \
    --single-transaction --quick --routines --events --triggers \
    --no-tablespaces DBNAME | /usr/bin/gzip -c > "$work/archive.sql.gz"; then
    echo "Database backup failed; no final archive published" >&2
    exit 1
fi
/usr/bin/gzip -t -- "$work/archive.sql.gz"
stamp=$(/usr/bin/date -u +%Y%m%dT%H%M%SZ)
final="$backup_dir/DBNAME-$stamp-${work##*.}.sql.gz"
# Same-filesystem hard link: fail if the destination already exists.
/usr/bin/ln -T -- "$work/archive.sql.gz" "$final"
printf 'Backup completed: %s\n' "$final"
chmod 700 /home/USERNAME/scripts/db-backup.sh
30 2 * * * /home/USERNAME/scripts/db-backup.sh >> /home/USERNAME/logs/db-backup.log 2>&1

Burada:

  • Hata denetimi: Bash pipefail ile dump veya gzip hatası tüm borunun başarısız olmasıdır; yalnızca set -e yeterli değildir. Hata metni arşive yazılmaz.
  • Kapsam: Tek veritabanı, tablolar, view/trigger/routine/event nesneleri; kullanıcılar, grant’ler ve tam sunucu yapılandırması ayrıca ele alınır.
  • Tutarlılık: single-transaction InnoDB için tutarlı okuma sağlar. MyISAM/MEMORY tabloları ve eşzamanlı DDL aynı güvenceye sahip değildir; yedek boyunca şema değişimini engelleyin.
  • İzinler: Hesaba seçilen nesneleri okuyacak gereken yetkileri verin; eksik yetkide başarısız dökümü kullanmayın. no-tablespaces tablespace oluşturma tanımlarını atlar. MySQL set-gtid-purged=OFF, GTID geçmişini dışarıda bırakır; replikasyon/PITR yedeği için bu basit örnek yeterli değildir.

Parolayı komut satırına veya environment değişkenine taşımak yerine, hesap sahibine ait aşağıdaki dosyada saklayın. Dosyayı editörle oluşturun, sahipliğini doğrulayın ve 600 izni verin. Özel karakterleri istemci seçenek dosyası kurallarına göre kaçırın; bu metin şifrelenmiş bir kasa değildir.

# /home/USERNAME/.config/backup-client.cnf
[client]
user=BACKUP_USER
password="REPLACE_WITH_PASSWORD"
host=localhost

Scriptte --defaults-file ilk seçenektir. MySQL 8.4 için --no-login-paths, ayrıca okunabilen .mylogin.cnf dosyasının etkisini kaldırır. MariaDB alternatifi MySQL’e özgü bu seçeneği ve GTID bayrağını kullanmaz. localhost yerel socket bağlantısı içindir; uzak veritabanında doğrulanmış TLS ve bağlantı ayarlarını ayrıca yapılandırın. Dökümü kurulu sürümle uyumlu istemci kullanarak ayrı veritabanında geri yükleyin; yeni MariaDB dump başlığı eski istemcilerle uyumlu olmayabilir.

Yedek saklama süresi: önce adayları görün

Yedek almak kadar, eski yedekleri düzenli olarak temizlemek de önemlidir. Aksi halde disk alanı dolduğunda yeni yedekler başarısız olur. Silme planını saklama politikanıza göre belirleyin; yeni görevler başarısız olduğunda eldeki son doğrulanmış yedeğin de yaş sınırı nedeniyle silinmesini önleyin.

# Preview only. Run under the backup account; inspect these exact files.
/usr/bin/find /home/USERNAME/backups/mysql -maxdepth 1 -type f \
    -name 'DBNAME-*.sql.gz' -mtime +14 -print
/usr/bin/find /home/USERNAME/backups/files -maxdepth 1 -type f \
    -name 'site-*.tar.gz' -mtime +56 -print
# After verifying retention/recovery requirements, append -delete to
# the corresponding -print expression. Keep the same bounded path/filter.

Bu komutlar yalnızca listeler; silme yapmaz. GNU find, mtime yaşını tamamlanmış 24 saatlik dilimlerle karşılaştırır: +14 en az 15, +56 en az 57 gün demektir. İkincisi “son sekiz haftalık yedeği tut” kuralı değildir. Ad filtresi ve maxdepth, seçimi bu scriptlerin aynı dizindeki arşivleriyle sınırlar. Otomatik silmeyi ancak son doğrulanmış yerel/uzak kurtarma noktalarının korunacağını ve saklama gereksinimlerini kontrol ettikten sonra planlayın; yeni yedekler başarısızken yaşa göre son kullanılabilir kopyayı silmeyin. Log saklama süreleri rehberi hukuki ve operasyonel planlamaya ek bağlam sunar; bütün veriler için tek yasal süre yoktur.

Uzak depolamaya (rsync/rclone) otomatik yedek

Uzak depolama için rclone aracı, yapılandırılmış remote ve izin verilen dış bağlantı gerekir. Aşağıdaki üç --filter kuralı soldan sağa değerlendirilir; ilk eşleşme belirleyicidir. Başlangıçtaki /, yolu kopyalanan /home/USERNAME/backups dizinine göre kökten sınırlar. Böylece yalnız mysql dizininin doğrudan altındaki DBNAME-*.sql.gz ve files dizininin doğrudan altındaki site-*.tar.gz adları seçilir; son - ** kalan yolları dışlar. rclone bu dosya kurallarından mysql/ ve files/ için dizin geçiş kurallarını da türetir.

Bu seçim dosya adlarına dayanır; arşiv içeriğini veya geri yüklenebilirliği doğrulamaz. Önceki scriptlerin geçici .db-work/.files-work alt dizinleri, .part uzantılı dosyalar, daha derindeki aynı adlı aileler ve ilgisiz dosyalar seçilmez. Son arşiv adını ancak oluşturma/bütünlük adımları tamamlandıktan sonra yayımlama düzenini koruyun. Önce aynı komuta --dry-run ekleyerek gerçek hedefi ve seçimi inceleyin; kimlik bilgilerini loglamayın.

0 3 * * * /usr/bin/rclone copy /home/USERNAME/backups remote-backup:projects/site-1 --immutable --filter '+ /mysql/DBNAME-*.sql.gz' --filter '+ /files/site-*.tar.gz' --filter '- **' >> /home/USERNAME/logs/offsite-backup.log 2>&1

copy hedefte fazladan duran dosyaları silmez; –immutable, rclone’un farklı olduğunu belirlediği mevcut dosyayı güncellemek yerine hata verir; zaman damgası farkı da buna yol açabilir. Bu istemci seçeneği depolama tarafında Object Lock/WORM oluşturmaz. sync --delete-before yaklaşımı uzak kurtarma noktalarını da silebileceği için bağımsız geçmiş sağlamaz. Aktarım sonucunu ve geri yüklemeyi doğrulayın; yerel yedeğin saatine bakarak aktarımın bitmiş olduğunu varsaymayın. Uzak sürümleme/retention ve şifrelemeyi ayrıca kurun; gerekirse rclone crypt veya uygun bir yedek aracı kullanın. S3 uyumlu uzak yedekleme rehberi şifreli ve sürümlü kopyaları ele alır.

Rapor, istatistik ve log işlemlerini cron ile otomatize etmek

Yedeklerin yanında, cron job’ları ile raporlama ve log yönetimi tarafını da otomatikleştirebilirsiniz. Özellikle e-ticaret sitelerinde sepet/ödeme adımlarını takip eden scriptleri belirli aralıklarla çalıştırmak, dönüşüm hunisini izlemenize yardımcı olur. Bu konuda sunucu logları ve alarm kuralları ile sepet/ödeme izleme yazımızı mutlaka okumanızı öneririm.

Disk kullanım raporu göndermek

Küçük ama etkili bir örnek: Disk dolmadan önce haberdar olmak için günlük disk kullanım raporu gönderebilirsiniz.

#!/bin/bash
# Save as /home/kullanici/scripts/disk-report.sh
set -euo pipefail
report=$(/usr/bin/du -sh -- /home/kullanici/public_html)
printf '%s\n' "$report" | /usr/bin/mail -s "Gunluk disk kullanimi" you@example.com
0 8 * * * /bin/bash /home/kullanici/scripts/disk-report.sh >> /home/kullanici/logs/disk-report.log 2>&1

Scripti belirtilen konuma kaydedin, adresi değiştirin ve günlük dizinini önceden oluşturun. du hatası rapor göndermeden işi durdurur; mail aracının hata dönüşü de görünür olur. Komutun başarısı alıcıya teslimi veya doğru kota yüzdesini kanıtlamaz. Mail yolu ve posta sistemi kurulmuş olmalı; dizin boyutu yerine panelin kota hesabını ve inode limitini de izleyin.

Eski log dosyalarını sıkıştırma ve silme

Aktif bir logu dosya yaşına bakarak sıkıştırmayın: süreç açık dosyaya yazmayı sürdürebilir. Uygulamanın desteklediği log rotasyonunu veya doğru yeniden açma sinyalleriyle logrotate kullanın. Aşağıdaki örnek yalnızca uygulamanın kapattığı, özel closed dizinine taşınmış log adaylarını listeler:

# Preview only: a dedicated directory of closed, rotated application logs.
/usr/bin/find /home/USERNAME/logs/closed -maxdepth 1 -type f \
    -name 'app-*.log' -mtime +1 -print
# After verifying files are closed, add: -exec /usr/bin/gzip -- {} +
/usr/bin/find /home/USERNAME/logs/closed -maxdepth 1 -type f \
    -name 'app-*.log.gz' -mtime +30 -print
# Add -delete only after checking the retention policy and exact candidates.

GNU find için +1 en az iki, +30 en az 31 tamamlanmış 24 saatlik dilimdir; dosya adı tarihiyle aynı şey değildir. Adayları ve saklama politikasını kontrol ettikten sonra belirtilen exec veya delete eylemi eklenebilir. -exec ... {} + komutu doğru sonlandırır; kabuğa kaçırılmamış tek başına noktalı virgül bu görevi yapmaz. Aktif loglar ve başka uygulamanın dosyaları bu dizinde bulunmamalıdır.

Özel raporlama scriptlerini çalıştırmak

Örneğin, günlük satış raporunu CSV olarak üreten bir PHP scriptiniz olduğunu varsayalım. Bu scripti her gece çalıştırıp sonucu bir klasöre atabilir veya doğrudan e-posta ile gönderebilirsiniz:

15 1 * * * /usr/bin/php /home/kullanici/raporlar/gunluk-satis-raporu.php >> /home/kullanici/logs/daily-sales.log 2>&1

Script raporun veri aralığını ve hedefini belirler; cron sadece tetikler. logs dizinini önceden oluşturun ve döndürün. Başarı kaydı yalnızca rapor üretimi tamamlandıktan sonra yazılmalı; dosya üretmek e-posta göndermek değildir. Kişisel verileri ve erişim yetkilerini rapor paylaşımında dikkate alın.

Bakım işleri: önbellek temizleme, uygulama cron’ları ve sağlık

Uygulamaların zamanlayıcıları aynı değildir. WordPress trafikle tetiklenen WP-Cron kullanır; Laravel schedule:run ile uygulama takvimini değerlendirir; Magento’nun kendi cron kurulumu vardır. Kurulu uygulamanın belgelerine göre yapılandırın ve çift tetikleme/çakışma ihtimalini kontrol edin.

WordPress’te wp-cron yerine gerçek cron kullanmak

WordPress trafik geldiğinde zamanı gelen görevleri kontrol edip WP-Cron’u tetikleyebilir; her sayfa isteğinin bütün görevleri yeniden çalıştırdığını söylemek doğru değildir. Düşük trafikte geciken tetiklemeyi düzenlemek için sistem cron’u kullanılabilir. Geçiş sırası önemlidir:

  1. Doğru hesap ve PHP sürümüyle wp-cron.php çağıran alternatif işi kurup zamanlanmış çalışmasını doğrulayın.
  2. Ancak alternatif çalıştıktan sonra wp-config.php içinde DISABLE_WP_CRON değerini true yaparak sayfa yüklemesiyle tetiklemeyi kapatın.
  3. Görev gecikmesini ve hatalarını izleyin; seçilen aralık uygulama ihtiyacına ve hosting limitine uygun olmalıdır.

Bu işlem WP-Cron görev motorunu kaldırmaz; tetikleyiciyi değiştirir. Ağır callback’leri, Action Scheduler kuyruğunu veya kaynak limitlerini tek başına düzeltmez.

*/10 * * * * /usr/bin/php /home/kullanici/public_html/wp-cron.php >> /home/kullanici/logs/wp-cron.log 2>&1

Bu konuyu adım adım görmek için, WordPress’te wp-cron devre dışı bırakma ve gerçek cron kurulum rehberimize göz atabilirsiniz.

Laravel ve benzeri framework’lerde schedule:run

Laravel gibi framework’lerde iş zamanlamasını uygulama içinden yönetirsiniz ve tek bir cron satırıyla tüm planlı görevleri tetiklersiniz:

* * * * * cd /home/kullanici/proje && /usr/bin/php artisan schedule:run >> /home/kullanici/logs/laravel-scheduler.log 2>&1

Laravel 12’de takvim genellikle routes/console.php içinde veya bootstrap/app.php içindeki withSchedule ile tanımlanır; eski uygulamalarda app/Console/Kernel.php bulunabilir. Proje yapısını kontrol edin. schedule:run zamanı gelen işleri değerlendirir; dakikalık giriş her görevi her dakika çalıştırmaz. withoutOverlapping ve gerekiyorsa onOneServer uygulama cache kilitleriyle yapılandırılmalı; uzun süren veya dakikadan kısa aralıklarla tetiklenen görevlerde sürüme uygun dağıtım davranışı ayrıca kontrol edilmelidir.

Önbellek ve geçici dosyaları temizlemek

Dosya yaşı, uygulama cache’inin süresinin dolduğunu veya storage dizininin silinebilir olduğunu göstermez. Session, lock ve yükleme dosyaları da burada olabilir. Uygulamanın desteklediği temizleme yöntemini kullanın. Aşağıdaki salt listeleme yalnızca sizin oluşturduğunuz, başka yerde kullanılmayan özel export geçici dosyaları içindir:

/usr/bin/find /home/kullanici/tmp/exports -maxdepth 1 -type f \
    -name 'export-*.tmp' -mtime +2 -print

Benzer şekilde, WordPress için belirli cache eklentilerinin komut satırı arayüzü varsa, bunları da cron ile tetikleyebilirsiniz. Genel bakım işlerini yıllık bazda planlamak için küçük işletmeler için yıllık web sitesi bakım takvimi rehberimiz size güzel bir iskelet sunar.

Basit sağlık kontrolleri (health check)

Profesyonel izleme sistemleri kadar kapsamlı olmasa da, cron ile temel sağlık kontrolleri yapabilirsiniz. Örneğin sitenize curl ile istek atıp, hata durumunda kısa bir e-posta gönderen küçük bir script çalıştırmak mümkün.

*/5 * * * * /usr/bin/php /home/kullanici/monitoring/health-check.php >> /home/kullanici/logs/health-check.log 2>&1

Aynı sunucudaki cron, sunucunun kendisi veya cron hizmeti durduğunda alarm üretemeyebilir. Dışarıdan çalışan bir izleyiciyle son başarılı kontrol zamanını ve eksik çalışmaları takip edin. HTTP başarı kodu bütün uygulama akışının sağlıklı olduğunu kanıtlamaz; seçilen kontrolün kapsamını belirleyin.

cPanel ve DirectAdmin’de cron job güvenliği ve en iyi pratikler

Görevin çalıştığı hesap, dosya izinleri, hataların görünürlüğü ve çakışma davranışı birlikte değerlendirilmelidir. Aşağıdaki kontroller, bu yazıdaki örneklerin gerçek ortama uyarlanmasını tamamlar.

1. Tam yol kullanın (binary ve scriptler için)

Cron ortamında PATH değişkeni genellikle sınırlıdır. Bu yüzden:

  • php yerine /usr/bin/php
  • mysqldump yerine /usr/bin/mysqldump
  • tar yerine /bin/tar

Doğrulanmış tam yollar komutun yanlış sürümünün seçilmesini önler. Dosya gerçekten yoksa veya çalıştırma izni yoksa yalnızca tam yol yazmak hatayı gidermez. Cron’un çalışma dizini ve ortam değişkenleri interaktif terminalden farklı olabilir.

2. Scriptleri mümkünse public_html dışına taşıyın

Yedekleme, raporlama, log temizleme gibi scriptlerinizin tarayıcıdan direkt erişilebilir olmaması önemli bir güvenlik tedbiridir. Bunları:

  • /home/kullanici/scripts
  • /home/kullanici/cron

Bu dizinleri hiçbir vhost, alias veya başka paylaşımın web üzerinden sunmadığını da kontrol edin. Yol adının public_html dışında olması, yanlış web sunucusu eşlemesini tek başına engellemez. Script ve kimlik bilgileri yalnızca gereken hesaplarca okunabilmelidir.

3. Parola ve hassas bilgileri komut satırına yazmayın

Özellikle mysqldump veya uzak depolama araçlarında, kullanıcı adı/parola bilgilerini direkt komut içinde yazmak hem loglara sızabilir hem de süreç listelerinde (ps) görünebilir. Bunun yerine:

  • Bu rehberdeki gibi açıkça seçilen, 600 izinli istemci seçenek dosyası kullanın.
  • Uzak araçların desteklediği korumalı kimlik bilgisi mekanizmasını seçin; environment değişkeni tek başına gizlilik garantisi değildir.
  • Yedeklerin kendileri de parolalar veya kişisel veri içerebilir; erişim, aktarım ve saklama şifrelemesini planlayın.

Kimlik bilgisi dosyalarını yedek arşivi ve erişim politikasıyla birlikte değerlendirin; komut ve hata günlüklerinde sırların görünmediğini kontrol edin.

4. Çalışma sıklığını abartmayın

Her şeyi “her dakika” çalıştırmak cazip gelebilir ama bu hem hesabınızın kaynak limitlerini zorlar hem de veritabanı/sunucu üzerinde gereksiz yük oluşturur. Önerimiz:

Çalışma sıklığını veri kaybı toleransı, görev süresi ve sağlayıcı limitleri belirler. Dakikalık uygulama tetikleme ile saatler süren tam yedeği aynı kategoriye koymayın. flock gibi atomik kilit kullanın; dosyanın varlığını kontrol edip sonra oluşturmak yarış koşuluna açıktır. Zamanları ayırmak da çakışmayacağını garanti etmez.

Daha ileri düzey iş yükleriniz varsa, cron yapılandırmasını DCHost teknik ekibimizle birlikte gözden geçirmek iyi bir yatırım olur.

5. Önce manuel test, sonra cron’a ekleme

Önce üretim dışı veriyle ve cron hesabının izinlerine benzer koşullarda deneyin. Silme işlemlerinde listeleme/dry-run kullanın; doğru hedef doğrulanmadan yıkıcı komutu sırf test amacıyla çalıştırmayın. Örneğin uygulamanıza ait test edilebilir bir PHP scripti:

/usr/bin/php /home/kullanici/cron/yedek.php

Manuel başarıdan sonra ilk gerçek zamanlanmış çalışmanın zamanını, dönüş kodunu ve çıktısını kontrol edin. Yedek için ayrıca ayrı ortamda geri yükleme yapın. Her başarı loguna güvenmek yerine en son doğrulanmış kurtarma noktasının yaşını izleyin; hata çıktısını körlemesine /dev/null’a göndermeyin.

DCHost altyapısında cron job senaryolarını projeye göre kurgulamak

DCHost’ta ister paylaşımlı hosting, ister NVMe VPS, ister dedicated sunucu veya colocation kullanın; cron job stratejisini projeye göre şekillendirmek uzun vadede size ciddi rahatlık sağlar.

Küçük kurumsal/site-vitrin projeleri

Az değişen bir içerik sitesi için şu plan değerlendirilebilir; gereken kurtarma noktası ve dosya değişim sıklığına göre aralıkları değiştirin:

  • Günlük dosya ve veritabanı yedeği (gece saatlerinde)
  • Haftalık log temizliği ve sıkıştırma
  • WordPress kullanıyorsanız gerçek cron ile wp-cron.php tetikleme

Bu görevleri panelden planlamak elle tetikleme ihtiyacını azaltır; restore testleri, yazılım güncellemeleri ve izleme takibi devam eder. Yıllık bakım takvimi rehberi daha geniş planlama için kullanılabilir.

E-ticaret ve yüksek trafikli WordPress/Laravel projeleri

Daha yoğun projelerde ise genellikle şu yapı öne çıkıyor:

  • Uygulama görevleri için dakikalık/5 dakikalık cron’lar (sipariş durumu, stok güncelleme vb.)
  • Gece saatlerinde incremental veya tam yedekler
  • Ayrı cron job’larla veritabanı yedeği ve dosya yedeğinin ayrılması
  • Uzak depoya (S3 uyumlu storage veya ikinci sunucuya) otomatik replikasyon

WordPress ağırlıklı projeler için WordPress yedekleme stratejileri rehberimizde paylaşımlı hosting ve VPS’te otomatik yedek planlarını detaylıca anlattık. Bu rehberle birlikte elinizdeki cron örneklerini birleştirirseniz, oldukça sağlam bir otomasyon iskeleti kurabilirsiniz.

VPS, dedicated ve colocation senaryoları

VPS, dedicated veya colocation üzerinde yetkiniz varsa daha fazla araç seçebilirsiniz; erişim seviyesi, bakım sorumluluğu ve kaynak limitleri yine geçerlidir. Örnek alanlar:

  • Kontrollü paket güncellemelerini uygun bakım penceresine planlamak; körlemesine tüm paketleri yükseltmek yerine test ve geri dönüş sağlamak.
  • Logları merkezi sisteme taşıyan bir ajan veya uygun görev kurmak; aktarım gecikmesi ve kayıpları izlemek.
  • Doğrulanmış yedekleri farklı konumdaki depoya aktarmak; bağımsız saklama ve geri yükleme testlerini korumak.

Daha kompleks ortamlarda, cron ile systemd timer, izleme/alerting ve yedekleme çözümlerini bir arada ele almak en doğrusu. Burada size özel mimari önerisi isterseniz, DCHost teknik ekibi olarak proje detaylarınıza göre birlikte bir plan çıkarmaktan memnun oluruz.

Cron Görevlerini İzlenebilir Bir Bakım Planına Dönüştürün

Cron tanımlı zamanda komutu başlatır; doğruluk, tekrar deneme, kilit, bildirim ve yedek bütünlüğü script ve çevresindeki sistemin sorumluluğudur. PHP yolunu ve saat dilimini doğrulayın, işleri cron hesabıyla test edin, ilk zamanlanmış çalışmayı takip edin. Bir işin başlayamaması veya başarısız olması sonraki çalışmayı otomatik olarak güvenilir kılmaz.

Dosya/veritabanı yedeklerini parolayı komut satırına koymadan, geçici dosyadan tamamlanmış arşive kontrollü geçişle oluşturun. Saklama öncesi doğru adayları görün; uzak kopyanın yerel silmeleri takip eden tek ayna olmasını önleyin. Rapor ve uygulama tetiklemelerinde log, çakışma kilidi ve eksik çalışma alarmı ekleyin.

Zamanlama unutmayı azaltır; düzenli kontrolün yerini almaz. Yedeklerin gerçek geri yükleme sonucunu, en son başarılı çalışma zamanını ve değişen kaynak ihtiyacını periyodik olarak değerlendirin. Panel veya paket sürümü değiştiğinde komut yolları ve desteklenen seçenekleri tekrar doğrulayın.

Sıkça Sorulan Sorular

Cron, bir komut veya scripti tanımlı zamanlarda çalıştırır. Panelde dakika, saat, ayın günü, ay ve haftanın günü alanlarını doldurun; Command alanına yalnızca komutu girin. Doğru hesap, PHP/araç yolu ve zaman dilimini doğrulayın. Önce uygun test verisiyle deneyin, sonra ilk zamanlanmış çalışmayı izleyin. Cron tek başına başarı veya geri yüklenebilir yedek garantisi değildir.

Veri değişim hızı, kabul edilebilir kayıp, görev süresi ve hosting limitleri belirleyicidir. Günlük veritabanı veya haftalık dosya yedeği yalnızca örnek bir plandır; yoğun mağazalar ve sık yüklenen dosyalar daha sık kurtarma noktası gerektirebilir. Bağımsız uzak kopyaları ve restore testlerini planlayın. Yaşa dayalı silme son sekiz kopyayı tutmakla aynı değildir; son doğrulanmış yedeği koruyun.

Ağır veya çakışan işler CPU, disk ve veritabanı kaynaklarını tüketebilir. Süre ve kaynak kullanımını ölçün, uygun saat seçin ve flock gibi atomik kilitle çakışmayı kontrol edin. Tam yollar ve script izinlerini doğrulayın. Hataları /dev/null’a atmak çözüm değildir; dönen günlükler ve dışarıdan eksik çalışma takibi kullanın.

WP-Cron zamanı gelen işleri trafikle tetikleyebilir; düşük trafikte gecikme oluşabilir. Önce doğru hesap ve PHP sürümüyle alternatif cron çağrısını kurup doğrulayın, ardından DISABLE_WP_CRON ile sayfa yüklemesi tetiklemesini kapatın. WP-Cron motoru kullanılmaya devam eder. Aralığı görev ihtiyacına göre seçin; sistem cron’u ağır callback veya kaynak sorunlarını tek başına düzeltmez.
↑