Docker & DevOps

    Docker Restart Politikaları

    no, on-failure, always ve unless-stopped politikalarının farkını ve doğru seçimini anlatan rehber.

    11 dk okuma Güncellendi: 25 Ağustos 2026

    Sunucunuz gece yarısı çekirdek güncellemesi sonrası yeniden başladı ve sabah siteye giren müşteri "bağlantı reddedildi" gördü. Konteynerler diskte duruyor, imajlar yerinde, hiçbir şey bozulmamış; sadece kimse onları tekrar başlatmamış. Ya da tam tersi: bir yapılandırma hatası yüzünden konteyner açılır açılmaz çıkıyor, Docker onu inatla yeniden başlatıyor, log dosyası saniyede yüzlerce satır büyüyor ve disk doluyor. Bu iki senaryonun ortak sebebi, Docker restart politikalarının varsayılan davranışının yanlış anlaşılmasıdır.

    Docker'ın dört restart politikası vardır ve aralarındaki farklar ilk bakışta kılı kırk yarmak gibi görünür; ama üretimde her birinin çok somut sonuçları olur. Bu rehberde dört politikanın tam davranışını, always ile unless-stopped arasındaki o meşhur ince farkı, geri çekilme (backoff) mekanizmasını ve yeniden başlatma sayacının ne zaman sıfırlandığını, Compose'daki restart: no YAML tuzağını, sunucu yeniden başladığında neyin gerçekten ayağa kalktığını ve restart politikasının sağlık kontrolünün yerini neden tutmadığını anlatacağım.

    Dört Politika ve Aralarındaki Fark#

    Bir konteynere restart politikası, oluşturma anında --restart bayrağıyla ya da Compose'da restart anahtarıyla verilir. Politika, konteynerin çıkış yapması durumunda Docker'ın ne yapacağını belirler. Dört seçenek ve davranışları şöyledir:

    PolitikaHata ile çıkıştaNormal (0) çıkıştaElle durdurulduğundaDocker yeniden başlarken
    no (varsayılan)BaşlatmazBaşlatmazBaşlatmazBaşlatmaz
    on-failure[:N]Başlatır (en fazla N kez)BaşlatmazBaşlatmazBaşlatır (hata ile durduysa)
    alwaysBaşlatırBaşlatırBaşlatmazBaşlatır
    unless-stoppedBaşlatırBaşlatırBaşlatmazBaşlatmaz

    Varsayılanın no olduğunu özellikle vurgulamak istiyorum. docker run ile başlattığınız her konteyner, siz açıkça belirtmediğiniz sürece bir daha asla kendiliğinden ayağa kalkmaz. Sunucu yeniden başladığında ya da Docker servisi güncellendiğinde bütün yığınınız yerde kalır. Üretimde çalışan hiçbir kalıcı servis no politikasında olmamalıdır.

    # Yeni konteyner olustururken
    docker run -d --name firmaniz-app --restart unless-stopped firmaniz/web:1.4.0
    
    # Zaten calisan bir konteynerin politikasini degistir - yeniden olusturmaya gerek yok
    docker update --restart unless-stopped firmaniz-app
    
    # Mevcut politikayi ve yeniden baslatma sayisini gor
    docker inspect --format='{{.Name}} {{.HostConfig.RestartPolicy.Name}} sayac={{.RestartCount}}' firmaniz-app
    

    docker update komutunu bilmek zaman kazandırır: politikayı değiştirmek için konteyneri silip yeniden oluşturmanız gerekmez, çalışan konteyner üzerinde anında uygulanır.

    always ile unless-stopped Arasındaki Kritik Fark#

    İki politika neredeyse aynıdır ve tek bir senaryoda ayrışır: Docker daemon yeniden başladığında, daha önce elle durdurduğunuz konteynere ne olur?

    always politikasındaki bir konteyneri docker stop ile durdurursanız o an ayağa kalkmaz, bu doğru. Ancak sunucu yeniden başladığında ya da Docker servisi yeniden başlatıldığında always konteyneri yeniden ayağa kalkar. Docker, "her zaman çalışsın" talimatını harfiyen uygular ve elle durdurma bilgisini daemon yeniden başlarken unutur.

    unless-stopped ise durdurma kararınızı hatırlar. Elle durdurduğunuz bir konteyner, sunucu yeniden başlasa bile durmuş kalır; onu siz açıkça başlatana kadar öyle kalır.

    # Senaryo: bakim icin bir servisi kasten durdurdunuz
    docker stop firmaniz-eski-api
    # Gece sunucu yeniden basladi...
    
    # --restart always ise: firmaniz-eski-api yeniden acilir (istemediginiz sey)
    # --restart unless-stopped ise: kapali kalir (istediginiz sey)
    

    Pratikte tavsiyem nettir: uzun ömürlü servisler için varsayılan tercihiniz unless-stopped olsun. Bir konteyneri kasten durdurduysanız bunun bir sebebi vardır ve o sebep sunucu yeniden başlayınca ortadan kalkmaz. always politikasını yalnızca "bu konteyner kesinlikle ve her koşulda ayakta olmalı" dediğiniz altyapı bileşenleri için, örneğin ters proxy'niz için tercih edin.

    on-failure ve Çıkış Kodları#

    on-failure politikası konteyneri yalnızca sıfırdan farklı bir çıkış koduyla sonlandığında yeniden başlatır. 0 ile çıkan bir konteyner işini başarıyla bitirmiş kabul edilir ve rahat bırakılır. Bu, tek seferlik işler için doğru politikadır: bir yedekleme betiği, bir migration konteyneri ya da bir rapor üretici geçici bir ağ hatası yüzünden başarısız olduysa tekrar denesin, ama işini bitirdiğinde sonsuza kadar dönüp durmasın.

    Deneme sayısını sınırlamak için iki nokta üst üste ile sayı verirsiniz:

    # En fazla 5 kez dene, sonra pes et
    docker run -d --name gece-yedek --restart on-failure:5 firmaniz/backup:1.0
    
    # Compose karsiligi
    #   restart: on-failure
    #   ya da uzun bicim: deploy.restart_policy.max_attempts
    

    Sınır koymanın değeri şudur: sınırsız on-failure, kalıcı bir hata (yanlış parola, eksik dosya, hatalı yapılandırma) karşısında sonsuz döngüye girer. Beş denemeden sonra duran bir konteyner, docker ps -a listesinde Exited (1) olarak durur ve size sorunu araştırma fırsatı verir; log dosyanızı da diski dolduracak kadar şişirmez. Konteynerin neden sürekli çıktığını teşhis etmek için konteyner sürekli yeniden başlıyor yazısındaki adımları izleyebilirsiniz.

    Çıkış kodlarının anlamını bilmek teşhisi hızlandırır:

    Çıkış koduGenellikle anlamı
    0Başarıyla tamamlandı
    1Uygulama hatası (yapılandırma, bağlantı, istisna)
    125Docker komutunun kendisi hatalı
    126Komut bulundu ama çalıştırılamadı (izin)
    127Komut bulunamadı (yol hatası, eksik ikili)
    137SIGKILL — çoğunlukla bellek yetersizliği (OOM)
    143SIGTERM — düzgün durdurma isteği

    137 gördüğünüzde ilk bakacağınız yer bellek sınırıdır: docker inspect --format='{{.State.OOMKilled}}' konteyner_adi komutu true dönüyorsa konteyner belleğe sığmamış demektir; restart politikası bu sorunu çözmez, sadece tekrarlatır.

    Geri Çekilme ve Sayacın Sıfırlanması#

    Docker, sürekli çöken bir konteyneri saniyede yüzlerce kez başlatarak sunucuyu yormaz. Yeniden başlatma denemeleri arasında üstel geri çekilme uygular: ilk bekleme çok kısadır, sonraki her denemede süre kabaca ikiye katlanır. Böylece kalıcı bir hata durumunda denemeler giderek seyrekleşir ve CPU tüketimi kontrol altında kalır.

    Bu mekanizmanın en kritik ayrıntısı, sayacın ne zaman sıfırlandığıdır: konteyner belirli bir süre kesintisiz çalışırsa yeniden başlatma sayacı sıfırlanır ve geri çekilme süresi başa döner. Pratik sonucu şudur: her on beş dakikada bir çöken bir konteyner, on-failure:5 politikasıyla bile asla "pes etmez", çünkü her çöküş arasında yeterince uzun çalışıp sayacı sıfırlar. Beş deneme sınırı yalnızca üst üste, hızlı ardışık çöküşler için geçerlidir.

    Bunu izlemenin en doğrudan yolu sayaca ve olay akışına bakmaktır:

    # Konteyner kac kez yeniden baslatildi
    docker inspect --format='{{.RestartCount}}' firmaniz-app
    
    # Yeniden baslatma olaylarini canli izle
    docker events --filter event=restart
    
    # Son 24 saatte hangi konteynerler yeniden basladi
    docker events --since 24h --filter event=restart --format '{{.Time}} {{.Actor.Attributes.name}}'
    

    RestartCount değerinin sürekli artması, altta çözülmemiş bir sorun olduğunun en net göstergesidir. Üretimde bu değeri periyodik olarak toplamanızı öneririm; sessizce dönüp duran bir konteyner, kullanıcıya kısa kesintiler olarak yansır ve loglara bakmadan fark edilmez.

    Compose'da restart Ayarı ve YAML Tuzağı#

    Compose dosyasında politika servis düzeyinde tanımlanır. Burada çok bilinen ama hâlâ herkesi yakalayan bir YAML tuzağı vardır: YAML, tırnaksız no değerini boolean false olarak yorumlar. Compose bu durumda beklediğiniz gibi davranmaz ya da doğrudan hata verir.

    services:
      proxy:
        image: nginx:1.27-alpine
        restart: always            # ters proxy her kosulda ayakta olsun
    
      app:
        image: firmaniz/web:1.4.0
        restart: unless-stopped    # uzun omurlu servisler icin varsayilan tercih
    
      migrate:
        image: firmaniz/web:1.4.0
        command: ["./bin/migrate", "up"]
        restart: "no"              # TIRNAK ZORUNLU - yoksa YAML bunu false okur
    
      yedek:
        image: firmaniz/backup:1.0
        restart: on-failure        # gecici hatada tekrar dene
    

    Swarm modunda çalışıyorsanız restart yerine deploy.restart_policy bloğu geçerlidir ve daha ayrıntılı ayar sunar. Tek makinede docker compose up ile çalışıyorsanız deploy bloğunun restart_policy alanı yok sayılır; bu, "ayarladım ama çalışmıyor" şikâyetlerinin sık görülen bir sebebidir.

      app:
        image: firmaniz/web:1.4.0
        deploy:
          replicas: 3
          restart_policy:
            condition: on-failure
            delay: 5s
            max_attempts: 3
            window: 120s
    

    Compose dosyanızın genel yapısını ve ortam bazlı farklılıkları nasıl yöneteceğinizi Compose profilleri ve ortam değişkenleri yazısında ayrıntılı ele aldım.

    Sunucu Yeniden Başladığında Ne Olur#

    Restart politikası ancak Docker daemon çalışıyorsa iş görür. Bu apaçık görünse de en sık atlanan adım tam olarak burasıdır: Docker servisi açılışta başlamıyorsa hiçbir politika sizi kurtarmaz. Yeni kurulan sunucularda ya da elle kurulmuş Docker'da bu ayar kapalı kalabilir.

    # Docker acilista otomatik basliyor mu
    systemctl is-enabled docker
    # Ciktisi "disabled" ise:
    sudo systemctl enable --now docker
    
    # containerd de acilista basliyor olmali
    systemctl is-enabled containerd
    

    Sunucuyu yeniden başlattıktan sonra durumu doğrulamak en güvenilir testtir. Bakım penceresinde bir kez sudo reboot yapıp ardından docker ps ile beklediğiniz konteynerlerin geri geldiğini görmek, teoride doğru olan bir yapılandırmanın pratikte de çalıştığını kanıtlar.

    Bir ayrıntı daha: Docker daemon yeniden başlatıldığında always ve unless-stopped politikalı konteynerler sırayla ayağa kalkar, ancak Compose'daki depends_on sırası bu senaryoda uygulanmaz. Yani veritabanı ile uygulama aynı anda açılmaya çalışabilir. Uygulamanız açılışta veritabanına bağlanamazsa çıkmalı ve restart politikası sayesinde tekrar denemelidir; ya da bağlantıyı yeniden deneyen bir başlangıç mantığı içermelidir. Bu, dağıtık sistemlerde "sıraya güvenme, tekrar dene" ilkesinin en somut örneğidir.

    Restart Politikası Sağlık Kontrolünün Yerini Tutmaz#

    Bu ayrımı net koymak gerekiyor çünkü çok yaygın bir yanılgı. Restart politikası yalnızca konteyner çıkış yaptığında tetiklenir. Konteyner ayakta ama uygulama kilitlenmişse, isteklere 500 dönüyorsa veya veritabanı havuzu tükenmişse süreç ölmediği için hiçbir politika devreye girmez. Tek makinede çalışan Docker, unhealthy durumdaki bir konteyneri yeniden başlatmaz.

    İki mekanizmayı birlikte kullanmanın en temiz yolu, uygulamanın kurtarılamaz bir durumu kendisi tespit edip süreci sonlandırmasıdır. Sağlık kontrolü sorunu görür, uygulama kendini kapatır, restart politikası yeniden başlatır. Zinciri böyle kurduğunuzda ek bir araca ihtiyaç duymazsınız. Sağlık kontrolünün nasıl tanımlanacağını Docker healthcheck kullanımı yazısında adım adım anlattım.

    Sık Yapılan Hatalar#

    Varsayılanın always olduğunu sanmak. Varsayılan no'dur. docker run ile hızlıca başlattığınız ve "geçici" dediğiniz konteyner, sunucu yeniden başladıktan sonra geri gelmez. Kalıcı hâle gelen her geçici konteynere politika atayın.

    --rm ile restart politikasını birlikte kullanmaya çalışmak. docker run --rm konteyneri çıkışta siler; silinen konteyner yeniden başlatılamaz. Docker bu ikisini birlikte kabul etmez ve hata verir.

    Kalıcı hatayı restart ile örtmek. Yanlış veritabanı parolası yüzünden çöken bir konteyneri always ile döndürmek sorunu çözmez, sadece görünmez kılar. RestartCount değerini izleyin; sürekli artıyorsa çözülmemiş bir kök neden vardır.

    Log sürücüsünü sınırsız bırakmak. Saniyede birkaç kez yeniden başlayan bir konteyner, JSON log dosyasını hızla gigabaytlara çıkarır ve diski doldurur. daemon.json içinde log döndürme sınırı tanımlayın:

    {
      "log-driver": "json-file",
      "log-opts": { "max-size": "10m", "max-file": "3" }
    }
    

    Disk dolduğunda neyi temizleyeceğinizi Docker diski doldurdu yazısında bulabilirsiniz.

    Compose'da restart: no yazarken tırnağı unutmak. YAML bunu false olarak okur. Doğrusu restart: "no" biçimidir.

    Sıkça Sorulan Sorular#

    always mi unless-stopped mı kullanmalıyım#

    Uzun ömürlü uygulama servisleri için unless-stopped daha doğru bir varsayılandır, çünkü sizin kasten durdurma kararınızı sunucu yeniden başladıktan sonra da korur. always ise "hiçbir koşulda kapalı kalmamalı" dediğiniz altyapı bileşenleri, örneğin ters proxy ya da izleme ajanı için uygundur. İkisi arasındaki tek fark, elle durdurulmuş bir konteynerin Docker daemon yeniden başladığında ayağa kalkıp kalkmayacağıdır.

    Restart politikasını çalışan konteynerde değiştirebilir miyim#

    Evet, docker update --restart unless-stopped konteyner_adi komutu politikayı anında değiştirir ve konteyneri yeniden oluşturmanıza gerek kalmaz. Compose ile yönetiyorsanız değişikliği dosyaya yazıp docker compose up -d demeniz daha doğrudur; aksi hâlde bir sonraki dağıtımda dosyadaki eski değer geri gelir. Mevcut ayarı docker inspect ile doğrulayabilirsiniz.

    Sunucu yeniden başlayınca konteynerler neden gelmedi#

    En sık iki sebep vardır. Birincisi konteynerin restart politikası no'dur, yani hiç ayarlanmamıştır. İkincisi Docker servisinin kendisi açılışta başlamamaktadır; systemctl is-enabled docker komutu disabled dönüyorsa sudo systemctl enable --now docker ile düzeltilir. Üçüncü ve daha nadir sebep, konteynerin bağlı olduğu bir diskin açılışta henüz bağlanmamış olmasıdır.

    on-failure sınırı neden çalışmıyor gibi görünüyor#

    Çünkü yeniden başlatma sayacı, konteyner belirli bir süre kesintisiz çalıştığında sıfırlanır. on-failure:5 sınırı yalnızca hızlı ve ardışık çöküşler için geçerlidir; her yarım saatte bir çöken bir konteyner arada yeterince uzun çalıştığı için sayacı her seferinde sıfırlar ve sonsuza kadar dönmeye devam eder. Bu tür aralıklı çöküşleri sınırla değil, izleme ve alarm ile yakalamanız gerekir.

    Restart politikası konteyner sağlıksız olduğunda devreye girer mi#

    Hayır. Tek makinede çalışan Docker'da unhealthy durumu bir çıkış sayılmaz, dolayısıyla restart politikası tetiklenmez. Bunun için ya uygulamanızın kurtarılamaz durumda kendini sonlandırması, ya Docker Swarm gibi sağlıksız görevleri değiştiren bir orkestratör kullanmanız, ya da sağlıksız konteynerleri izleyip yeniden başlatan bir yardımcı konteyner çalıştırmanız gerekir.

    Kaç saniyede bir yeniden başlatma denenir#

    Docker üstel geri çekilme uygular: ilk deneme neredeyse anında yapılır, sonraki her denemede bekleme süresi kabaca ikiye katlanır. Böylece kalıcı bir hatada denemeler seyrekleşir ve sunucu boşuna yorulmaz. Konteyner yeterince uzun süre kesintisiz çalışırsa geri çekilme süresi ve deneme sayacı başa döner.

    Docker Swarm'da restart politikası farklı mı çalışır#

    Evet. Swarm'da restart anahtarı yerine deploy.restart_policy bloğu geçerlidir ve condition, delay, max_attempts, window alanlarıyla çok daha ayrıntılı ayar yapabilirsiniz. Ayrıca Swarm sağlık kontrolüne de tepki verir: unhealthy bir görevi durdurup yerine yenisini başlatır. Tek makinede docker compose up çalıştırırken deploy.restart_policy yok sayılır, bu yüzden iki ortamda farklı anahtarlar kullanmanız gerekir.

    Kapanış#

    Restart politikası, tek satırlık bir ayarın üretimdeki en somut karşılıklarından biridir. Aklınızda kalması gereken dört alışkanlık şunlar: kalıcı servislere varsayılan olarak unless-stopped verin, tek seferlik işlere on-failure ve makul bir deneme sınırı koyun, systemctl is-enabled docker ile Docker'ın açılışta başladığını mutlaka doğrulayın ve RestartCount değerini düzenli izleyerek sessizce dönüp duran konteynerleri erken yakalayın. Restart politikasının çöken süreci kurtardığını, kilitlenmiş bir uygulamayı ise kurtarmadığını da unutmayın; o boşluğu sağlık kontrolü doldurur.

    Bu ayarların gerçekten iş görmesi için altındaki sunucunun da kararlı olması gerekir. Kendi Docker yığınınızı çalıştırmak için tam root erişimli VDS ya da esnek kaynaklı bulut sunucu paketlerimize göz atabilirsiniz; sunucu güncellemeleri, yeniden başlatma sonrası doğrulama ve izleme gibi işleri devretmek isterseniz sunucu yönetimi hizmetimiz bunları sizin yerinize üstlenir. Konteyner verilerinizin düzenli kopyası için de yedekleme çözümümüz tamamlayıcı bir adımdır.

    DockerRestartKonteyner

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.