Docker Yedekleme

17.07.2025

Sunucumda bulunan çeşitli docker containerlarının yedeklenmesi her zaman üşendiğim bir konu olmuştur. Bazı uygulamarın kendine özgü yedekleme image’ları var, bazıları ise illa elle müdahale gerektiriyor vesaire. Yedeği aldıktan sonra da bu dosyaları bir yerlere (Google Drive, Amazon S3, Cloudflare R2 vb.) yüklemek gerekiyor. Yani üşenmekte haklı olduğum bir süreç.

Geçen hafta sonunda bir çözüm aramaya başladım. Her zaman ki gibi “illa ki bunu daha önce düşünen birileri vardır” diyerek Youtube’a sordum. Bu aralar bu tarz şeyleri Youtube’a sormaya başladım. Neyse offen/docker-volume-backup 🡥 adında bir projeye rastladım. Mevcut docker container’larına ek olarak kullanılıyor. Yedeklemek istediğiniz container’ın volume’lerini bu container’a da ekliyorsunuz. Verdiğiniz talimatlar doğrultusunda; belirtilen sıklıkla bu volume’lerin yedeğini alıyor, belirttiğiniz servislere yüklüyor ve belirttiğiniz adet güncel yedeği tutup eski yedekleri siliyor. Bütün bunların yanında, yedek almadan önce yapılması gereken işlemler varsa (örneğin veritabanı yedeğinin alınması) onları da yapıyor.

Güvenlik ve ya gizlilik sebebiyle yedeklerinizin 3. parti kişiler tarafından okunamamasını isterseniz, aldığı yedekleri yüklemeden önce şifreleyebiliyor. İsterseniz yedekleme işlemlerinden sonra size çeşitli platformlardan (Discord, Telegram, email vb) bildirim mesajı da atabiliyor. Aynı hizmeti parayla almak isteseniz bir alternatif bulamayabilirsiniz yani :)

Neyse sadede geleyim.

RSS reader olarak kullandığım FreshRSS 🡥’in yedeğini almak için aşağıdaki compose.yml dosyasını kullanıyorum.

# compose.yml
services:
  # FreshRSS container'ı
  freshrss:
    image: freshrss/freshrss:latest
    container_name: freshrss
    hostname: freshrss
    restart: unless-stopped
    logging:
      options:
        max-size: 10m
    # FreshRSS volume'leri
    volumes:
      - ./data:/var/www/FreshRSS/data
      - ./extensions:/var/www/FreshRSS/extensions
    ports:
      - 127.0.0.1:13013:80
    environment:
      TZ: Europe/Istanbul
      CRON_MIN: '3,33'
    labels:
      # Yedekleme işlemine başlamadan önce freshrss container'ını durdur
      - docker-volume-backup.stop-during-backup=freshrss
      # Yedeğe ait arşiv dosyası oluşturmadan önce freshrss'in veritabanını yedekle
      - docker-volume-backup.archive-pre=/bin/sh -c './cli/db-backup.php'
  # Yedekleme container'ı
  backup:
    image: offen/docker-volume-backup:latest
    container_name: freshrss-backup
    restart: always
    # Yedekleme talimatlarını `backup.env` environment dosyasından yükle.
    env_file: ./backup.env
    volumes:
      # FreshRSS container'ına ait volume'leri read-only olarak ekle
      - ./data:/backup/freshrss-data:ro
      - ./extensions:/backup/freshrss-extensions-data:ro
      # Sunucunun docker.sock socketine erişime izin veriyoruz ki söylediğimiz container'ları durdurup yeniden başlatabilsin.
      - /var/run/docker.sock:/var/run/docker.sock:ro

Yedekleme talimatlarını belirttiğimiz backup.env dosyası da aşağıdaki gibi:

# backup.env

# Yedekleme sıklığı, 9:01 ve 21:01 de yedekliyorum.
# Cron syntax'ı için => https://crontab.guru/
BACKUP_CRON_EXPRESSION="1 9,21 * * *"

# Yedekleme işlemi öncesinde durduracağı container.
# compose.yml dosyasındaki `docker-volume-backup.stop-during-backup=freshrss`
# kısmındaki etiket ile birebir eşleşmeli.
BACKUP_STOP_DURING_BACKUP_LABEL="freshrss"

# Yedek arşiv dosyasının adı
BACKUP_FILENAME="freshrss-%Y-%m-%dT%H-%M-%S.{{ .Extension }}"

# Yedek dosyasının başlangıcı. Bu başlangıçtan sonraki kısım tarih ve saat olduğu için
# bu zaman bilgisine göre eski yedekleri siliyor.
BACKUP_PRUNING_PREFIX="freshrss-"

# Son 10 günlük yedeği tutup, daha eski yedekleri siliyor.
BACKUP_RETENTION_DAYS="10"

# Arşiv dosyasını encrypt ederken kullanacağı şifre.
AGE_PASSPHRASE="********************"

# Yedekleri yüklemesi için Cloudflare R2 bilgilerimi tanımlıyorum.
# Burada AWS S3 ile aynı API'a sahip diğer servisleri de tanımlayabilirsiniz.
# Örneğin Minio, DigitalOcean Spaces, Cloudflare R2
AWS_ENDPOINT="********************************.r2.cloudflarestorage.com"
AWS_ACCESS_KEY_ID="********************************"
AWS_SECRET_ACCESS_KEY="****************************************************************"
AWS_S3_BUCKET_NAME="backup"

Artık sadece 5 dakikamı ayırarak, yukarıdaki konfigurasyon değişikliklerini yapıp tüm container’larımı yedekleyebilirim. Üşendiğim şeyler listemden bir kalem daha eksilmiş oldu.