QueryProxy
Doküman menüsü

Yedekleme ve geri yükleme

QueryProxy kurulumunda nelerin yedekleneceği, SQLite'ın güvenle nasıl kopyalanacağı, Litestream ile çoğaltma ve APP_KEY'in saklanıp geri yüklenmesi.

Güncelleme:

Bir QueryProxy yedeğinin birbirinden ayrıldığında işe yaramayan iki yarısı vardır: veri (uygulama veritabanı ve sonuç dosyaları) ve içindeki saklanan bağlantı kimlik bilgilerinin, chat secret’larının, maskeleme anahtarlarının ve TLS sertifikalarının şifresini çözen APP_KEY. İkisini de yedekleyin ve farklı yerlerde tutun.

Nelerin yedekleneceği

Ne Nerede durur Notlar
Uygulama veritabanı Data volume’deki database.sqlite ya da DB_*’nin işaret ettiği MySQL, MariaDB veya PostgreSQL veritabanı Kullanıcılar, takımlar, bağlantılar (şifreli), talepler, maskeleme kuralları, denetim günlüğü
APP_KEY APP_KEY değişkeni, APP_KEY_FILE ya da data volume’deki üretilmiş .app_key Onsuz şifreli sütunlar okunamaz. Bkz. anahtar
Sonuç dosyaları QUERYPROXY_RESULT_DISK diski; varsayılan olarak data volume’de storage/app/private/results Maskelenmiş NDJSON dosyaları. QUERYPROXY_RESULT_TTL_DAYS sonra silinirler; bu yüzden birçok kurulum bunları atlar
Ortamınız -e bayrakları, --env-file ya da compose dosyası Aynı yapılandırmayı yeniden başlatmak için gerekir

Data volume (/var/www/html/storage/app) SQLite veritabanını, üretilmiş anahtar dosyasını ve sonuç dosyalarını tutar. storage/app/tls altındaki TLS dosyaları çalışma anında veritabanındaki şifreli değerlerden yazılır; bu yüzden veritabanıyla birlikte geri gelirler.

Anahtar volume’deyse yedek, anahtarı koruduğu verinin yanında taşır. Arşivi yalnızca sahibinin okuyabileceği şekilde yazın (umask 077) ve onu anahtarın kendisi kadar özenle saklayın. Daha iyisi, APP_KEY’i volume’ün dışından verin; anahtar dosyası SQLite veritabanıyla aynı volume’ü paylaştığında queryproxy:doctor uyarır.

SQLite veritabanını kopyalama

En basit yedek README’deki yedektir: konteyneri durdurun ve volume’ü arşivleyin. Konteyner durduğu için hiçbir şey yazmaz; dolayısıyla kopya tutarlıdır.

Konteyner çalışırken veritabanını kopyalamak için, sqlite3 komut satırı aracı olan (QueryProxy image’ı bunu içermez) ve volume’ü okuyabilen bir makineden SQLite’ın kendi .backup komutunu kullanın:

sqlite3 /path/to/database.sqlite ".backup '/backups/queryproxy-$(date +%F).sqlite'"

.backup, SQLite’ın online backup mekanizmasını kullanır. SQLite, online backup sırasında diğer bağlantıların yazmaya devam edebileceğini ve başka bir süreçten gelen bir yazmanın genellikle kopyayı yeniden başlattığını belgeler; sürekli yoğun yazma altında bir kopya hiç bitmeyebilir. Bir QueryProxy kurulumu az yazar, bu yüzden bu nadiren önemli olur; yine de komutun çıkış kodunun 0 olduğunu kontrol edin. QueryProxy çalışırken database.sqlite’ı cp ya da tar ile kopyalamayın: dosya yazılmanın ortasında olabilir ve journal ya da WAL yan dosyaları (-journal, -wal, -shm; son ikisi Litestream veritabanını WAL’a geçirdikten sonra) ana dosyanın içermediği değişiklikleri taşıyabilir.

MySQL, MariaDB ve PostgreSQL için, her uygulama veritabanında olduğu gibi veritabanının kendi araçlarını (mysqldump, pg_dump ya da snapshot’lar) kullanın.

Litestream ile sürekli çoğaltma

Gecelik bir kopya yerine dakikalar öncesine ait bir geri yükleme noktası istiyorsanız, Litestream bir SQLite veritabanını S3 gibi bir nesne depolamasına çoğaltır. QueryProxy’nin parçası değildir ve QueryProxy test paketi onu çalıştırmaz; bu yüzden ona güvenmeden önce bir staging kopyasında geri yüklemeyi prova edin.

Litestream yalnızca SQLite’ın WAL journal moduyla çalışır ve uygulama geçirmediyse veritabanını buna geçirir. Checkpoint yaparken kısa yazma kilitleri alır. Veritabanı başına bir Litestream süreci çalıştırın ve başka hiçbir kurulumun kullanmadığı bir yola çoğaltın: belgeleri, birden çok uygulamanın aynı bucket ve yola çoğaltmasının geri yükleyememenize yol açabileceği konusunda uyarır.

Asgari bir yapılandırma:

dbs:
  - path: /var/www/html/storage/app/database.sqlite
    replica:
      type: s3
      bucket: my-queryproxy-backups
      path: queryproxy
      region: eu-central-1

Litestream AWS_ACCESS_KEY_ID ve AWS_SECRET_ACCESS_KEY değerlerini ortamdan okur. Aynı data volume’ü bağlayan bir sidecar olarak çalıştırın. Geri yükleme komutu replica URL’sini ve bir çıktı yolunu alır:

litestream restore -o /restore/database.sqlite s3://my-queryproxy-backups/queryproxy

Litestream yalnızca veritabanını çoğaltır. APP_KEY ve sonuç dosyaları bunun içinde değildir.

APP_KEY

Anahtara kurulumun en değerli secret’ı gibi davranın. Her hedef veritabanı kimlik bilgisini, chat imzalama secret’larını, takım başına maskeleme anahtarlarını ve saklanan TLS sertifikalarını şifreler. Kaybolmuş bir anahtar geri getirilemez ve özgün anahtarı olmadan başlatılan bir konteyner yenisini üretir ve bunların hiçbirini okuyamaz.

İşe yarayan bir emanet (escrow) prosedürü:

  1. Bir kez, açıkça üretin ve data volume’ün dışında tutun: docker run --rm queryproxy/queryproxy php artisan key:generate --show.
  2. Bir secret manager’da ya da ikinci bir kişinin açabileceği mühürlü bir zarfta saklayın: en az iki sorumlu, iki ayrı yerde; hiçbiri yedek depolaması olmasın.
  3. APP_KEY ya da APP_KEY_FILE ile verin (bir Docker ya da Kubernetes secret’ı), bkz. Yapılandırma.
  4. Döndürmeleri kaydedin. Döndürdüğünüzde eski anahtarı APP_PREVIOUS_KEYS içine taşıyın (virgülle ayrılmış); böylece eski şifreli veri hâlâ çözülür; ikisini de saklayın. Döndürmeden önce alınmış bir yedek, o sırada geçerli olan anahtara ihtiyaç duyar.
  5. Test edin. Her döndürmeden ya da geri yüklemeden sonra queryproxy:doctor, anahtarın saklanan kimlik bilgilerinin şifresini çözüp çözemediğini bildirir (app_key kontrolüne bakın).

Geri yükleme

  1. Konteyneri durdurun ve kaldırın (docker stop queryproxy && docker rm queryproxy).

  2. Veriyi geri koyun. README’deki gibi yapılmış bir arşiv için:

    [!WARNING] İkinci komut, yedeği açmadan önce queryproxy-data volume’ündeki her şeyi siler. Önce arşivin istediğiniz arşiv olduğunu kontrol edin.

    docker run --rm -v queryproxy-data:/data -v "$PWD":/backup alpine \
      sh -c 'find /data -mindepth 1 -delete \
        && tar xzf /backup/queryproxy-data.tgz -C /data'

    SQLite için, çalıştırıyorsanız önce Litestream sidecar’ını durdurun: çalışan bir sidecar geri yüklenen dosyayı mevcut replica’nın üzerine çoğaltabilir. Ardından eski veritabanının yanındaki database.sqlite-wal, database.sqlite-shm ve database.sqlite-journal dosyalarını silin; SQLite artakalan bir WAL’ı geri yüklenen dosyaya uygular ve onu bozar. Bundan sonra bir .backup kopyasını DB_DATABASE yoluna volume’de database.sqlite olarak yerleştirin ya da litestream restore -o <path> komutunu henüz dosya bulunmayan bir yola çalıştırın (önce eski veritabanı dosyasını kaldırın). MySQL, MariaDB ve PostgreSQL için veritabanını kendi araçlarıyla geri yükleyin.

  3. Yedeğin geldiği aynı sürümü, aynı ortam dosyasıyla ve aynı APP_KEY ile (döndürdüyseniz APP_PREVIOUS_KEYS ile birlikte) başlatın.

  4. Sonucu kontrol edin:

    docker exec queryproxy php artisan queryproxy:doctor
    docker exec queryproxy php artisan audit:verify

    app_key ok olmalı ve audit:verify zincirin sağlam olduğunu bildirmelidir. Geri yüklenen bir kopyadaki kopukluk, kopyanın kendisinin hasarlı olduğu anlamına gelir (örneğin QueryProxy yazarken alınmış düz bir dosya kopyası); önceki yedeği deneyin. Bkz. Denetim zinciri ve SIEM dışa aktarımı.

  5. Plan buysa yükseltmeyi ancak bundan sonra yapın.

Geri yüklenmiş bir kurulumda, chat düğmeleri saatler ya da günler önceki mesajlara ait olan pending talepler olabilir. Böyle bir mesajın düğmelerinin süresi dolmuş olabilir; hatırlatma, hâlâ pending olan bir talep için yeni bir kart gönderir. Taleplerin kendisi asla süresi dolup düşmez.

Sonraki adımlar

Gezinmek için ok tuşları, açmak için Enter.