SSD Nodes Learn 🎉 VPS $5.50/aydan başlayan
Rehberler Matt ConnorYazan Matt Connor

Docker Compose yığını yedekleme ve yükseltme rehberi

Docker Compose yığınlarını güvenle yedeklemek ve yükseltmek için izlenmesi gereken adımlar. Veritabanı dökümü, volume yedekleme ve sürüm geçişi öncesi kritik uyarılar burada.

Bir Docker Compose yığınının yedeklemesi neleri içermelidir

Bir Docker Compose yığını yedeklemesi dört ayrı öğeyi barındırmalıdır; bunlardan herhangi birinin kaybı uygulamanın geri yüklenememesine neden olur: compose dosyası, yanındaki .env, tüm volume içerikleri ve veritabanının kendi istemcisi tarafından oluşturulan bir veritabanı dökümü. Veritabanı container'ı çalışırken dosyalarını kopyalamak bir yedekleme yöntemi değildir. Yükseltme işlemleri de aynı listeyi gerektirir, ancak ek bir kuralı vardır: yedeklemeyi pull komutunu çalıştırmadan önce alın; çünkü şema migrasyonları ileriye dönük çalışacak şekilde yazılır ve çoğu proje geri dönüş yolu sunmaz.

Aşağıdaki her şey, yığının halihazırda dağıtılmış olduğunu ve docker compose ps komutunun servisin çalıştığını gösterdiğini varsayar. Örneklerde /srv/myapp dizininde bulunan ve app ile db isimli servislere sahip bir proje dizini kullanılmıştır. Kendi isimlerinizi kullanın. Komutlar kasıtlı olarak genel tutulmuştur; çünkü önemli olan kısımlar, yani volume'lar ve veritabanı, uygulama ne olursa olsun aynı şekilde çalışır.

Yığınınızın gerçekte ne depoladığını belirleyin

cd /srv/myapp
docker compose ps
docker compose config --volumes
docker volume ls --filter label=com.docker.compose.project=myapp

docker compose config --volumes, dosyanızda tanımlanan adlandırılmış birimlerin kısa adlarını yazdırır. docker volume ls, bu birimlerin disk üzerinde gerçekten sahip olduğu adları yazdırır. Compose, proje adını başına eklediği için bu iki liste birbirinden farklıdır: dosyada db_data olarak yazılan bir birim, diskte myapp_db_data olarak bulunur. Proje adı varsayılan olarak dizin adıdır; bu nedenle dizini yeniden adlandırmak, yığını yeni ve boş bir birim kümesine yönlendirir ve eski birimleri verilerinizle dolu halde bırakır. Aşağıdaki her komut, docker volume ls çıktısındaki gerçek adı gerektirir.

Bind mount'lar bu listelerin hiçbirinde görünmez. Compose dosyasında bunlar, iki noktanın solunda bir ana makine yolu bulunan girişlerdir, ./config:/app/config. Bunlar ana makine üzerindeki sıradan dizinlerdir, bu nedenle standart araçlarla erişilebilirler. Adlandırılmış birimler /var/lib/docker/volumes/ altında yaşar ve docker volume inspect --format '{{.Mountpoint}}' myapp_db_data, bunlardan birinin tam yolunu yazdırır. Yığınınızın hangi türü kullandığı, onu nasıl kopyalayacağınızı değiştirir ve bind mount'lar ile adlandırılmış birimler konusu bu iki yöntem arasındaki farkları tüm detaylarıyla ele alır.

Şimdi bulduklarınızı iki gruba ayırın. Bazı birimler, başka hiçbir şekilde yeniden oluşturulamayacak durum verilerini tutar: yüklenen dosyalar, oluşturulan anahtarlar, veritabanının kendisi ve kullanıcının uygulamaya girdiği her türlü veri. Diğerleri ise uygulamanın kendi kendine yeniden oluşturabileceği küçük resimler ve arama dizinleri gibi türetilmiş verileri tutar. İkinci grubu yedeklemek disk alanı ve geri yükleme süresi harcar ancak hiçbir fayda sağlamaz. Bir Redis önbellek birimi bunun en net örneğidir: onu kaybetmenin maliyeti, yalnızca ilk isteğin yavaş gerçekleşmesidir.

Compose dosyasını ve .env dosyasını yedekleyin

Her iki dosya da ana makinede yan yana bulunur ve hiçbiri bir volume içerisinde yer almaz. .env dosyası veritabanı parolasını, uygulama gizli anahtarını ve tüm API token'larını tutar; bu nedenle bir yığın volume'u tekrar çalışan bir uygulamaya dönüştüren dosya budur. Ayrıca genellikle .gitignore içerisinde listelenir, bu da "yapılandırmam git üzerinde" planının en önemli tek dosyayı dışarıda bıraktığı anlamına gelir. Gizli bilgileri bir env dosyasında tutmak doğru yöntemdir ve bu durum yedekleme sürecinize eşleşen bir sorumluluk yükler.

sudo install -d -m 700 -o "$USER" -g "$(id -gn)" /srv/backups/myapp
cp -a compose.yaml .env /srv/backups/myapp/
chmod 600 /srv/backups/myapp/.env

Sadece ilkini değil, stack'in kullandığı tüm compose dosyalarını kopyalayın. -f compose.yaml -f compose.prod.yaml ile başlatılan bir stack, her iki dosyanın da aynı şekilde geri gelmesine ihtiyaç duyar ve birden fazla compose dosyasının nasıl birleştiği, hangi değerlerin gerçekte container'a ulaşacağını belirler.

Bir uyarı, .env ile volume'lar arasında bir bağ kurar. Resmi Postgres imajı, POSTGRES_PASSWORD değerini yalnızca boş bir veri dizinini başlattığı sırada okur. Bu değeri daha sonra değiştirmek, veritabanı içindeki parolayı değiştirmez. Geçen ayın volume'unu bugünün .env dosyasıyla yan yana geri yüklerseniz, uygulama FATAL: password authentication failed for user "appuser" hatasıyla bağlantı kuramaz; oysa her iki dosya da incelendiğinde doğru görünür. .env dosyasını ve volume'ları aynı ana ait olacak şekilde birlikte yedekleyin.

Veritabanını kendi istemcisi ile yedekleme

Bir veritabanı sunucusu dosyalarına sürekli yazma işlemi yapar. Sunucu çalışırken alınan bir tar veya /var/lib/postgresql/data, bazı sayfaları yazma öncesinden, bazılarını ise yazma sonrasından kopyalar; bu nedenle arşiv, tutarlı bir şekilde yeniden oynatılamayacak farklı zaman dilimlerinin bir karışımını içerir. Bir dump aracı ise veriyi tek bir işlem (transaction) içerisinde okur, böylece dosya tek ve tutarlı bir anı yansıtır. Yedekleme ile kopyalama arasındaki fark budur.

docker compose exec -T db sh -c \
  'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc' \
  > /srv/backups/myapp/db-$(date +%F).dump

-T bayrağını koruyun. Bu bayrak TTY tahsisini kapatır; TTY bağlıyken Docker çıktı akışını kabuğunuza iletirken dönüştürür ve bu durum ikili (binary) dump dosyasını bozar. Bu durumu ancak geri yükleme işlemi başarısız olduğunda fark edersiniz. Tek tırnak işaretleri de önemlidir: bunlar, ana makinenizdeki kabuğun $POSTGRES_USER değişkenini genişletmesini engeller; böylece değişken, compose dosyasında halihazırda tanımlı olan değerler kullanılarak container içindeki kabuk tarafından genişletilir. -Fc, veriyi yazarken sıkıştıran ve daha sonra pg_restore ile nesnelerin seçilmesine olanak tanıyan özel bir formatta çıktı üretir.

Roller ve parolaları herhangi bir veritabanının dışında tutulur, bu yüzden onları da yedekleyin:

docker compose exec -T db sh -c 'pg_dumpall -U "$POSTGRES_USER" --globals-only' \
  > /srv/backups/myapp/globals.sql

Ardından dosyanın bir dump dosyası olduğunu, hata mesajı içermediğini kontrol edin:

ls -lh /srv/backups/myapp/
head -c 5 /srv/backups/myapp/db-$(date +%F).dump

Özel formatlı bir dump dosyası PGDMP baytlarıyla başlar. Sıfır baytlık veya pg_dump: ile başlayan bir dosya, komutun başarısız olduğu anlamına gelir. Kabuk, komut çalışmadan önce çıktı dosyasını oluşturur; bu nedenle başarısız bir dump işlemi, makul bir isim ve zaman damgasına sahip bir dosya bırakır. Bu, en sık karşılaşılan sessiz yedekleme hatasıdır.

MariaDB veya MySQL için istemci değişse de yöntem aynı kalır:

docker compose exec -T db sh -c \
  'mariadb-dump -u root -p"$MARIADB_ROOT_PASSWORD" --single-transaction --databases "$MARIADB_DATABASE"' \
  > /srv/backups/myapp/db-$(date +%F).sql

--single-transaction, yazma işlemlerini engellemeden InnoDB tablolarının tutarlı bir dump'ını alır. MySQL imajında komut mysqldump, değişkenler ise MYSQL_ROOT_PASSWORD ve MYSQL_DATABASE şeklindedir. Güncel MariaDB imajlarında mysqldump, mariadb-dump için uyumluluk adı olarak çalışmaya devam eder. Komut satırında verilen parolanın, dump işlemi sürdüğü sürece container'ın süreç listesinde görüneceğini unutmayın.

SQLite özel bir dikkat gerektirir. Veritabanı tek bir dosyadır ancak yakın zamandaki işlemler hala yanında ayrı bir -wal dosyasında bekliyor olabilir; bu nedenle sadece .db dosyasını kopyalamak, en son yazılan verilerin eksik olduğu bir veritabanı ile sonuçlanır. Eğer imaj istemciyi içeriyorsa, sqlite3 /data/app.db ".backup '/data/app-backup.db'" uygulamayı çalışırken tutarlı bir kopya oluşturur. Eğer istemci yoksa, container'ı durdurun ve .db dosyasını, -wal ve -shm eşlikçileriyle birlikte kopyalayın.

Veritabanınız yığın (stack) içinde değil de ana makinede çalışıyorsa, aynı komutlar docker compose exec ön eki olmadan geçerlidir ve bir sonraki yeniden yapılandırmanızdan önce veritabanını Docker içinde veya ana makinede çalıştırma konusunu okumanız faydalı olacaktır.

Volume'leri yakalama

Adlandırılmış bir volume, elle düzenlemeniz gereken bir host yoluna sahip değildir; bu nedenle onu geçici bir container içine mount edin ve oradan arşivleyin.

docker run --rm \
  -v myapp_uploads:/data:ro \
  -v /srv/backups/myapp:/backup \
  alpine:3 tar czf /backup/uploads.tar.gz -C /data .

Yardımcı container, volume'ü /data dizinine salt okunur (read-only) olarak, yedekleme dizininizi ise /backup dizinine mount eder ve ardından arşivi host tarafına yazar. --rm, tar komutu sonlanır sonlanmaz yardımcı container'ı kaldırır. :ro bayrağı önemlidir, çünkü hatalı yazılmış bir tar komutu bu sayede kaynağa zarar veremez. -C /data ., geri yükleme işleminin doğru yere yapılmasını sağlar: tüm yolları volume kök dizinine göreli olarak saklar. Bunun yerine tar czf /backup/uploads.tar.gz /data yazarsanız her yolun başına bir data/ eklenir; bu durumda geri yükleme işlemi volume içinde /data/data dizinini oluşturur ve uygulama boş bir dizin görür. Arşiv root kullanıcısına aittir, çünkü tar işlemi container içinde root yetkisiyle çalıştırılmıştır. Bu durum bir engel teşkil ediyorsa sudo chown "$USER" /srv/backups/myapp/uploads.tar.gz komutunu çalıştırın; geri yüklenen dosyalar uygulama tarafından okunamaz durumdaysa PUID ve PGID'nin dosya sahipliğini nasıl belirlediği hakkındaki bilgileri okuyun.

Bu işlemi her adlandırılmış volume için bir kez çalıştırın. Bind mount'lar için herhangi bir container'a gerek yoktur: tar czf /srv/backups/myapp/config.tar.gz -C /srv/myapp/config . komutu aynı işi host üzerinde yapar.

Uygulamanın durdurulması gerekip gerekmediğine her volume için ayrı karar verin. Uygulamanın üzerinde sürekli yazma işlemi yaptığı bir volume'ün canlı tar yedeğini almak, bir dosyanın yazılma anında yarım kalmasına neden olabilir. Dosyaların bir kez yazılıp ardından sadece okunduğu bir yükleme dizini için bu risk düşüktür. Diğer tüm durumlar için, kopyalama süresi boyunca ilgili servisi docker compose stop app ile durdurun ve ardından docker compose start app komutunu kullanın. stop, container'ları ve volume'leri yerinde bırakır; bu tam olarak burada istediğiniz durumdur. Komutları girmeden önce down ve stop arasındaki fark konusundan emin olmanızda fayda vardır.

Veritabanı volume'ünün tar yedeğini, veritabanı yedeğiniz olarak görmeyin. Yedek, dump dosyasıdır. Durdurulmuş bir veritabanının volume arşivi, yalnızca hızlı bir yeniden oluşturma yöntemi olarak işe yarar, fazlası değildir.

İşlem sırası

  1. Compose dosyalarını ve .env öğesini yedekleme dizinine kopyalayın.
  2. Veritabanını çalışır durumdayken dump edin.
  3. Eğer volume içerikleri yerinde değişiyorsa uygulama container'ını durdurun.
  4. Her bir named volume ve bind-mount dizinini arşivleyin.
  5. Durdurduğunuz tüm servisleri başlatın ve ardından docker compose ps ile doğrulayın.
  6. Stack üzerinde çalışan image etiketlerini ve digest değerlerini not edin.
  7. Tüm yedekleme dizinini bu sunucudan başka bir yere kopyalayın.
  1. adım, genellikle sonraya bırakılan adımdır.

Yedeği sunucudan dışarı aktarın

Yedeklerin, yığınla aynı disk üzerinde tutulması sizi yalnızca kendi hatalarınıza karşı korur; başka hiçbir riske karşı koruma sağlamaz. Bir disk biriminin arızalanması, sunucunun silinmesi veya hesabın kaybedilmesi durumunda her iki kopya da aynı anda yok olur. Dizinleri, bu VPS'ten bağımsız bir depolama alanına, belirli bir zaman çizelgesi ve saklama politikası dahilinde gönderin. VPS üzerinden restic yedekleri rehberi, depo kurulumunu, saklama bayraklarını ve kontrol komutlarını ele almaktadır; bu nedenle burada tekrar edilmesine gerek yoktur.

restic, dökümü doğrudan bir pipe üzerinden okuyabilir; bu sayede düz metin halindeki veritabanı hiçbir şekilde diske yazılmaz:

docker compose exec -T db sh -c 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc' \
  | restic backup --stdin --stdin-filename db.dump

Hangi aracı kullanırsanız kullanın, zamanlamayı bir systemd timer veya cron job içerisine yerleştirin ve görevin başarısız olması durumunda bildirim alacağınız bir mekanizma kurun. Çıktısı hiçbir yere ulaşmayan bir yedekleme betiği, altı ay boyunca çalışmayı durdursa bile kimsenin haberdar olamayacağı bir betiktir.

Yedekleme işleminin çalıştığını bir geri yükleme tatbikatı ile doğrulayın

Geri yüklemesi yapılmamış bir yedekleme sadece bir varsayımdır. Aşağıdaki tatbikat, mevcut yığının yanında ikinci bir yığın oluşturarak geri yükleme yapar; böylece üretim ortamı hizmet vermeye devam eder ve yazdığınız hiçbir komut üretim ortamını etkilemez.

Mekanizma, proje adıdır. Docker Compose, proje adını dizin adından alır ve oluşturduğu her container ile volume üzerine damgalar. Yedeği yeni bir dizine kopyaladığınızda, geri yüklenen yığın kendi volume alanlarına otomatik olarak sahip olur.

sudo install -d -m 700 -o "$USER" -g "$(id -gn)" /srv/myapp-restore
cd /srv/myapp-restore
cp /srv/backups/myapp/compose.yaml /srv/backups/myapp/.env .

Kopyalanan compose dosyasını, yayınlanan ana makine portu çalışan yığınla çakışmayacak şekilde düzenleyin; 18080:8080 yerine 8080:8080 kullanın veya kopyalanan .env dosyasında bu değeri belirleyen değişkeni değiştirin. Ardından, hiçbir şeyi başlatmadan container'ları ve boş volume alanlarını oluşturun:

docker compose create
docker volume ls --filter label=com.docker.compose.project=myapp-restore

İkinci komut, üretim ortamındakiyle aynı volume adlarını, başında myapp-restore_ ile listelemelidir. Bu alanları doldurun, veritabanını tek başına başlatın ve dökümü yükleyin:

docker run --rm -v myapp-restore_uploads:/data -v /srv/backups/myapp:/backup \
  alpine:3 tar xzf /backup/uploads.tar.gz -C /data
docker compose up -d db
docker compose exec -T db sh -c \
  'pg_restore -U "$POSTGRES_USER" -d "$POSTGRES_DB" --clean --if-exists' \
  < /srv/backups/myapp/db-2026-08-16.dump

--clean --if-exists, her nesneyi yeniden oluşturmadan önce siler; bu da geri yükleme işleminin tekrarlanabilir olmasını sağlar. Bu parametre olmadan, halihazırda tabloları içeren bir veritabanına ikinci bir çalıştırma denemesi pg_restore: error: could not execute query: ERROR: relation "users" already exists hatası ile durur.

Ardından geri kalan servisleri başlatın ve bir kullanıcının yapacağı şekilde kontrol edin:

docker compose up -d --wait
docker compose exec -T db sh -c 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "\dt"'
docker compose logs --tail=50

docker compose up -d --wait, her servis çalışır veya sağlıklı durumda olduğunu bildirene kadar bekler ve herhangi biri bu duruma gelmezse sıfır olmayan bir çıkış kodu döndürür; bu da adımın betiklenebilir olmasını sağlar. Bir servis hiçbir zaman sağlıklı duruma gelmezse, docker compose ps durumunu gösterir ve Compose healthchecks bu sütunun neyi okuduğunu açıklar. Daha sonra uygulamayı alternatif port üzerinden açın ve gerçek bir hesapla giriş yapın. Bir kayıt yazın ve bir volume içinde yaşayan bir dosyayı açın. Bu ikili kanıttır: döküm geri yüklendi, volume geri yüklendi ve ikisi birbiriyle uyumlu. Sadece giriş sayfasının görüntülendiğini kanıtlayan bir tatbikat, verileriniz hakkında hiçbir şey kanıtlamamış demektir.

Tatbikat başarıyla tamamlandığında ortamı kaldırın:

docker compose down -v

Bu, -v bayrağının doğru olduğu tek yerdir. Üretim dizininde aynı komutu çalıştırmak, korumaya çalıştığınız volume alanlarını siler.

Compose yığını nasıl yükseltilir

Mevcut sürümünüz ile hedeflediğiniz sürüm arasındaki tüm sürüm notlarını okuyun ve bu notlarda breaking (kırılma) ve migration (geçiş) terimlerini aratın. Birden fazla ana sürüm atlamayı desteklemeyen projeler bunu notlarda belirtir; başarısız olan bir geçiş işlemi, genellikle şemanın bir kısmını değiştirdikten sonra hata verir.

Herhangi bir değişiklik yapmadan önce şu an ne çalıştırdığınızı kaydedin:

docker compose images
docker image inspect --format '{{index .RepoDigests 0}}' postgres:16.4

docker compose images, her servisin şu anda kullandığı imajı ve etiketi listeler. Bir etiket her an başka bir noktayı işaret edecek şekilde değiştirilebildiğinden, bir imajı tam olarak tanımlayan tek değer digest (özet) bilgisidir.

Yukarıdaki bölümlerde belirtilen yedekleri alın ve sunucu dışına kopyalayın. Bunu küçük güncellemeler (patch release) için de yapın. İnsanların hazırlık yapmayı bıraktığı durumlar, genellikle en ucuz atlatılan yükseltmelerdir.

Ardından, compose dosyasındaki sürümü sabitleyin, çünkü latest bir sürüm numarası değildir:

services:
  db:
    image: postgres:16.4

image: postgres:latest kullanıldığında, docker compose pull o etiketin bugün işaret ettiği her neyse onu çeker ve dün ne çalıştırdığınızı tanımlamanızın bir yolu kalmaz. Sabitlenmiş bir etiket, yükseltme işlemini git diff içinde okuyabileceğiniz ve tek bir düzenleme ile geri alabileceğiniz tek satırlık bir işleme dönüştürür. Uygulama imajını da aynı şekilde, projenin sürüm sayfasındaki tam sürüm numarasını kullanarak sabitleyin.

İmajları çekin ve yeniden oluşturun:

docker compose pull
docker compose up -d --wait

docker compose up -d, dosyayı çalışan container'lar ile karşılaştırır ve yalnızca imajı veya yapılandırması değişen servisleri yeniden oluşturur. İsimlendirilmiş volume'lere dokunmaz, bu nedenle yeni container mevcut veriler üzerinde başlar. İşlemin amacı budur ancak risk de buradadır; çünkü yeni sürümün ilk başlatılması genellikle şema geçişinin çalıştığı andır.

Süreci izleyin:

docker compose ps
docker compose logs -f --tail=100 app

Başarısız olan bir container, docker compose ps çıktısının STATUS sütununda Exited (1) durumunu gösterir; hata nedeni ise log kayıtlarının son satırlarında yer alır. Geçiş hataları burada belirgindir, başka hiçbir yerde görünmez. Loglar durulduğunda sisteme giriş yapın ve uygulamayı bir dakika boyunca test edin.

Eğer docker compose pull, no space left on device hatası ile durursa, bunun yaygın nedeni eski imaj katmanlarıdır; kullanılmayan Docker imajlarının temizlenmesi ile disk alanı geri kazanılabilir. Temizleme işlemini yükseltme başarılı olduktan sonra yapın, öncesinde değil; çünkü hızlı bir geri alma (rollback) işlemi bu eski katmanlar üzerinde gerçekleşir.

Yükseltme başarısız olduğunda geri alma yöntemi

İki farklı durum söz konusudur ve maliyetleri birbirinden oldukça farklıdır. Yeni sürüm veritabanı şemasını değiştirmediyse, geri alma işlemi tek satırlık bir komuttur: eski etiketi (tag) compose dosyasına geri yazın ve docker compose up -d komutunu çalıştırın. Container değiştirilir, volume'lar yerinde kalır ve eski kod daha önce yazdığı veriyi okumaya devam eder.

Yeni sürüm şema göçü (migration) gerçekleştirdiyse, eski kod artık veriyi okuyamaz. Göç betikleri ileriye dönük çalışacak şekilde yazılır ve çoğu proje herhangi bir sürüm düşürme (downgrade) betiği içermez. Bu durumda eski sürüm başlar ancak yeniden adlandırılan veya silinen bir sütuna yönelik ilk sorguda ERROR: column "avatar_url" does not exist biçimindeki hatalarla başarısız olur. Geri dönüş yolu, yükseltme öncesinde aldığınız dump dosyasıdır: eski etiketi geri yükleyin, veritabanı volume'unu kaldırın, boş bir volume oluşturun, dump dosyasını içine geri yükleyin ve servisi başlatın. Bu dump dosyası olmadan geri dönüş imkansızdır; yedeklemenin yükseltme işleminden önce yapılmasının temel nedeni budur.

Postgres ana sürüm yükseltmeleri bu durumun en kritik halidir ve genellikle yükseltme aşamasında değil, geri alma aşamasında sorun çıkardığı için kullanıcıları şaşırtır. Disk üzerindeki veri formatı her ana sürümde değişir. postgres:16.4 etiketini postgres:17.2 ile değiştirip docker compose up -d komutunu çalıştırdığınızda, yeni sunucu başlamayı reddeder:

FATAL:  database files are incompatible with server
DETAIL:  The data directory was initialized by PostgreSQL version 16, which is not compatible with this version 17.2.

Image dosyası sizin yerinize pg_upgrade işlemini gerçekleştirmez. Compose yığını içindeki desteklenen yöntem şudur: dump al, değiştir, geri yükle. Eski sürüm çalışırken dump alın, docker compose down komutunu kullanın, veritabanı volume'unu kaldırın, yeni etiketi ayarlayın, temiz ve boş bir veri dizini için docker compose create komutunu çalıştırın, veritabanını başlatın, dump dosyasını geri yükleyin ve diğer servisleri başlatın. Yeni ana sürüm bir gün boyunca gerçek trafiği sorunsuz karşılayana kadar eski dump dosyasını saklayın. Aynı ana sürüm içindeki küçük yükseltmelerde (örneğin 16.4'ten 16.9'a geçiş), veri formatı kararlı olduğu ve container doğrudan başlayabildiği için bu işlemlerin hiçbirine gerek yoktur.

VPS snapshot'ları bir yedekleme midir?

Bunlar yedeklemenin bir tamamlayıcısıdır ve her ikisi de farklı durumlarda başarısız olur. Snapshot, hypervisor seviyesinde tüm diski kopyalar; bu sayede yedeklemeyi unuttuğunuz kısımlar dahil olmak üzere tüm makineyi dakikalar içinde geri getirir. Bu durum onu tek bir iş için doğru araç yapar: yükseltme işlemi sunucuyu bozduğunda ve sunucuyu yirmi dakika önceki haline döndürmek istediğinizde.

Diğer tüm durumlar için yetersiz bir araçtır. Granülarite tüm makineyi kapsar; dolayısıyla silinen tek bir tabloyu kurtarmak, tüm sunucuyu başka bir yere geri yükleyip tabloyu içinden ayıklamanız gerektiği anlamına gelir. Saklama süresi genellikle kısadır. Kopyalar normalde sunucuyla aynı sağlayıcı hesabında tutulur; bu nedenle bir hesap kaybı, sunucuyu ve snapshot'larını aynı anda yok eder. Ayrıca çalışan bir makinenin snapshot'ı, veritabanını yazma işlemi sırasında yakalar; bu yüzden veritabanı ilk açılışta crash recovery gerçekleştirir ve o sırada devam eden tüm işlemler kaybolur.

Her ikisini de kullanın. Snapshot, bir yükseltme penceresi için geri alma düğmesidir. Dump ise hesap silinmesi gibi durumlarda hayatta kalan kopyadır. snapshot ve yedeklemelerin farkı bölümü, her birinin hangi hataları gerçekten karşıladığını detaylandırır. Aynı yedekleme dizini, bir stack'i yeni bir VPS'e taşıma işlemini hafızadan yeniden kurmak yerine rutin bir iş haline getiren şeydir.

Neler ters gider ve ne görürsünüz

down komutunda volumes bayrağı. docker compose down -v, dosyanın bildirdiği adlandırılmış birimleri siler ve Compose bunu Volume myapp_db_data Removed yazan bir satırla onaylar. Bunun geri dönüşü yoktur. Sade docker compose down komutu birimlere dokunmaz. Uzun biçimi olan docker compose down --volumes komutunu yazın; böylece yıkıcı bayrak, harf harf yazmanız gereken bir kelime haline gelir.

Sihirli dizge içermeyen bir döküm. pg_restore: error: did not find magic string in file header, dosyanın bir arşiv olmadığını gösterir. Bunun yaygın nedeni docker compose exec üzerinde -T eksikliğidir; çünkü bir TTY bağlıyken akış, kabuğunuza ulaşana kadar dönüştürülür ve ikili döküm hasarlı olarak ulaşır. Dökümü -T ile tekrar alın ve ardından ilk beş baytı head -c 5 ile kontrol edin.

Değişmeyen bir parola. Geri yükleme sonrası FATAL: password authentication failed for user "appuser" hatası, .env ile veri dizininin farklı zamanlara ait olduğu anlamına gelir. İmaj, parolayı yalnızca boş bir veri dizini oluşturduğunda ayarlar; bu nedenle .env dosyasını daha sonra düzenlemek veritabanı içinde hiçbir şeyi değiştirmez. Eşleşen .env dosyasını geri yükleyin veya parolayı veritabanı içinde ALTER USER ile değiştirin.

İkinci, boş bir birim. Docker, birimi talep üzerine oluşturur; bu nedenle s eksikken çalıştırılan docker run -v myapp_upload:/data komutu, yepyeni ve boş bir birime yazma yapar ve işlemin başarılı olduğunu bildirir. docker volume ls komutu daha sonra her iki ismi de gösterir ve bunlardan biri hiçbir veri içermez. Birim isimlerini ezberden yazmak yerine docker volume ls çıktısından kopyalayın.

Üretim ortamına yönelik bir geri yükleme. Geri yükleme komutlarını /srv/myapp-restore yerine /srv/myapp içinde çalıştırmak, canlı verilerin yedekle üzerine yazılmasına neden olur ve komutlar her iki yerde de aynı görünür. Her geri yükleme komutundan önce pwd değerini kontrol edin ve deneme çalışmalarını kendi dizininde tutun.

FAQ

docker compose down verilerimi siler mi?

Hayır. docker compose down, container'ları ve varsayılan ağı kaldırır ancak isimlendirilmiş volume'ları ve bind mount'ları olduğu gibi bırakır. docker compose down -v, dosyanızda tanımladığınız isimlendirilmiş volume'ları kaldırır ve bu işlem kalıcıdır. Bind mount'lar ana makine dizinleridir, bu nedenle Compose bunları asla kaldırmaz. Yedekleme sırasında servisleri durdurmak ancak diğer her şeyi olduğu gibi bırakmak istiyorsanız, bunun yerine docker compose stop kullanın.

pg_dump çalıştırmak yerine Postgres veri dizinini kopyalayabilir miyim?

Yalnızca container durdurulmuş durumdayken. Sunucu çalışırken dosyalar sürekli değişir ve kopyanız, tutarlı bir şekilde geri yüklenemeyecek farklı zaman dilimlerine ait verilerin bir karışımı olabilir. Dosya seviyesinde kopyalama ayrıca belirli bir Postgres ana sürümüne bağlıdır; bu nedenle farklı bir sürümde çalışmayacaktır. Container'ı durdurun, volume'u arşivleyin, tekrar başlatın ve elde ettiğiniz sonucu tek yedekleme yönteminiz olarak değil, hızlı bir yeniden oluşturma yolu olarak görün. Dump dosyası, taşınabilir olan ve geri yükleme yapacağınız asıl yedektir.

Compose içinde Postgres'i yeni bir ana sürüme nasıl yükseltirim?

Sadece tag değiştirmek yeterli değildir. Yeni sunucu, eski veri dizini üzerinde çalışmayı reddeder ve The data directory was initialized by PostgreSQL version 16, which is not compatible with this version 17.2 günlüğünü üretir. Eski sürüm çalışırken pg_dump komutunu çalıştırın, ardından docker compose down ile dump alın, veritabanı volume'unu kaldırın, yeni tag'i ayarlayın, boş bir volume oluşturmak için docker compose create komutunu çalıştırın, veritabanını başlatın ve dump dosyasını geri yükleyin. Yeni sürüm gerçek trafiği sorunsuz karşılayana kadar eski dump dosyasını saklayın.

Yedeklemeler ne sıklıkla çalışmalı ve ne kadar süre saklanmalı?

Yedekleme aralığını, yeniden yapmayı göze alabileceğiniz iş miktarına göre belirleyin. Günlük yedekleme, kişisel veya küçük ekipli yapılar için uygundur; ayrıca herhangi bir yükseltme işleminden hemen önce manuel bir yedek daha alınmalıdır. Saklama süresi için, fark etmediğiniz hasarları kapsayacak kadar geçmişi tutun; çünkü Cuma günü fark edilen bozuk bir tablo için Perşembe gecesi alınan yedek işe yaramayacaktır. restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune makul bir başlangıç politikasıdır. Program ne olursa olsun, üç ayda bir geri yükleme testi yapın. Bunu yapana kadar elinizde yedek değil, sadece dosyalar vardır.

Yedek almak için tüm yapıyı durdurmam gerekir mi?

Genellikle hayır. Veritabanı dump'ı sunucu çalışırken tutarlı kalır, bu nedenle veritabanı için kesinti gerekmez. Asıl soru volume'lardır. Uygulama yalnızca dosya ekliyorsa (örneğin bir yükleme dizini), canlı arşivleme yeterince güvenlidir. Eğer dosyaların üzerine yazıyorsa, kopyalama süresi boyunca ilgili servisi docker compose stop app ile durdurun ve işlem bittikten sonra tekrar başlatın. Veritabanı çalışmaya devam ederken uygulamayı durdurmak, genellikle sağlayabileceğiniz en kısa güvenli penceredir.