Docker'da bir container kapandığında ya da Docker daemon yeniden başladığında container'ın kendiliğinden tekrar çalışmasını istiyorsanız ona bir yeniden başlatma politikası (restart policy) verirsiniz. Bu iş docker run komutunun --restart bayrağıyla, Compose dosyasında ise servisin restart: anahtarıyla yapılır. Dört değer vardır: no (varsayılan, hiç yeniden başlatmaz), on-failure[:max-retries] (yalnızca hata koduyla çıkışta), always (her durduğunda) ve unless-stopped (siz elle durdurmadıkça). Sunucuda sürekli açık kalması gereken web sunucusu, veritabanı veya kuyruk işçisi gibi servisler için genellikle unless-stopped ya da always, yalnızca başarısız olduğunda tekrar denenmesi gereken işler için on-failure seçilir.

Bu yazıda her politikanın resmî belgelerdeki tam davranışını, politikanın hangi andan itibaren geçerli olduğunu belirleyen 10 saniye kuralını, elle durdurma istisnasını, çalışan bir container'ın politikasını docker update ile değiştirmeyi, Compose karşılığını, systemd gibi süreç yöneticileriyle ilişkisini ve live-restore ayarından farkını ele alıyoruz. Container'ın ne kadar bellek ve CPU kullanabileceğini CPU ve bellek limiti yazısında, Swarm servislerinin yeniden başlatma ayarlarını docker stack deploy yazısında, Compose'un deploy.restart_policy bloğunu da Compose deploy ve kaynak limitleri yazısında bulabilirsiniz. Serinin tamamı için Docker öğrenme rehberine bakın.

Restart policy nedir, ne zaman devreye girer?

Restart policy, Docker daemon'un bir container'ı izleyip gerektiğinde yeniden başlatmasını sağlayan kuraldır. Docker belgeleri burada açık bir tercih belirtir: container'ları otomatik başlatmak için harici süreç yöneticileri yerine restart policy kullanmanızı önerir. Sebebi basittir; daemon container'ın ne zaman, hangi çıkış koduyla durduğunu zaten bilir ve kararı bu bilgiye göre verebilir.

Politikayı tetikleyen iki olay vardır. Birincisi container'ın kendi ana sürecinin sona ermesidir: uygulama çöker, hata koduyla çıkar ya da işini bitirip 0 koduyla kapanır. İkincisi Docker daemon'un yeniden başlamasıdır; sunucunun yeniden açılması, Docker paketinin güncellenmesi veya servisin elle yeniden başlatılması bu gruptadır. Dört politika bu iki olaya farklı tepki verir ve doğru seçimi yapmak için asıl önemli olan da bu farktır.

Dört politika ve farkları

Dört politika ve farkları: no (varsayılan), on-failure[:max-retries], always, unless-stopped

Belgelerdeki tanımları bir tabloda toplayalım. Tablodaki "elle durdurulmuşsa" sütunu, container'ı docker stop ile sizin durdurduğunuz durumu anlatır.

PolitikaHata koduyla çıkış0 koduyla çıkışDaemon yeniden başlarsaElle durdurulmuşsa
no (varsayılan)Yeniden başlatmazYeniden başlatmazBaşlatmazBaşlatmaz
on-failure[:max-retries]Yeniden başlatır, isteğe bağlı deneme sınırıylaYeniden başlatmazBaşlatmazBaşlatmaz
alwaysYeniden başlatırYeniden başlatırBaşlatırDaemon yeniden başlayınca ya da container elle başlatılınca
unless-stoppedYeniden başlatırYeniden başlatırBaşlatır (elle durdurulmadıysa)Başlatmaz, daemon yeniden başlasa bile

no varsayılandır; hiçbir bayrak vermediğiniz her container bu politikayla çalışır. Sunucunuz yeniden açıldığında bazı container'ların geri gelmemesinin en sık nedeni budur: politika hiç ayarlanmamıştır.

on-failure yalnızca sıfırdan farklı bir çıkış kodu, yani bir hata görüldüğünde devreye girer. :max-retries ekiyle daemon'un en fazla kaç kez yeniden deneyeceğini sınırlayabilirsiniz. Belgelerin özellikle vurguladığı bir ayrıntı var: on-failure politikası daemon yeniden başladığında container'ı başlatmaz. Yani sunucu yeniden açıldıktan sonra bu politikaya sahip container'lar kendiliğinden ayağa kalkmaz.

always container hangi sebeple durursa dursun onu yeniden başlatır. Tek istisna elle durdurmadır: container'ı docker stop ile durdurduysanız, daemon yeniden başlayana ya da siz container'ı elle başlatana kadar kapalı kalır. unless-stopped ise always ile neredeyse aynıdır; fark, durdurulmuş bir container'ın daemon yeniden başladığında bile kapalı kalmasıdır.

docker run ve docker update ile politika vermek

Yeni bir container başlatırken politikayı --restart bayrağıyla verirsiniz. Belgelerdeki örnek bir Redis container'ını unless-stopped ile başlatır: container çıkarsa veya daemon yeniden başlarsa Docker onu tekrar çalıştırır, ama siz kendiniz durdurduysanız dokunmaz.

bash
docker run -d --name redis --restart unless-stopped redis

Hata durumunda en fazla beş deneme yapılmasını istediğiniz bir iş için on-failure politikasına deneme sınırını iki nokta üst üste ile eklersiniz:

bash
docker run -d --name rapor-isi --restart on-failure:5 rapor-imaji

Zaten çalışan bir container'ın politikasını değiştirmek için container'ı silip yeniden oluşturmanız gerekmez. docker update komutu politikayı yerinde günceller. Belgelerde ayrıca o anda çalışan tüm container'lara aynı politikayı uygulayan bir örnek de yer alır; burada docker ps -q çalışan container'ların kimliklerini verir.

bash
docker update --restart unless-stopped redis

docker update --restart unless-stopped $(docker ps -q)

Politika ne zaman geçerli olur: 10 saniye kuralı

Politika ne zaman geçerli olur: 10 saniye kuralı: Elle durdurma istisnası, Yalnızca container'lar için geçerlidir

Belgelere göre restart policy ancak container başarıyla başladıktan sonra yürürlüğe girer. Buradaki "başarıyla başlamak" ifadesinin somut bir tanımı vardır: container en az 10 saniye ayakta kalmış ve Docker onu izlemeye başlamış olmalıdır. Bu kuralın amacı, hiç başlayamayan bir container'ın sonsuz bir yeniden başlatma döngüsüne girmesini engellemektir.

Pratikte bunun anlamı şudur: yanlış bir ortam değişkeni, eksik bir dosya ya da hatalı bir komut yüzünden ilk saniyelerde çöken bir uygulamayı restart policy ile "kurtarmayı" beklemeyin. Böyle bir durumda asıl bilgi container loglarındadır; docker logs çıktısına bakıp hatayı düzeltmek gerekir. Logların diskte ne kadar yer kapladığını sınırlamak için log boyutu ve log driver yazısına göz atabilirsiniz.

Elle durdurma istisnası

İkinci önemli kural elle durdurmayla ilgilidir. Bir container'ı elle durdurduğunuzda restart policy, daemon yeniden başlayana ya da container'ı elle yeniden başlatana kadar yok sayılır. Bu da yine bir döngüyü önlemek içindir: siz durdurduğunuz anda daemon container'ı geri açmaya çalışmaz.

Sunucu bakımı açısından fark şöyle ortaya çıkar. Diyelim ki bakım için bir container'ı docker stop ile durdurdunuz, sonra sunucuyu yeniden başlattınız. Politika always ise container açılışta geri gelir, çünkü daemon yeniden başlamıştır. Politika unless-stopped ise container kapalı kalır, çünkü onu siz durdurmuştunuz. Kapattığınız şeyin kapalı kalmasını istiyorsanız unless-stopped, ne olursa olsun açılışta her container'ın çalışmasını istiyorsanız always daha uygun düşer.

Yalnızca container'lar için geçerlidir

--restart ile verilen politikalar tek tek container'lara uygulanır. Swarm servislerinin yeniden başlatma davranışı docker service create komutunun kendi bayraklarıyla ayarlanır; bu konu Docker Swarm kurulumu ve stack deploy yazılarında ele alınıyor.

Ön planda çalışan container ve terminal oturumu

Belgelerde sık karıştırılan bir durumu gösteren güzel bir örnek var: container'ı -d olmadan, yani ön planda çalıştırdığınızda container durduğu anda bağlı terminal oturumu da sona erer. Politika ne olursa olsun bu değişmez. Örnekte 1'den 5'e kadar sayıp hata koduyla çıkan küçük bir imaj kullanılır:

dockerfile
FROM busybox:latest
COPY --chmod=755 <<"EOF" /start.sh
echo "Starting..."
for i in $(seq 1 5); do
  echo "$i"
  sleep 1
done
echo "Exiting..."
exit 1
EOF
ENTRYPOINT /start.sh

İmaj docker build -t startstop . ile oluşturulup always politikasıyla çalıştırıldığında belgelerdeki çıktı şöyledir; sayılar yazılır, betik çıkar ve terminal de onunla birlikte kapanır:

bash
docker run --restart always startstop
Starting...
1
2
3
4
5
Exiting...

Terminal kapanmış olsa da container yeniden başlatılmıştır; belgelerdeki docker ps çıktısı container'ı çalışır durumda gösterir. Yeniden başlatmalar arasında docker container attach ile terminalinizi tekrar bağlayabilirsiniz, ancak container bir sonraki çıkışında bağlantı yine kopar. Bu örnekten çıkarılacak ders, sunucuda uzun ömürlü servisleri her zaman -d ile arka planda başlatmak ve çıktıyı loglardan izlemektir.

Compose'da restart anahtarı

Compose dosyasında aynı dört değer servis düzeyindeki restart anahtarıyla verilir. Compose belgesindeki tanımlar Docker'ınkiyle örtüşür: no varsayılandır ve hiçbir koşulda yeniden başlatmaz, always container kaldırılana kadar yeniden başlatır, on-failure[:max-retries] çıkış kodu hata gösterdiğinde çalışır, unless-stopped ise çıkış kodundan bağımsız olarak yeniden başlatır ama servis durdurulduğunda veya kaldırıldığında bunu bırakır. Aşağıdaki dosyada üç servis üç farklı politikayla tanımlı:

yaml
services:
  web:
    image: nginx:alpine
    restart: unless-stopped
  worker:
    image: busybox
    command: ["sh", "-c", "exit 1"]
    restart: on-failure:3
  migrate:
    image: busybox
    command: ["echo", "tamam"]
    restart: "no"

Dosyayı docker compose config ile doğruladığımızda normalize edilmiş çıktıda politikalar aynen korunur; migrate servisi için çıktının ilgili kısmı şöyledir:

bash
docker compose -f compose.yaml config
name: restart
services:
  migrate:
    command:
      - echo
      - tamam
    image: busybox
    networks:
      default: null
    restart: 'no'

Belgedeki örneklerde no değeri tırnak içinde, restart: "no" biçiminde yazılır. Compose v5.5.1 ile denediğimizde tırnaksız restart: no da aynı şekilde 'no' olarak normalize edildi; yine de belgedeki yazımı kullanmak en güvenli yoldur. Compose'un üretim kullanımı belgesi de kesinti yaşamamak için restart: always gibi bir politika tanımlamayı önerilen değişiklikler arasında sayar. Tek servisli bir Compose dosyasının temelleri için Docker Compose başlangıç rehberine, çok servisli üretim düzeni için Docker Compose rehberine bakabilirsiniz.

systemd ve diğer süreç yöneticileri

Restart policy her senaryoya uymayabilir. Belgelerin verdiği örnek, Docker dışındaki süreçlerin bir container'a bağımlı olduğu durumdur. Böyle bir durumda container'ı systemd veya supervisor gibi bir süreç yöneticisiyle başlatabilirsiniz. Yöneticiyi, container'ı elle başlatırken kullandığınız docker start ya da docker service komutunu çalıştıracak şekilde yapılandırırsınız; ayrıntılar kullandığınız aracın belgelerindedir.

Container'ın içinde süreç yöneticisi çalıştırmak da mümkündür, ancak belgeler bunu önermez. Bu araçlar Docker'dan habersizdir, yalnızca container içindeki işletim sistemi süreçlerini izler ve davranışları platforma, hatta aynı Linux dağıtımının sürümlerine göre değişebilir.

Unutulmaması gereken bir bağlantı daha var: always ve unless-stopped container'larının sunucu açılışında geri gelmesi, daemon'un yeniden başlamasına dayanır. Debian ve Ubuntu'da Docker servisi açılışta varsayılan olarak başlar. systemd kullanan diğer dağıtımlarda Docker ve containerd'yi açılışta başlatmak için belgeler şu komutları verir:

bash
sudo systemctl enable docker.service
sudo systemctl enable containerd.service

Bu davranışı geri almak için enable yerine disable kullanılır. Kurulum sonrası adımların tamamı, yani docker grubu ve açılışta başlatma, sudo olmadan Docker çalıştırma yazısında anlatılıyor.

Restart policy ile live-restore arasındaki fark

Restart policy ile live-restore arasındaki fark: Nerede ayarlanır, Çözdüğü sorun, Container durur mu, Sınırı

İki ayar sık karıştırılır ama farklı sorunları çözer. Restart policy, container durduğunda veya daemon yeniden başladığında container'ın yeniden başlatılıp başlatılmayacağını belirler. dockerd için --live-restore (ya da daemon.json içinde "live-restore": true) ise daemon kapalıyken container'ların hiç durmadan çalışmaya devam etmesini sağlar. Belgelere göre live restore sayesinde Docker güncellemesi sırasında container'lar çalışır kalır, ancak ağ bağlantısı ve kullanıcı girdisi kesintiye uğrar.

Live restore'un sınırları da belgelerde yazılıdır: yalnızca yama sürümü güncellemelerinde (YY.MM.x) desteklenir, büyük sürüm geçişlerinde desteklenmez; köprü IP adresleri gibi daemon ayarları değiştiyse container'lar geri bağlanamayabilir. Bu ayarın nasıl açılacağı daemon.json yapılandırma yazısında yer alıyor.

ÖzellikRestart policylive-restore
Nerede ayarlanırHer container için --restart veya Compose restartDaemon için daemon.json veya dockerd bayrağı
Çözdüğü sorunDuran container'ı yeniden başlatmakDaemon kapalıyken container'ı çalışır tutmak
Container durur muDurur, sonra yeniden başlatılırDurmaz, çalışmaya devam eder
Sınırı10 saniye kuralı ve elle durdurma istisnasıYalnızca yama sürümü güncellemeleri

Sık yapılan hatalar

  • Hiç politika vermemek. Varsayılan no olduğu için sunucu yeniden açıldığında container'lar kapalı kalır.
  • on-failure ile açılışta geri gelmeyi beklemek. Bu politika daemon yeniden başladığında container'ı başlatmaz; açılışta çalışması gereken servisler için unless-stopped veya always seçin.
  • Çöken bir uygulamayı restart policy ile örtmek. 10 saniye kuralı nedeniyle hemen çöken container'lar için çözüm loglardaki hatayı düzeltmektir.
  • docker stop sonrası always politikasının container'ı hemen geri açmasını beklemek. Elle durdurma, daemon yeniden başlayana ya da container elle başlatılana kadar politikayı askıya alır.
  • Restart policy ile systemd biriminin aynı container'ı yönetmesi. Belgeler bu kombinasyonun çakışma yarattığını söyler.
  • Compose dosyasında değeri yanlış yazmak ve config doğrulamasının bunu yakalayacağını varsaymak.

Sık Sorulan Sorular

Sunucu yeniden başladıktan sonra container'larım neden açılmadı?

Üç olasılığı sırayla kontrol edin: container'a hiç politika verilmemiş olabilir (varsayılan no), politika on-failure olabilir (daemon yeniden başlamasında tetiklenmez) ya da container'ı daha önce elle durdurmuş ve unless-stopped kullanmış olabilirsiniz. Ayrıca Docker servisinin açılışta başladığından emin olun; daemon çalışmıyorsa hiçbir politika işlemez. Daemon'a bağlanılamıyorsa Cannot connect to the Docker daemon hatası yazısına bakın.

always mı, unless-stopped mı seçmeliyim?

Fark yalnızca elle durdurduğunuz container'larda ortaya çıkar. Bakım için durdurduğunuz bir container'ın sunucu yeniden açıldığında kendiliğinden geri gelmesini istemiyorsanız unless-stopped seçin. Her koşulda açılışta çalışmasını istiyorsanız always uygundur.

Çalışan bir container'ın politikasını değiştirmek için yeniden oluşturmam gerekir mi?

Hayır. docker update --restart <politika> <container> komutu politikayı yerinde değiştirir. Compose ile yönettiğiniz servislerde ise değişikliği Compose dosyasına yazın ki bir sonraki yeniden oluşturmada kaybolmasın.

max-retries sınırı dolunca ne olur?

Belgeler :max-retries ekinin daemon'un yeniden başlatma denemelerinin sayısını sınırladığını söyler. Sınır dolduğunda daemon container'ı yeniden başlatmayı bırakır; container durmuş olarak kalır ve sorunu loglardan incelemeniz gerekir.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: Docker öğrenme rehberi · CPU ve bellek limiti · Compose deploy ayarları · daemon.json yapılandırma · Docker Compose rehberi