Yedekleme & yükseltme

Tek komutla yedek al ve geri yükle, günlük yedeği aç, yeni sürüme tek komutla geç.

Yedek üç şeyden oluşur: PostgreSQL veritabanı, yüklenen dosyalar (ekler ve metne gömülen görseller, app-uploads birimi) ve gizli anahtarları taşıyan .env.onprem ayar dosyası. Yalnız veritabanını almak yetmez; geri yüklediğinde görevler ve sayfalar gelir ama ekleri açılmaz. Paketle gelen iki betik bu işi senin yerine yapar: ./scripts/backup.sh yedek alır, ./scripts/restore.sh geri yükler. Komutları kurulum dizininde çalıştır. Yükseltme tek komuttur: ./scripts/update.sh en son paketi indirir, önce yedek alır ve güncellemeyi uygular (v1.67.2 ve sonrası).

Yedek alma

./scripts/backup.sh

Yedek uygulama çalışırken alınabilir; pg_dump tutarlı bir anlık görüntü alır. Her çalıştırma kurulum dizinindeki backups/ altında tarih, saat ve kurulu sürümle adlandırılmış yeni bir klasör açar, örneğin backups/2026-10-02-023000-v1.61.0. Sürüm diskte açılmış paketten değil kurulu uygulama konteynerinden okunur; güncellemeden önce alınan yedek bu yüzden eski sürümün adını taşır. Klasöre yalnız betiği çalıştıran kullanıcı erişir (izin 700). Veritabanı konteyneri çalışmıyorsa betik dökümü alamayacağını söyleyip durur.

Dosyaİçerik
db.sql.gzVeritabanı (pg_dump, sıkıştırılmış düz SQL)
uploads.tar.gzYüklenen dosyalar (app-uploads birimi)
env.onprem.env.onprem kopyası; gizli anahtar taşır, izni 600
manifest.txtTarih, sürüm, boyutlar, tablo sayısı, sunucu adı

Betik yedeği kendisi doğrular: iki arşiv de geçerli gzip mi, dosya arşivi sorunsuz listeleniyor mu, döküm pg_dump’ın bitiş işaretiyle bitiyor mu (yarıda kesilmemiş), döküm makul sayıda tablo oluşturuyor mu (varsayılan en az 20). Yedek önce adı .partial ile biten bir klasöre yazılır ve ancak doğrulandıktan sonra asıl adını alır; adı .partial ile bitmeyen her klasör eksiksizdir. Bir kontrol tutmazsa betik açık bir hata mesajıyla sıfırdan farklı bir kodla çıkar ve yarım klasörü siler.

Saklama: en yeni 7 eksiksiz yedek tutulur, eskileri silinir. Yalnız yedek adı kalıbına uyan ve manifest.txt dosyası status: ok diyen klasörler sayılır ve silinir; backups/ altına koyduğun başka bir şeye dokunulmaz.

SeçenekNe yapar
--keep NEn yeni N yedeği tut. Varsayılan: .env.onprem içindeki MYWAY_BACKUP_KEEP, yoksa 7
--dir YOLYedeği backups/ yerine YOL’a yaz, örneğin bağlı bir ağ diskine
--quietYalnız hataları ve tek satırlık bir özeti yaz (cron için)
--verify KLASÖRYedek almadan var olan bir yedeği denetle
./scripts/backup.sh --keep 14
./scripts/backup.sh --dir /mnt/nas/myway-backups
./scripts/backup.sh --verify backups/2026-10-02-023000-v1.61.0

Yedeği başka bir makineye kopyala. Aynı diskteki yedek bir disk arızasından ya da sunucunun kaybından seni korumaz; betik de elle alınan her yedeğin sonunda bunu hatırlatır. Klasörleri düzenli olarak başka bir yere taşı ya da --dir ile doğrudan bağlı bir ağ diskine yaz. Yedek .env.onprem içerdiği için gizli anahtar taşır; hedefi buna göre koru.

Günlük otomatik yedek

Kurulum betiği günlük yedeği kurmayı önerir ve "Set up a daily automatic backup? [Y/n]" diye sorar; varsayılan evettir. Kabul edersen her gece 02:30’da ./scripts/backup.sh --quiet çalışır, en yeni 7 yedek backups/ altında tutulur ve çıktı logs/backup.log dosyasına yazılır. Cevap .env.onprem içine MYWAY_DAILY_BACKUP=yes ya da no olarak kaydedilir ve sonraki çalıştırmalarda yeniden sorulmaz. Soru ilk kurulumda sorulur; v1.61.1’den eski bir kurulumu güncellerken de cevap henüz kayıtlı olmadığı için bir kez gelir. Terminal olmadan çalışan bir kurulumda (otomasyon) günlük yedek varsayılan olarak açılır.

Yedeğin sonucu Ayarlar > Sağlık ekranında görünür. Uygulama çalışıyorsa ./scripts/backup.sh her yedeğin sonucunu (başarılı ya da hata, boyut, tablo ve dosya sayısı, süre) uygulamaya bildirir; bu yalnız gece yedeği için değil, elle alınan yedek için de geçerlidir, --verify ile yapılan denetim ise bildirilmez. Zamanlanmış işler tablosundaki "Yedekleme" satırı son yedeği, sonucunu ve sonraki çalışmayı gösterir. Son yedek 26 saatten eskiyse satır "Gecikti", hatayla bittiyse "Hata" olur; henüz hiç sonuç gelmemişse (örneğin günlük yedek kapalı ve elle de yedek alınmamışsa) "Çalışmadı" görünür. Bildirim yedeği hiçbir zaman başarısız saymaz: uygulamaya ulaşılamazsa betik yalnız bir uyarı yazar, çıkış kodu değişmez. Uygulama kapalıyken alınan yedek bildirilmez. v1.62.0’dan eski bir kurulumu güncellerken alınan yedek, henüz eski sürümde çalışan uygulamaya bildirilemez; betik bunu bir uyarıyla söyleyebilir, yedek bundan etkilenmez.

AyarNe yapar
./scripts/install.sh --daily-backupGünlük yedeği sormadan açar
./scripts/install.sh --no-daily-backupGünlük yedeği kurmaz, varsa kaldırır
MYWAY_BACKUP_KEEP.env.onprem içinde kaç yedeğin tutulacağı (varsayılan 7)
MYWAY_BACKUP_REPORT=no.env.onprem içinde: yedeğin sonucunu Sağlık ekranına bildirmeyi kapatır

Günlük yedek, zamanlanmış görevlerle aynı crontab bloğuna yazılır. Kurulum betiğini NO_CRON=1 ile çalıştırırsan günlük yedek de zamanlanmaz ve betik kurulum sonunda bunu bir uyarıyla bildirir; bu durumda ./scripts/backup.sh’i kendin çalıştır ya da crontab’a kendin ekle.

Geri yükleme

./scripts/restore.sh backups/2026-10-02-023000-v1.61.0

Betik hiçbir şeye dokunmadan önce yedeği doğrular. Sonra yedeğin tarihini ve sürümünü kurulu sürümle yan yana, tablo ve dosya sayılarıyla gösterir ve "Type RESTORE to continue:" diye sorar. Devam etmek için RESTORE yazarsın; başka bir cevap hiçbir şeyi değiştirmeden çıkar. Betik terminal olmadan çalışacaksa (örneğin başka bir betikten) onay --yes ile verilir. Onaydan sonra:

  1. 1Uygulamayı durdurur; veritabanı konteyneri çalışmaya devam eder.
  2. 2Dökümü yeni, boş bir veritabanına tek işlemde yükler ve yükleme başarılı olunca adını değiştirerek mevcut veritabanının yerine koyar. Yükleme başarısız olursa mevcut veritabanına dokunulmamıştır ve uygulama yeniden başlatılır.
  3. 3Önceki veritabanını uygulama sağlıklı açılana kadar <veritabanı adı>_pre_restore adıyla saklar, sonra siler.
  4. 4Yüklenen dosyalar birimini boşaltır ve yedekteki arşivi açar.
  5. 5Uygulamayı başlatır (bekleyen migrasyonlar her zamanki gibi uygulanır) ve sağlıklı açılmasını bekler. Geri yüklemeden önce oturum açmış kullanıcıların yeniden giriş yapması gerekebilir.

.env.onprem varsayılan olarak geri yüklenmez; betik yalnız yedektekinden farklı olan ayarların ADLARINI listeler, değerlerini göstermez. Yedeği yeni bir sunucuya taşıyorsan --with-env ekle; mevcut dosya .env.onprem.before-restore-<zaman> olarak saklanır. Kayıtlı GitLab erişim anahtarları SESSION_SECRET ve GITLAB_TOKEN_KEK ile şifrelidir: bu değerler yedektekinden farklıysa betik uyarır ve --with-env ile yeniden çalıştırmanı ya da GitLab’ı sonradan yeniden bağlamanı önerir.

# yeni sunucuya taşıma: paketi kur, yedek klasörünü sunucuya kopyala
# moving to a new server: install the package, copy the backup directory over
./scripts/install.sh
./scripts/restore.sh --with-env backups/2026-10-02-023000-v1.61.0

Yedeği kendi sürümüyle geri yükle. Yedeğin sürümü kurulu sürümden farklıysa betik uyarır. Daha eski bir sürümün yedeği açılışta migrasyonlarla yükseltilir; daha yeni bir sürümün yedeği kurulu sürümde açılmayabilir. En güvenli yol: önce yedeğin sürümündeki paketi kur, geri yükle, sonra her zamanki gibi güncelle.

Elle yedek (betiksiz)

Betikleri kullanamadığın bir durumda aynı işi elle yaparsın. Compose dosyasının adı varsayılan değil, bu yüzden her komut -f docker-compose.onprem.yml ve --env-file .env.onprem ile verilir. .env.onprem dosyasını da ayrıca güvenli bir yere kopyala.

# veritabanı / database
docker compose -f docker-compose.onprem.yml --env-file .env.onprem \
  exec -T postgres sh -c 'pg_dump --no-owner --no-privileges -U "$POSTGRES_USER" "$POSTGRES_DB"' \
  | gzip > myway-db-$(date +%F).sql.gz

# yüklenen dosyalar / uploaded files
docker run --rm -v myway-onprem_app-uploads:/data:ro postgres:16-alpine \
  tar czf - -C /data . > myway-uploads-$(date +%F).tar.gz

Elle geri yüklerken önce uygulamayı durdur. Döküm BOŞ bir veritabanına yüklenmelidir; dolu bir veritabanının üstüne yüklemek "already exists" hatalarıyla yarım kalır. Aşağıdaki komutlar mevcut veritabanını silip boş olarak yeniden oluşturur, yani betikten farklı olarak yükleme başarısız olursa geri dönüş yolu yoktur.

C="docker compose -f docker-compose.onprem.yml --env-file .env.onprem"
$C stop app
$C exec -T postgres sh -c 'psql -U "$POSTGRES_USER" -d postgres -c "DROP DATABASE \"$POSTGRES_DB\" WITH (FORCE)" -c "CREATE DATABASE \"$POSTGRES_DB\""'
gunzip -c myway-db-YYYY-MM-DD.sql.gz | \
  $C exec -T postgres sh -c 'psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -d "$POSTGRES_DB"'
docker run --rm -i -v myway-onprem_app-uploads:/data postgres:16-alpine \
  sh -c 'find /data -mindepth 1 -delete && tar xzf - -C /data && chown -R 1000:1000 /data' \
  < myway-uploads-YYYY-MM-DD.tar.gz
$C up -d

Birim adı <proje>_app-uploads biçimindedir; standart kurulumda myway-onprem_app-uploads olur. Emin değilsen docker volume ls | grep app-uploads ile doğrula.

Yükseltme

cd myway-onprem   # kurulum dizininiz / your install directory
./scripts/update.sh

v1.67.2’den beri kurulum dizinindeki ./scripts/update.sh yükseltmeyi tek adımda yapar. .env.onprem içindeki LICENSE_KEY ile en son paketi indirir, paketteki sürümü kurulu sürümle karşılaştırır; aynıysa "Already up to date." yazar ve hiçbir şeye dokunmaz. Yeni sürüm varsa paketi kurulum dizininin üstüne açar (.env.onprem ve backups/ değişmez), ./scripts/install.sh --backup ile önce kurulu sürümün yedeğini alıp güncellemeyi uygular ve PUBLIC_URL tanımlıysa /api/health yeni sürümü gösterene kadar en fazla 150 saniye bekler. Yedek alınamazsa güncelleme uygulanmaz.

SeçenekNe yapar
--forceSürüm aynı olsa da paketi indirip yeniden kurar
MYWAY_DOWNLOAD_URLİndirme adresi (ortam değişkeni); varsayılan https://www.themyway.app/api/download
ENV_FILEOkunacak ayar dosyası (ortam değişkeni); varsayılan .env.onprem

İlk kez: betik v1.67.2 paketiyle gelir. Daha eski bir kurulumu bir kez aşağıdaki yolla güncelleyin; yeni paketi satın alma e-postanızdaki bağlantıdan ya da Ayarlar > Güncellemeler’deki "v1.69.0 paketini indir" gibi görünen düğmeden alın. Sonraki güncellemelerde ./scripts/update.sh yeterlidir. Betik internet ister; kapalı ağda da aşağıdaki yolla güncelleyin.

Yedek başarısız olursa paket dosyaları diske açılmış ama kurulu sürüm değişmemiş olur. Bu durumda ./scripts/update.sh’i yeniden çalıştırmak "Already up to date." der; sorunu giderdikten sonra ./scripts/update.sh --force ya da ./scripts/install.sh çalıştırın. Kurulum kendi sertifikasıyla çalışıyorsa (IP adresi ya da standart dışı port) son bekleme adımı sertifikayı doğrulayamayabilir ve güncelleme uygulanmış olsa da 150 saniye sonra hata verebilir; sürümü Ayarlar > Güncellemeler’den doğrulayın. "Download failed" hatası lisans anahtarından, ağdan ya da güncelleme hakkının sona ermesinden gelebilir; betik sunucunun açıklamasını göstermez, nedeni Ayarlar > Güncellemeler’de görünür.

Paketi kendiniz indirdiyseniz (kapalı ağ ya da ilk geçiş) yükseltme ilk kurulumla aynı betikle yapılır. Betik mevcut ayarlarını (adres, portlar, lisans anahtarı, e-posta yapılandırması) korur, yalnız eksik yeni ayarları tamamlar, yeni imajları yükler, veritabanı migrasyonlarını uygular ve zamanlanmış görevleri tazeler. Yeni bir sürüm çıktığında Ayarlar > Güncellemeler ekranında görünür; "Şimdi kontrol et" ile beklemeden de bakabilirsin.

Güncellemeden önce yedek: betik mevcut bir kurulum bulduğunda, yeni imajları yüklemeden ÖNCE "Back up before updating? [Y/n]" diye sorar; varsayılan evettir. Evet dersen ./scripts/backup.sh ile kurulu (eski) sürümün yedeğini alır ve doğrular. Yedek alınamazsa güncelleme UYGULANMAZ ve hiçbir şey değişmemiş olur; sorunu giderip betiği yeniden çalıştırırsın. Veritabanı çalışmıyorsa yedek için yalnız veritabanı başlatılır, uygulama kapalı kalır. İlk kurulumda bu soru sorulmaz. Terminal olmadan çalıştırıldığında (otomasyon) ve seçenek verilmemişse betik güvenli tarafı seçer: güncellemeden önce yedek alır ve bunu çıktıda belirtir.

SeçenekNe yapar
--backupGüncellemede sormadan yedek alır
--no-backupGüncellemeden önceki yedeği bilerek atlar (önerilmez); betik "Updating WITHOUT a backup." uyarısını yazar
--daily-backup / --no-daily-backupGünlük otomatik yedeği sormadan açar / kapatır
  1. 1Sürüm notlarını oku; "Dikkat" işaretli maddeler davranış değişikliğidir ve ekibini etkileyebilir.
  2. 2Yükseltme sırasında geçici olarak yaklaşık 1 GB boş disk bulundur: yeni imaj yazılırken eskisi hâlâ diskte durur. Güncellemeden önce alınan yedek de kurulum dizinindeki backups/ altında yer kaplar.
  3. 3Yeni paketi indir ve sunucuda kurulum dizininin üstüne çıkart.
  4. 4./scripts/install.sh çalıştır. Kurulumdaki sorular yeniden sorulmaz, kayıtlı ayarların kullanılır; "Back up before updating? [Y/n]" sorusunu cevaplarsın (Enter evet demektir). v1.61.1’den eski bir kurulumda önce bir kez "Set up a daily automatic backup? [Y/n]" de sorulur.
  5. 5Betik önce eski sürümün yedeğini alıp doğrular, sonra yeni imajları yükler. Migrasyonlar açılışta kendiliğinden uygulanır; betik sonunda zamanlanmış görevleri bir kez deneyip sonucu bildirir. Güncellemede "ilk kayıt olan yönetici olur" uyarısı çıkmaz, onun yerine mevcut kullanıcıların, verinin ve ayarların değişmediği yazılır.
  6. 6Bittiğinde eski imajları docker image prune -a ile temizleyebilirsin; çalışan konteynerlerin kullandıkları silinmez.
# paketi elle indirdiyseniz: kurulum dizininin üstüne çıkart, sonra
# if you downloaded the package yourself: extract it over the install directory, then
cd myway-onprem   # kurulum dizininiz / your install directory
./scripts/install.sh   # önce yedek almayı sorar (varsayılan evet) / asks to back up first (default yes)

Yalnız docker load ve docker compose up -d ile elle GÜNCELLEMEYİN. Uygulama güncellenir ama güncellemeden önce yedek alınmaz, zamanlanmış görevler kurulmaz ve yeni sürümün getirdiği ayar satırları .env.onprem dosyasına eklenmez: son tarih bildirimleri ve gözden geçirme hatırlatmaları hiçbir hata görünmeden sessizce çalışmamaya başlar. Bu işleri yapan yol kurulum betiğidir; ./scripts/update.sh de onu çağırır.

Migrasyonlar ileriye dönüktür; geri almanın yolu güncellemeden önce alınan yedektir, bu yüzden yedek sorusunu evet diye geç. Sürüm atlamak sorun değil: aradaki migrasyonlar sırayla uygulanır, tek tek her sürüme uğramanız gerekmez. Yükseltmeden sonra ilk girişte "Neler yeni" kutusu bu sürümün getirdiklerini bir kez gösterir.