Kendi VPS sunucularımdan birinde OpenClaw sunucusu çalıştırıyorum. Bildiğiniz üzere OpenClaw hafızası ve yetenekleri /root/.openclaw içerisinde tutuluyor. Yani kişisel yapay zeka asistanınıza ait her şey aslında bu dizin altında.
Daha öncesinde OpenClaw Agent’ımı Google Drive hesabıma nasıl bağladığımı burada ki yazımda anlatmıştım.
Sorun şu: bu dizin kaybolursa OpenClaw sunucunuzu “yeniden kur, devam et” diyebileceğimiz bir şey değil. Ajanımızın tüm yetenekleri, yetkinlikleri ve entegrasyonları bu dizin altında barındırılıyor.
Yapay zeka asistanınızı özelleştirdikçe ve dolayısı ile yaptığı işin niteliği arttıkça önemi de artıyor. Peki, bu kadar hayatımı kolaylaştıran sistemin yedeğini nasıl alabilirim?
Hedef Uygulama Mı?
Proje kapsamında ki hedefim aslında oldukça basit. Aşağıda ki üç ana maddeye odaklandım:
- Belirli aralıklarla sunucudaki veriyi yedekle ve GoogleDrive hesabımda ilgili klasöre at.
- Dirve’da sadece son 2 yedeği tut.
- İşlem bilgisini Telegram’dan bana bildir.
Mimari
Zaten kendi sunucularımda host ettiğim bir n8n bulunuyordu. Özellikle threat intelligence projem olan securitytimeline.com gibi projelerim için n8n kullanıyordum. Bu yüzden bu işlem için de kendi sunucularımda host ettiğim n8n’i kullandım.
Temelde akış şu şekilde:
Schedule Trigger
- SSH: Sunucu da backup scriptini çalıştır. (sudo -n ile, non-interactive bir script)
- SSH: Oluşan arşivi n8n'e indir.
- Upload: Google Drive'a yükle.
- SSH: Sunucuda oluşturulan yedeği sil.
-- Google Drive: Klasörde ki yedekleri listeler, en eskiyi bul ve sil (retention)
-- Telegram: Mesaj gönder.
Hata Mesajını ise ayrı bir workflow'da, Error Trigger ile tetikle.
Retention ve başarı bildirimini özellikle ayrı ayrı gerçekleştirdim. İlk başta başarı mesajını, silme adımından sonra koymuştum. Ama bu adımda fark ettim ki Drive tarafında 2 veya daha az dosya varken silme node’u hiç çalışmıyor ve dolayısıyla ondan sonra ki node’larda tetiklenmiyordu. Bildirim bazen hiç gitmiyordu. Çözüm olarakta ikisini de aynı noktadan, birbirinden bağımsız bir şekilde tetiklemek olarak düşündüm.
OpenClaw’a Kendi Backup Scriptini Yazdırmak
İsteğim son derece basit olduğu için, OpenClaw tarafında ki yedek alma scriptini kendisine yazdırdım. OpenClaw’a “Kendi ortamını incele ve bir yedekleme script’i hazırla” dedim. OpenClaw zaten kendi dosya sistemine ve terminale erişimi olduğu için, kurulum ortamını tarayıp tüm sistem yollarını ve gereksinimleri kendisi tespit etti:
```bash
TS=$(date +%Y%m%d-%H%M%S)
FILE=/tmp/openclaw-backup-$TS.tar.gz
STAGING=$(mktemp -d /tmp/openclaw-backup-$TS.XXXXXX)
# ... veri dizinini tar'la, varsa Postgres'i pg_dump ile ekle ...
echo "$FILE"
```
Burada ki tek kısıtım; scriptin son satırı sadece oluşan dosyanın tam yolunu yazmalı, başka hiç bir satır olmamalıydı. Sebebi ise n8n tarafında bu stdout’u doğrudan bir sonraki adımın girdisi olarak kullanıyordum. Araya başka bir log satırı girdiğinde workflowum crash oluyordu.
İşin Güvenlik Tarafı
Script, /root/.openclaw a erişim için root yetkisi istiyor. n8n’in SSH Credential’ını doğrudan root ile bağlamak ilk başlarda test ederken en kısa yoldu fakat bu güvenlik zafiyetine yol açıyor. Keyin olası bir sızma durumunda sunucuya tam bir root erişim yetkisi veriliyor.
Burada ise ayrı bir automation kullanıcı açtım ve sadece bu script için NOPASSWD sudo yetkisi verdim.
automation ALL=(root) NOPASSWD: /usr/local/bin/openclaw-backup.sh
n8n’de ki Command node’u sudo -n /usr/local/bin/openclaw-backup.sh scriptini çalıştırıyor ve -n ile de şifre isteğini engelledim.
Retention: Silme Sırası
Google Drive’da, ilgili klasörde en fazla 2 yedeğin tutulmasını istiyordum. Mantık olarak basitti. FIFO kuralı uygulanacaktı fakat burada önce yükle sonra sil mi, yoksa önce sil sonra yükle mantığını mı kullanacaktım. Ben önce yükledim, sonra sildim. Dosya yüklendikten sonra klasörde ki dosyaları createdTime‘a göre sıraladım ve eğer liste 2’den fazla ise en eski olanı sildim.
javascript
const files = $input.all()
.map(item => item.json)
.sort((a, b) => new Date(a.createdTime) - new Date(b.createdTime));
if (files.length > 2) {
return [{ json: { fileIdToDelete: files[0].id } }];
}
return [];
Bunu yükleme başarısız olursa hiçbir şeyin silinmemesi için özellikle yaptım.
N8N Diski İlgi İstiyor
Sunucu tarafını temizledik ama hatırlarsanız yukarıda oluşturulan yedeği n8n’e alıp, buradan Drive’a yüklemiştim. Benim ortalama yedek dosyalarım 300MB civarında oluyor ve n8n bunu kendi execution historysinde tutuyordu. Binary data modu “memory” olduğunda bu dosyayı base64’e çevirip, execution db’sine gömüyordu.
Benim yedek aldığım destination bölgem Google Drive olduğu için n8n’de ki execution geçmişinde dosyanın saklanmasına ihtiyacım yoktu. İlgili workflow’un ayarlarında Save successful production executions kısmını None olarak set ettim.Hata mesajları debug içn hala kayıt ediliyor ama başarılı işlemden sonra n8n böylece kendi diskini şişirmiyordu.
Bildirimler: Başarı Ana Workflow’undur, Hata Başka
Başarı mesajını doğrudan ana workflowa ekledim. Hata bildirimi için ise farklı bir yol seçerek n8n’in Error Trigger node’unu ayrı bir workflow’a koyup, ana workflow’un ayarlar kısmından “Error Workflow” olarak bağladım.
Sonuç
Şu anda elimde zamanlamış çalışan, sunucu ve n8n tarafında disk biriktirmeyen, Drive’da Sabir sayıda yedek tutan, başarı ve başarısızlığı Telegram’a düşen bir sistemim var. Script’i ve n8n Workflow yapısı GitHub’ımda paylaştım. Kendi OpenClaw sunucununuzun yedeğini almak isterseniz repo’ya göz atabilirsiniz:


