Biraz araştırma ve testten sonra, Docker konteynerlerinin kullanım ömrü hakkında bazı yanlış anlamalar yaşadığımı fark ettim. Bir konteynerin yeniden başlatılması, Docker'ın bu arada imaj yeniden oluşturulduğunda yeni bir imaj kullanmasına neden olmaz. Bunun yerine, Docker sadece resmi getirilirken edilir önce kapsayıcı oluşturmadan . Yani bir konteyner çalıştırdıktan sonraki durum kalıcıdır.
Kaldırma neden gerekli
Bu nedenle, yeniden oluşturmak ve yeniden başlatmak yeterli değildir. Container'ların bir hizmet gibi çalıştığını düşündüm: Hizmeti durdurun, değişikliklerinizi yapın, yeniden başlatın ve bunlar geçerli olur. Bu benim en büyük hatamdı.
Kaplar kalıcı olduğundan, docker rm <ContainerName>
önce onları kullanarak kaldırmanız gerekir . Bir konteyner kaldırıldıktan sonra onu basitçe başlayamazsınız docker start
. Bu, docker run
yeni bir kapsayıcı örnek oluşturmak için en son görüntüyü kullanan kullanılarak yapılmalıdır .
Konteynerler olabildiğince bağımsız olmalıdır
Bu bilgiyle, verilerin konteynerlerde saklanmasının neden kötü bir uygulama olarak nitelendirildiği anlaşılır ve Docker bunun yerine veri hacimlerini / ana bilgisayar direktörlerini monte etmeyi öneriyor : Uygulamaları güncellemek için bir konteynerin yok edilmesi gerektiğinden, içeride depolanan veriler de kaybolacaktır. Bu, fazladan çalışmanın hizmetlerin kapatılmasına, verilerin yedeklenmesine vb. Neden olur.
Dolayısıyla, bu verileri tamamen kapsayıcıdan çıkarmak akıllıca bir çözüm: Ana bilgisayarda güvenli bir şekilde depolandığında ve kapsayıcı yalnızca uygulamanın kendisini tuttuğunda verilerimiz için endişelenmemize gerek yok.
Neden -rf
sana gerçekten yardım etmeyebilir
docker run
Komut, bir sahip Clean up denilen anahtarı -rf
. Docker konteynerlerini kalıcı olarak tutma davranışını durduracaktır. -rf
Docker kullanıldığında , konteynerden çıkıldıktan sonra onu yok edecektir. Ancak bu anahtarın iki sorunu vardır:
- Docker ayrıca kapsayıcıyla ilişkilendirilmiş bir adı olmayan birimleri kaldırır, bu da verilerinizi öldürebilir
- Bu seçeneği kullanarak, kapsayıcıları arka planda
-d
anahtar kullanarak çalıştırmak mümkün değildir.
-rf
Anahtar, hızlı testler için geliştirme sırasında işten tasarruf etmek için iyi bir seçenek olsa da , üretim için daha az uygundur. Özellikle arka planda bir konteyneri çalıştırma seçeneğinin eksik olması nedeniyle, ki bu çoğunlukla gerekli olacaktır.
Bir konteyner nasıl kaldırılır
Bu sınırlamaları, yalnızca kapsayıcıyı kaldırarak atlayabiliriz:
docker rm --force <ContainerName>
--force
(Ya da -f
konteyner çalıştıran SIGKILL kullanın) geçer. Bunun yerine, kapsayıcıyı daha önce de durdurabilirsiniz:
docker stop <ContainerName>
docker rm <ContainerName>
İkisi de eşittir. docker stop
ayrıca SIGTERM kullanıyor . Ancak --force
switch'i kullanmak , özellikle CI sunucularını kullanırken komut dosyanızı kısaltacaktır: docker stop
konteyner çalışmıyorsa bir hata atar. Bu, Jenkins ve diğer birçok CI sunucusunun yapıyı hatalı olarak başarısız olarak değerlendirmesine neden olur. Bunu düzeltmek için, önce konteynırın soruda yaptığım gibi çalışıp çalışmadığını kontrol etmelisiniz ( containerRunning
değişkene bakın ).
Docker kapsayıcısını yeniden oluşturmak için tam komut dosyası
Bu yeni bilgiye göre senaryomu şu şekilde düzelttim:
#!/bin/bash
imageName=xx:my-image
containerName=my-container
docker build -t $imageName -f Dockerfile .
echo Delete old container...
docker rm -f $containerName
echo Run new container...
docker run -d -p 5000:5000 --name $containerName $imageName
Bu mükemmel çalışıyor :)