“İmaj” ve “container” kelimeleri günlük konuşmada sık sık birbirinin yerine kullanılır, ama aslında farklı şeylerdir. Bu farkı baştan doğru kavramak; docker rm ile docker rmi arasındaki farktan, “neden imajı sildim de yer açılmadı?” sorusuna kadar bir sürü kafa karışıklığını önler.
Kısa cevap: tarif ve yemek
Programlamadan bir benzetme: imaj bir sınıf (class) gibidir, container onun çalışan bir örneği (instance). İmaj salt okunur bir şablondur; container ise o şablondan başlatılmış, üzerine kendi yazılabilir katmanını eklemiş canlı bir süreçtir.
| İmaj (image) | Container | |
|---|---|---|
| Ne? | Uygulama + bağımlılıkları + dosya sistemi şablonu | İmajdan başlatılmış çalışan (veya durmuş) örnek |
| Değişir mi? | Hayır — salt okunur, değişmez (immutable) | Evet — üstüne yazılabilir bir katman eklenir |
| Kaç tane? | Bir imaj, bir kez indirilir | Aynı imajdan istediğiniz kadar container başlatılabilir |
| Silme komutu | docker rmi |
docker rm |
İmaj, üst üste binmiş katmanlardan oluşur
Bir Dockerfile’daki her dosya değiştiren talimat (RUN, COPY, ADD) imaja yeni bir katman ekler. docker history bu katmanları ve her birinin boyutunu gösterir:
FROM temel-imaj
RUN echo a > /a
RUN echo b > /b
COPY . /app
$ docker history katmanli:1 --format '{{.Size}} {{.CreatedBy}}'
16.4kB COPY . /app # buildkit
8.19kB RUN /bin/sh -c echo b > /b # buildkit
8.19kB RUN /bin/sh -c echo a > /a # buildkit
14.9MB
En alttaki satır temel imajın kendisidir; üstündeki her satır, bir talimatın eklediği farktır. Bu yapının iki önemli sonucu var: katmanlar paylaşılır (aynı temel imajı kullanan on imaj, o katmanı diskte bir kez tutar) ve katmanlar önbelleğe alınır (değişmeyen talimatlar yeniden çalıştırılmaz — bkz. Build Cache ve BuildKit).
Etiket (tag) bir isimdir, imaj değildir
Bir imaja istediğiniz kadar etiket verebilirsiniz; hepsi aynı imajı işaret eder:
$ docker tag temel:1 temel:v1
$ docker tag temel:1 temel:latest
$ docker images temel --format '{{.Repository}}:{{.Tag}} {{.ID}}'
temel:1 da40800f731b
temel:latest da40800f731b
temel:v1 da40800f731b
Üç etiketin aynı kimliği (ID) taşıdığına dikkat edin. İki yaygın yanlış anlama:
:latest“en yeni” demek değildir. Sadece etiket belirtmediğinizde kullanılan varsayılan isimdir; birinin onu güncelleyip güncellemediğini garanti etmez. Üretimde sabit sürüm etiketi kullanın.- Bir etiket zamanla başka bir imaja işaret edebilir. Gerçekten değişmez bir referans istiyorsanız içerik özetini (digest) kullanın:
imaj@sha256:...
Container’ın yaşam döngüsü
Bir container birkaç durumdan geçer. docker run aslında create + start işlemlerinin kısayoludur; bunları ayrı ayrı çalıştırınca durumlar net görünür:
$ docker create --name c1 temel:1 /bin/sh -c 'echo merhaba'
$ docker ps -a --filter name=c1 --format '{{.Names}} {{.Status}}'
c1 Created
$ docker start -a c1
merhaba
$ docker ps -a --filter name=c1 --format '{{.Names}} {{.Status}}'
c1 Exited (0) Less than a second ago
| Durum | Anlamı | Geçiş komutu |
|---|---|---|
Created |
Oluşturuldu, henüz çalışmadı | docker start |
Up (running) |
Çalışıyor | docker stop / docker kill |
Exited (kod) |
Süreç bitti; çıkış kodu 0 başarıyı gösterir | docker start / docker rm |
docker stop önce SIGTERM gönderir, container belirtilen süre içinde (varsayılan 10 saniye) kapanmazsa SIGKILL ile sonlandırır. SIGTERM’e tepki vermeyen bir süreçte bu 10 saniyenin tamamını beklersiniz ve çıkış kodu 137 (128 + 9) olur — container’larınız “yavaş kapanıyor” ise sorun genellikle uygulamanın sinyali yakalamamasıdır.
Silerken: rm mı rmi mi?
Bir imajı, onu kullanan bir container (durmuş olsa bile) varken silemezsiniz:
$ docker rmi temel:1
Error response from daemon: conflict: unable to delete temel:1 (must be forced)
- container 7237f9f8a629 is using its referenced image 7096a6e93088
Önce container’ı (docker rm), sonra imajı (docker rmi) silin. Birden fazla etiketli bir imajda docker rmi etiket yalnızca o etiketi kaldırır (Untagged: temel:v1); imajın verisi son etiket de gidene kadar diskte kalır.
Container içinde yazdığınız her şey, container silindiğinde yazılabilir katmanıyla birlikte gider. Kalıcı olması gereken veri için volume kullanın.
Hızlı özet
- İmaj = salt okunur şablon (katmanlı); container = onun çalışan örneği.
- Etiketler aynı imaja işaret eden isimlerdir;
:latestözel bir anlam taşımaz. - Container yaşam döngüsü:
Created → Up → Exited;docker run=create+start. - Container’ı
docker rm, imajıdocker rmiile silersiniz.
Sıradaki adım: kendi imajınızı yazmak için Dockerfile Yazmaya Giriş yazısına geçebilir, ya da hiç başlamadıysanız Docker Nedir? yazısıyla temelleri tazeleyebilirsiniz.