# İçindekiler
Docker öğrenirken aldığım notlar.
Genellikle Özgür Öztürk'ün Docker eğitimini izlerken not aldım.
Elimin altında Türkçe kaynak olması için Docker ve Konteyner Uygulamaları kitabını almıştım ve bazen buradan faydalandım.
*Metinlerin bir bölümünü Özgür Hoca'nın sunumundan aldım.
*Naçizane; eğitimi şiddetle önerebilirim
Yeni nesil IT sistemleri Docker üzerinde koşuyor. En çok kullanılmak istenen platformlar listesinde üst sıralarda yer alıyor. İş ilanlarında aranan bir özellik 😜
- Temelde bir fiziksel makina üzerinde birden fazla sanal makina kurup, kaynak dağıtımını ve ortak kaynak kullanımını sağlayan sisteme verilen isimdir.
- Bu sayede fiziksel sunuculardaki atıl kapasiteyi minimuma indirebiliriz.
- Kaynak israfı önlenir
- Her uygulama izole edilmiştir, bu sayede bir uygulamada çıkan sorun diğer uygulamaları etkilemeyecektir
- Sanallaştırma her ne kadar kaynak israfını minimuma indirse de yine de kaynak israfı mevcuttur. Bu sebeple container'lar hayatımıza girdi.
- Linux containerlar sayesinde uygulamalar izole bir şekilde çalıştırılabildi fakat bu kolay bir işlem değildi.
- Namespaces
- Linux çekirdeğinde bulunan yapı taşlarındandır. Prensibi çekirdek kaynaklarrının bölümlere ayrılmasıdır. Container izolasyonunun sağlanmasındaki birincil yapıdır.
- Bazı namespaces'ler
- Net: Ağ arayüzlerini yönetir
- PID: Süreçlerin izolasyonunu sağlar
- Mnt: Dosya sistemindeki mount noktalarını yönetir
- Cgroups
- Linux çekirdeğinin kullandığı temel bileşenlerdendir. Donanım kaynaklarının sınırlandırılması, kısıtlama ve limit özelliklerinin sağlanması için kullanılır
- Container'lar; host makinede izole olarak çalışan, kullanıcı tarafından her şekilde müdahale edilebilen sanal birimdir.
- Aynı sistem üzerinde çalışırlar, o sistemin çekirdeğini kullanırlar fakat birbirlerinden tamamen izole durumdalardır.
- Docker engine; client-server mimarisinde bir uygulamadır
- Docker platformunun kalbidir
- Docker Daemon, Docker Client, REST API bileşenlerinden (temel) oluşur
- Docker Daemon
- REST API isteklerini karşılar
- Docker objelerini üretmemizi ve yönetmemizi sağlar (Container, image, volume vb bileşenler)
- Rest API
- Diğer uygulamalar rest api sayesinde docker daemon ile konuşur
- Docker CLI (Client)
- Rest API'nin en önemli kullanıcısı Docker CLI'dır
- Bir docker engine kurduğumuzda o makinede hem docker server (daemon) hem de docker client (docker cli) kurulmuş olur
- İstersek bu client (docker cli) uygulamasını localimize kurarak, cloudda kurduğumuz bir server (docker daemon)'ı yönetebiliriz. Yani bu 2 uygulama birbirinden farklıdır.
- Docker image'lerde kernel'e gerek yoktur
- Image'ler birer şablondur
- Bir image'i bir yerde depolayabilirsem, docker engine sayesinde bu image'i çalıştırabilirim
- Container'lar sayesinde image'leri depolayabiliriz
- Container dediğimiz şey aslında bir nevi image'lerin çalışır halidir. Container image şablonunun çalışan kopyasıdır olarak düşünebiliriz
- Bu sayede her sistemde her seferinde aynı sonucu alırız. Bir yerde çalışan container her yerde çalışır
- Container Registry, Container Image Registry, Docker Registry olarak da bilinir
- Docker imajlarını depolayıp dağıtabildiğimiz bir alt yapı servisidir
- En bilineni Docker Engine'ın default olarak baktığı yer olan Docker Hub'dır
- Play With Docker hizmeti sayesinde cloud ortamında Docker denemeleri yapabiliriz
- Tek kötü yanı bir oturumda en fazla 4 saat kullanmamıza izin vermesidir
- Docker Daemon'u yönetmemizi sağlar
docker version
-> Docker kurulumu ile ilgili temel bilgilere erişirizdocker info
-> Docker ile ilgili temel bilgilere erişiriz (kaç container çalışıyor, drivers vb.)docker
-> Docker CLI'da kullanabileceğimiz komutları listeler- Options
- Docker Daemon'a bağlanırken kullanacağımız parametreler gözükür
- Management Commands
- Yönetebileceğimiz bileşenlerin listesi
- Commands
- Yönetmek istediğimiz bileşen için çalıştırmak istediğimiz komut
- Options
docker image --help
-> image bileşeni ile kullanabileceğimiz komutları listeler
docker container --help
-> container bileşeni ile kullanabileceğim komutlardocker container run
-> parametre olarak verdiğimiz isimde bir container varsa başlatır yoksa önce oluşturur sonra başlatırdocker container run --name ilkcontainer ozgurozturknet/app1
-> ilkcontainer adında bir container oluşturdu ve docker hub'da ozgurozturknet altındaki varsayılan (app1) uygulamasını çalıştırdıdocker container ls -a
-> sistemdeki tüm container'ları listeler. -a olmasaydı sadece çalışan container'ları listelerdi- Container içerisindeki varsayılan olarak çalışması için ayarlanan uygulama durduğunda container'da kapatılır
docker container run <IMAGE>
docker container run -p 80:80 ozgurozturknet/adanzyedocker
- 80:80 portunda çalışan bir web servisi çalıştırır (hazır imaj)
docker container ls
komutu ile bu container'ı görebiliriz. Çünkü bu çalışıp kapanan bir uygulama değildir
docker container logs <ContainerID>
-> ID'si verilen container'a ait logları gösterirdocker container stop <ContainerID>
-> ID'si verilen container'ı durdururdocker container start <ContainerID>
-> ID'si verilen container'ı başlatırdocker container run -d -p 80:80 ozgurozturknet/adanzyedocker
- -d detach'ten gelmektedir. Container direkt arka planda çalışmaya başlar (terminalimize bağlamaz)
docker container rm <ContainerID>
-> ID'si verilen container'ı siler- illa tam id vermek zorunda değiliz id'nin ilk harflerini versek de olur
- Çalışan bir container silinemez bunu öncelikle durdurmamız gerekir ya da -f parametresi kullanılarak force ederek sileriz
docker container prune
- sistemdeki çalışmayan tüm container'ları siler
docker container run --name websunucu -p 80:80 -d ozgurozturknet/adanzyedocker
- websunucu adında bir container'ı adanzyedocker imajından oluşturdu ve arka planda çalıştırdı (127.0.0.1'e giderek görebilirsiniz)
docker container exec -it <ContainerName> <command>
it
-> interaktif olarak container'a bağlan demekdocker container exec -it websunucu sh
- websunucu container'ına bağlan ve sh komutunu çalıştır (shelle bağlanır)
ctrl + p q
kombinasyonu ile Container'ı kapatmadan arka plana alabiliriz
docker cp basitapp:/app .
-> container'ın kapanmış olması önemli değil yeter ki silinmemiş olsun. basitapp adındaki container'ın app klasörünü host makinadaki bu dizine kopyala dedik.
- Docker depolama alt yapısında union file system adı verilen bir yapı kullanır
- Docker imajları mevcut bir base imaj üzerine inşa edilir
- Bu imaj üzerine yapılan her değişiklik birer katman olarak eklenir ve bu katmanlar birer dosya olarak saklanır
- Tüm ayarlamalar image oluşturma aşamasında yapılandırılır
- Tek bir uygulama çalıştırması için dizayn edilir
- Bir sorun olursa saniyeler içerisinde yeni bir kopya oluşturulabilir
- Sorun container'a bağlanılarak çözülmez
- Container içerisinde çalışan ana uygulama durduğu zaman container'da durdurulur
- Container'da bir sorun ile karşılaşılırsa bu container'a bağlanılarak değil yeni bir container oluşturularak çözülür
- Container'lar yeniden oluşturulduğunda container içerisindeki veriler sıfırlanır, bunları container dışında tutmamız gerekir
- Ne demiştik? Docker lifecycle sonlandığında container içerisindeki her şey sıfırlanır, yani yazdığımız dosyalar vb hiç olmamış gibi ilk hale döner
- Volume'ler Container'lar dışında veri saklamak istediğimiz zaman çok kullanışlıdır
docker volume create <VolumeName>
-> parametre olarak verilen isimde bir volume oluştururdocker volume create ilkvolume
docker volume inspect <VolumeName>
-> volume detaylarını verirdocker volume inspect ilkvolume
docker container run -it -v ilkvolume:/uygulama alpine sh
- alpine imajından bir container oluşturuyorum
- -it ile container'a interaktif olarak bağlanıp sh komutunu çalıştırıyorum
- -v ile ilkvolume adındaki volume'u container içerisindeki /uygulama adındaki klasöre bağlıyorum
-v <VolumeName>:<ContainerİçindekiKlasör>
- Örneğimiz gereği aşağıdaki işlemleri gerçekleştiriyoruz
cd uygulama
touch test
echo "naber nasılsın?" > test
exit
ile conteiner'dan çıktık ve container'ı siliyoruz (volume'u test edeceğiz bakalım yeni bir container ile oluşturduğumuz test dosyasına ulaşabilecek miyiz)docker volume ls
-> komutu ile volume'leri listelerizdocker container run --name mydebiancontainer -it -v ilkvolume:/uygulama debian sh
- debian imajından mydebiancontainer adında container oluştur, /uygulama klasörüne ilkvolume volume'unu bağla ve sh ile container'a bağlan
- burdan aynı şekilde klasöre gidip cat ile dosya içerisine bakarsak yazdığımız verinin orda bulunduğunu görebiliriz
- Container içerisinde volume adında bir klasör yoksa, o isimde bir klasör oluşturulur ve içerisine mount edilir. Peki volume'leri bir klasör içerisine mount etmek istersek?
- Eğer volume imaj içinde bulunan mevcut klasöre mount edilirse:
- Klasör boşsa o anda volume içinde hangi dosyalar varsa bu klasörde de o dosyaları görürüz
- Klasörde dosya varsa ve volume boşsa klasördeki dosyalar volume'e kopyalanır
- Klasörde dosya var ya da yok fakat volume boş değilse, klasörün içinde volume'de ne varsa onu görürüz
- Host makinada (kendi local makinamız) bulunan bir klasörü veya dosyayı Container içerisinde map etmeye Bind Moun denir
docker container run -d -p 80:80 --name mynginx nginx
-> basit bir web sunucu oluşturdukdocker container exec -it mynginx sh
-> container'a bağlanıyoruzcd /usr/share/nginx/html
-> bize default olarak serve edilen dosya- Şimdi bu container'ı siliyoruz ve aşağıdaki komutu çalıştırıyoruz
docker container run -d -p 80:80 -v /Users/mebaysan/Desktop/mydockertest:/usr/share/nginx/html nginx
- -d ile container'ın arka planda çalışmasını sağlıyoruz
- -p ile port set ediyoruz
- -v ile aynı Volume bağlar gibi local makinamızdaki klasör path'ini veriyoruz ve dedik ki; container içerisindeki /usr/share/nginx/html klasörü localimdeki ilgili path'ten çeksin
- nginx -> imaj adı
- Unutmamalıyız ki bu yöntem development aşamasında kullanılır, kesinlikle production ortamında kullanmamalıyız!
- Ek protokol vb getirmeden ağ işlemlerini gerçekleştirebiliriz
- Container sistemlerinin iletişim altyapısını network driver'ları ile sağlıyoruz
- Temel 5 driver vardır
- Bridge
- Varsayılan driver'dır
- Network objesi oluşturulurken özellikle başka bir driver belirtilmezse bridge driver ile oluşturulur
- Her Docker kurulu host üstünde bridge driver ile oluşturulmuş "Bridge" adında network bulunur ve container oluşturulduğunda farklı bir driver belirtilmediği sürece default olarak buna bağlanılır
- Host
- Her sistemde host driver ile oluşturulmuş "Host" adında bir driver vardır
- Bu network'e bağlı container'da network izolasyonu olmaz. O host üzerinde çalışan bir process'mişcesine host'un ağ kaynaklarını kullanır
- Macvlan
- Bu driver ile oluşturulan network objeleri ile container'lar fiziksel ağlara kendi mac adreslerine sahip birer fiziksel ağ adaptörüne sahipmişcesine bağlanabilir
- None
- Container'a hiç bir şekilde ağ bağlantısı olmasın istersek None driver kullanılır
- Overlay
- Ayrı hostlar üzerindeki container'ların aynı ağda çalışıyormuş gibi çalışması istendiği zaman Overlay network'ler kullanılır
- Bridge
docker network ls
-> sistemdeki kurulu network objeleri listelerdocker network inspect bridge
-> bridge NAME'ine sahip objenin özelliklerini listelerdocker container run --net <NetworkObject> <CONTAINER>
--net
ile network objesini vererek ilgili network'e bağlanabilirizdocker container run --net none <CONTAINER>
-> container'a ağ bağlantısı olmaz (none)
- Ayni bridge üzerindeki container'lar birbirleriyle iletişim kurabilirler Fakat biz dış dünyadan container içerisindeki servislere erişmek istersek port publish denilen işlem sayesinde erişebiliriz.
- Örnek olarak container içerisindeki servis 80 portundan dinliyor. Biz
-p
ya da--publish
parametresi ile bu portu belirleriz ve bu sayede host makineye 80 portundan gelen istekleri container'ın 80 portuna iletiriz. - Bu işleme port publish denir. Notasyon şu şekildedir
-p <HostPort>:<ContainerPort>
-p 80:80
-> örnek-p 8080:80 -p 8043:443
-> birden fazla port publish yapabiliriz- Default olarak TCP portları açılır. Eğer istersek UDP portları açabiliriz
-p 80:80/udp
- Container'lar arası network izolasyonu sağlamak istersek ayrı bridge'ler oluşturarak bunu sağlayabiliriz
- Default bridge network içerisinde dns çözümlemesi yok
- Varsayılan dışında ip aralıkları tanımlayabiliriz
- Kullanıcı tanımlı bridge network'e bağlı container'lar birbirleriyle isimler üzerinden haberleşebilirler. Dns çözümlemesi sağlar
- Container'lar çalışır durumdayken de kullanıcı tanımlı bridge network'lere bağlanıp, bağlantıyı kesebilirler
docker container run -d --name websunucu ozgurozturknet/adanzyedocker
-> websunucu adında bir container oluşturuyorumdocker container run -it -d --name database1 ozgurozturknet/adanzyedocker sh
-> database1 adında bir container oluşturup içine giriyorum.ping websunucu1
ile ilk container'a erişmeye çalışıyorum/usr/src/myapp # ping websunucu
ping: websunucu: Name does not resolve
-> o container'a direkt container adı ile erişemiyorum; çünkü default bridge network'de dns çözümlemesi yok- Fakat IP adresi üzerinden erişebiliriz yani aralarında bağlantı var
- Şimdi container'ları siliyoruz ve kendi bridge'mizi oluşturup container'ları yeniden oluşturacağız
docker network create mybridge
-> mybridge adında bir bridge network oluşturduk. Opsiyon girmediğimiz için default olarak bridge oluşturdudocker network create --driver=host myhost
-> host network'u oluştururdocker network ls
-> network driver'lar listelenir
docker network inspect mybridge
-> network driver'ımızı inceliyoruzdocker container run -d --name websunucu --net mybridge ozgurozturknet/adanzyedocker
-> websunucu adında bir container oluşturduk ve mybridge driver'ına bağladıkdocker container run -d --name database --net mybridge ozgurozturknet/adanzyedocker
-> database adında bir container oluşturduk ve mybridge driver'a bağladıkdocker network inspect mybridge
-> mybridge adındaki driver'a bakıyoruz ve bağlı olan container'ları görüyoruzdocker container exec -it websunucu sh
-> websunucu container'ına bağlanıyoruzping database
-> database adındaki container'ı pingliyoruz ve bu sefer başarılı oluyoruz. Çünkü kendimiz bir bridge oluşturduk ve bunun üzerinde container'ları iletişime geçiriyoruz
docker network create --driver=bridge --subnet=10.10.0.0/16 --ip-range=10.10.10.0/24 --gateway=10.10.10.10 mybridge2
-> istersek oluşturduğumuz bridge'in ağ özelliklerini belirleyebiliriz- Kullanıcı tanımlı bridge'lerin en önemli özelliklerinden birisi de container'lar çalışırken bu bridge'lere bağlanabilirler
- Notasyon şu şekildedir:
docker network connect <BridgeName> <ContainerName>
docker network connect mybridge2 database
-> yukarda oluşturduğumuz database container'ını mybridge2 adındaki network'e bağlıyoruz. Unutmayalım şu an hala çalışan bir container!
docker attach database
-> çalışan bir container olan database'e bağlanıyoruzifconfig
-> yazdığımızda göreceğiz ki eth1 (mybridge2) gelmiş
docker network disconnect mybridge2 database
-> database container'ı mybridge2'den düşürüyoruzdocker network rm mybridge2
-> driver'ı sildik (bağlı bir container olmaması gerek)
- Docker araçlarını kullanarak loglara erişebiliriz
docker container run -d --name mycont1 ozgurozturknet/app1
-> arka planda mycont1 adında bir container oluşturdocker logs mycont1
-> mycont1 adındaki container'a ait loglardocker container run -d --name mycont2 -p 80:80 nginx
-> container oluşturup 127.0.0.1 adresine gidip 3-5 kere refresh yapıyorumdocker logs mycont2
-> container'a ait loglar
- Container; tek bir uygulamanın ya da servisin paketlenmiş halidir, sürekli olarak container içerisine girmeyiz.
docker top <ContainerName>
-> ilgili container içerisinde çalışan process'leri listelerdocker stats <ContainerName>
-> ilgili container'ın ne kadar kaynak kullandığını gösterirdocker stats
-> tüm container'ların kaynak kullanımını gösterir
- Eğer container oluştururken limitler koymazsak her container; sistem kaynaklarını sınırsız olarak kullanır
docker container run -dit --name mycont alpine
-> bir container oluşturuyorumdocker attach mycont
-> komutu ile container'a bağlanabilirimctrl + p q
kombinasyonu ile arka plana atabilirim (çalışmaya devam eder)
docker container run -d --memory=100m alpine
-> max 100mb kullanabilecek bir container oluşturdudocker container run -dit --name mytest --memory=100m alpine
-> mytest adında bir container oluşturuldu, max 100m kullanabilecekm
-> megabyteg
-> gigabytek
-> kilobyteb
-> byte
docker container run -dit --memory=100m --memory-swap=200m alpine
-> eğer memory limiti aşılsa bile swap olarak 200m daha kullanabilecekdocker container run -dit --cpus="1.5" alpine
-> oluşturduğumuz container sistem içerisinde ne kadar core varsa onun sadece 1.5 tanesini kullanabilecekdocker container run -dit --cpus="1.5" --cpuset-cpus="0,3" alpine
-> sadece cpu 0 ve cpu 3'ü kullanabil dedik
- İşletim sistemi bazında tanımlanan ve her yerden çağrılabilen değişkenlerdir
- Linux sistemlerde:
printenv
ile tüm ortam değişkenlerini gösterirecho $<EnvName>
-> ilgili değişkenin değerini verirexport <EnvName>=<EnvValue>
-> değişken tanımlamamızı sağlar
docker container run -it --env VAR1=deneme1 --env VAR2=deneme2 alpine sh
-> container'a 2 adet environment tanımladık. Environment'ler büyük küçük harf duyarlıdır.- Container içerisinde
printenv
kullanırsak (alpine linux olduğundan) tanımladığımız değişkenleri görebiliriz
- Container içerisinde
docker container run -it --env HOME alpine sh
-> eğer environment'e değer atamazsak sistem üzerinde o environment'i arar ve onun değerini atayıp container'a gönderir- Eğer istersek bir dosya içerisinde tüm ortam değişkenlerini tanımlayıp tek komut ile de bunu gönderebiliriz
touch env.list
echo "VAR1=deneme1" >> env.list
echo "VAR2=deneme1" >> env.list
echo "VAR3=deneme1" >> env.list
- Değişkenleri dosya içerisine ekledim
docker container run -it --env-file ./env.list alpine sh
-> --env-file parametresi sayesinde liste olarak environment'leri gönderdik
- Docker imajına verilen isim aynı zamanda o imajın nerede depolandığını da belirtir
- Docker imaj adı ile container oluşturabildiğimiz gibi imaj ID'sini de kullanarak imajlardan container oluşturabiliriz
- Docker imaj yapısı:
<RegistryURL>/<repository>:<tag>
docker.io/mebaysan/test:latest
- docker.io olmasının sebebi varsayılan olarak docker hub registry'den imaj çekilmesidir. Eğer istersek farklı registry'leri belirtebiliriz:
docker image pull gcr.io/google-containers/busybox
-> örnek olarak google image registry'den busy box adındaki imajı çektik
- docker.io olmasının sebebi varsayılan olarak docker hub registry'den imaj çekilmesidir. Eğer istersek farklı registry'leri belirtebiliriz:
- Tag'ler sayesinde tek repository içinde birden fazla versiyon tutabiliriz
docker image pull <ImageName>
-> komutu sayesinde local sistemimize bir imajı çekeriz- Tag belirtmediğimiz müddetçe default olarak
latest
tag'ı kullanılır
- Tag belirtmediğimiz müddetçe default olarak
docker tag ubuntu mebaysan/deneme
-> çektiğimiz ubuntu imajını localde yeniden adlandırdık (öncesinde pull edilmeli tabii). Artık aynı imaja mebaysan/deneme diyerek erişebiliriz.
- Docker imajı oluşturmak istersek öncelikle Dockerfile adında bir dosya oluşturmamız gerekir
- Daha detaylı bilgi için buraya Özgür hocanın repository'sine bakınız. Bu parametreleri ve açıklamalarını onun reposundan aldım.
- FROM
- Oluşturulacak imajın hangi imajdan oluşturulacağını belirten talimat. Dockerfile içerisinde geçmesi mecburi tek talimat budur. Mutlaka olmalıdır.
- Ör: FROM ubuntu:18.04
- LABEL
- İmaj metadata’sına key=value şeklinde değer çiftleri eklemek için kullanılır. Örneğin team=development şeklinde bir etiket eklenerek bu imajın development ekibinin kullanması için yaratıldığı belirtilebilir.
- Ör: LABEL version:1.0.8
- RUN
- İmaj oluşturulurken shell’de bir komut çalıştırmak istersek bu talimat kullanılır. Örneğin apt-get install xxx ile xxx isimli uygulamanın bu imaja yüklenmesi sağlanabilir.
- Ör: RUN apt-get update
- WORKDIR
- cd xxx komutuyla ile istediğimiz klasöre geçmek yerine bu talimat kullanılarak istediğimiz klasöre geçer ve oradan çalışmaya devam ederiz.
- Ör: WORKDIR /usr/src/app
- USER
- gireceğimiz komutları hangi kullanıcı ile çalıştırmasını istiyorsak bu talimat ile onu seçebiliriz.
- Ör: USER poweruser
- COPY
- İmaj içine dosya veya klasör kopyalamak için kullanırız
- Ör: COPY /source /user/src/app
- ADD
- COPY ile aynı işi yapar yani dosya ya da klasör kopyalarsınız. Fakat ADD bunun yanında dosya kaynağının bir url olmasına da izin verir. Ayrıca ADD ile kaynak olarak bir .tar dosyası belirtilirse bu dosya imaja .tar olarak sıkıştırılmış haliyle değil de açılarak kopyalanır.
- Ör: ADD https://wordpress.org/latest.tar.gz /temp
- ENV
- Imaj içinde environment variable tanımlamak için kullanılır
- Ör: ENV TEMP_FOLDER="/temp"
- ARG
- ARG ile de variable tanımlarsınız. Fakat bu variable sadece imaj oluşturulurken yani build aşamasında kullanılır. Imajın oluşturulmuş halinde bu variable bulunmaz. ENV ile imaj oluşturulduktan sonra da imaj içinde olmasını istediğiniz variable tanımlarsınız, ARG ile sadece oluştururken kullanmanız gereken variable tanımlarsınız.
- Ör: ARG VERSION:1.0
- VOLUME
- Imaj içerisinde volume tanımlanamızı sağlayan talimat. Eğer bu volume host sistemde varsa container bunu kullanır. Yoksa yeni volume oluşturur.
- Ör: VOLUME /myvol
- EXPOSE
- Bu imajdan oluşturulacak containerların hangi portlar üstünden erişilebileceğini yani hangi portların yayınlanacağını bu talimatla belirtirsiniz.
- Ör: EXPOSE 80/tcp
- ENTRYPOINT
- Bu talimat ile bir containerın çalıştırılabilir bir uygulama gibi ayarlanabilmesini sağlarsınız.
- Ör: ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
- CMD
- Bu imajdan container yaratıldığı zaman varsayılan olarak çalıştırmasını istediğiniz komutu bu talimat ile belirlersiniz.
- Ör: CMD java merhaba
- HEALTHCHECK
- Bu talimat ile Docker'a bir konteynerin hala çalışıp çalışmadığını kontrol etmesini söylebiliriz. Docker varsayılan olarak container içerisinde çalışan ilk processi izler ve o çalıştığı sürece container çalışmaya devam eder. Fakat process çalışsa bile onun düzgün işlem yapıp yapmadığına bakmaz. HEALTHCHECK ile buna bakabilme imkanına kavuşuruz.
- Ör: HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ || exit 1
- SHELL
- Dockerfile'ın komutları işleyeceği shell'in hangisi olduğunu belirtiriz. Linux için varsayılan shell ["/bin/sh", "-c"],Windows için ["cmd", "/S", "/C"]. Bunları SHELL talimatı ile değiştirebiliriz.
- Ör: SHELL ["powershell", "-command"]
- Aşağıdaki örnek senaryo için buraya bakabilirsiniz. Comment line'lar ile desteklenmeye çalışıldı.
- Ubuntu 18.04 yüklü bir sistem kur
- İşletim sistemini güncelle
- Python kur
- Uygulamayı sisteme kopyala
- Sistem başladığında uygulamanın başlamasını ayarla
docker image build -t <ImageTag> -f <DockerFileName> .
docker image build -t mebaysan/ilkimaj .
- ilkimaj adında bir imaj oluşturur
- . -> build context'i belirtiyoruz, eğer Dockerfile içinde COPY vb bir komut varsa bunlar için gerekli dosyaları sen bu çalıştığın klasör içerisinde ara
- Dockerfile'ın olduğu dizinde bir adet Dockerfile olduğundan ekstra -f parametresini girmeme gerek yok
docker image ls
komutu ile sistemimizdeki mevcut imajları görebilirizdocker container run mebaysan/ilkimaj
komutu ile oluşturduğumuz imajdan bir container oluşturduk ve ekran çıktısnı gördükdocker image history <ImageTag>
komutu ile imajın geçmişini görebilirizdocker image history mebaysan/ilkimaj
- Localde oluşturduğumuz bir Docker imajını hub'a göndermek için öncelikle CLI'da login olmamız gerekir
docker login
-> komutu ile login olabiliriz
docker image push <Image>
komutu ile localdeki istediğimiz image'i hub'a pushlayabilirizdocker image push mebaysan/ilkimaj
-> ilgili imajı pushlar
- Bir flask uygulamasını container'da çalıştırıyoruz. Daha detaylı bilgi için buraya bakabilirsiniz.
- O klasördeki Docker imajı oluşturmak için:
docker image build -t mebaysan/basitflaskimaj .
komutunu kullanıyorum
- Oluşturduğum imajdan bir container oluşturmak için:
docker container run --rm -p 80:5000 mebaysan/basitflaskimaj
--rm
-> container kapanınca otomatik olarak sil (bir daha silmekle uğraşmayalım)-p
-> bu makinaya 80 portundan gelen istekleri container'ın 5000 portuna yönlendir. Flask uygulaması 5000 portundan ayağa kalktığı için
- O klasördeki Docker imajı oluşturmak için:
echo
komutu sayesinde bir değeri çıktı olarak verir>
sayesinde bir komutun çıktısını yönlendiririzecho "deneme" > deneme.txt
&
komutun sonuna eklersek komutu arka plana atar, arkada çalışır|
1. komutun çıktısını 2. komuta iletmeye sağlarcat dosya | grep "naber"
dosya içeriğini okur çıktıyı grep'e yollar, içerisinde naber geçenleri filtrelerls ; date
-> ; sayesinde aynı anda birden fazla komut çalıştırmamızı sağlar&&
-> VE||
-> VEYA
- Healthcheck konusunu gördüğümüz dosyaya buradan bakabilirsiniz
- İmaj oluşturmak için:
docker image build -t mebaysan/basichealthcheck .
- Bu imajdan container oluşturmak için:
docker container run -d --name mycont -p 80:80 mebaysan/basichealthcheck
- ENV örneği ile container oluşturmak için:
docker container run -d --name mycont --env KULLANICI="BAYSAN" --env HOSTNAME="MyHOST" -p 80:80 mebaysan/basichealthcheck
-> ortam değişkenleri set ederek container oluşturuyoruz, detaylı açıklama Dockerfile içerisindedir
- COPY -> belirttiğimiz dosya veya klasörü belirttiğimiz PATH'e atar
- ADD -> COPY ile aynı işlevi yapar fakat dosya kaynağının bir url olmasına izin verir. Aynı zamanda kaynak dosya bir .tar dosyası ise bunu hedef klasöre decompress olarak atar
- Detaylar için buraya bakabilirsiniz
- Oluşturduğumuz Dockerfile ile imaj oluşturup aşağıdaki komut ile container oluşturuyoruz ve ADD sonucunu görüyoruz
docker container run -it mebaysan/wpadd sh
- CMD için buraya bakabilirsiniz
- ENTRYPOINT için buraya bakabilirsiniz
- CMD runtime'da değişebilirken ENTRYPOINT runtime'da değiştirilemez
- Her image'de en az 1 adet CMD veya ENTRYPOINT olmalıdır
- Eğer hem CMD hem de ENTRYPOINT varsa, CMD'de yazılanları ENTRYPOINT'e parametre olarak geçer
- Exec Form =>
CMD ["python", "app.py"]
- Shell Form =>
CMD python app.py
- Eğer komut Shell formunda girilirse bu imajdan container oluşturulduğu zaman bu komutu varsayılan shell'i çalıştırarak onun içerisinde çalıştırır. Bu nedenle container'da çalışan 1. process (pid 1) bu shell process olur
- Eğer komut Exec formunda girildiyse herhangi bir shell çalıştırılmaz ve komut direk process olarak çalışır. Container'ın pid 1'i o process olur
- Exec formunda çalıştırılan komutlar herhangi bir shell processi çalışmadığı için Environment Variable gibi bazı değerlere erişemezler.
- Eğer ENTRYPOINT ve CMD birlikte kullanılacaksa Exec form kullanılmalıdır. Shell formda CMD'deki komutlar ENTRPOINT'e parametre olarak aktarılmaz
- İmaj oluştururken, oluşturma aşamalarını kademelere bölmemize ve ilk kademede yarattığımız imaj içerisindeki dosyaları bir sonraki kademede oluşturacağımız imaja kopyalayabilmemize imkan sağlar. Bu sayede son imajımızın boyutunun küçülmesi sağlanır.
- Ör: Bir Go uygulaması yazdık ve bunu derleyip sunucuya göndereceğiz, imaj oluştururken önce kodu derler çalışan bir halini hazırlarız. Sonrasında bu çalışan derlenmiş dosyayı 2. aşamada nihai imaja koyar ve imajı oluştururuz. Bu sayede gereksiz yere kaynak kodlarını veya go derleyicisini imaj içerisinde tutmamıza gerek kalmaz
- Örnekler için buraya bakabilirsiniz
- İmaj oluştururken kullanbildiğimiz bir diğer parametre ise ARG'dır. Sadece build aşamasında kullanılabilir ve sonrasında container ayağa kalktığında erişilemez.
- Örnek için buraya bakabilirsiniz.
- Örnek bir Build Arg gönderimi
docker image build -t mytest2 --build-arg VERSION=3.8.1 .
- Dockerfile olmadan da docker imaj oluşturabiliriz
- Doğru kullanım Dockerfile olsa da tek yöntem bu değildir
- Öncelikle localimizde bir container oluşturur ve içerisinde gerekli kurulumları vs yaparız
- Ardından
docker commit <LocalContainerName> <NewImageTag>
komutu ile o container'dan bir imaj oluşturmuş oluruz- Ör:
docker commit localcont1 mebaysan/prodcont1:latest
- Ör:
docker commit -c 'CMD ["command 1", "command 2"]' <LocalContainerName> <NewImageTag>
-> -c parametresi ile CMD, EXPOSE vb. komutları bu imaja ekleyebiliriz
- Save komutu sayesinde localde oluşturduğumuz bir imajı
.tar
dosyası olarak kayıt edebiliriz, ve internet erişimi olmasa bile (hub'dan çekemiyor demektir) sunucuya atabilirizdocker save <LocalImage> -o <filename>.tar
docker save mebaysan/test -o mebaysantestimaj.tar
- Load komutu ile
.tar
olarak gelen docker dosyasını sisteme imaj olarak yükleyebilirizdocker load -i <TarFile>
docker load -i mebaysantestimaj.tar
- Kendi ağımızda ücretsiz olarak bir docker deposu oluşturabiliriz
- Bunun için yine Docker Hub üzerinden 😊 registry imajını kullanacağız
- Bu imaj sayesinde bir container çalıştıracağız. İçerisinde docker hub'a benzer bir yazılım çalıştırıyor. 5000 portundan ayağa kalkıyor.
docker pull registry
imajı locale çekiyoruzdocker container run -d -p 5000:5000 --restart always --name registry registry
- restart parametresi container down olduğunda ne yapılacağını alır
always
-> down olunca ne olursa olsun restart atno
-> down olunca bir şey yapmaon-failure
-> sadece hata olur da kapanırsa yeniden başlat fakat biz elimizle manuel kapatırsak yeniden başlatmaunless-stopped
-> manuel olarak stop edersek başlatmaz fakat geri kalan her durumda başlatır
- 5000 portunu 5000 portuna publish ettik
- registy adındaki container'ı registry imajından oluşturduk
- restart parametresi container down olduğunda ne yapılacağını alır
http://127.0.0.1:5000/
altında çalışmaya başlarhttp://127.0.0.1:5000/v2/_catalog
altında kayıtlı repoları gösterir,localcont1
adında bir imaj oluşturduğumuzu varsayalımdocker push localhost:5000/localcont1
-> localdeki imajı registry'e kayıt ettidocker pull localhost:5000/localcont1
bu adrese erişebilen makinalar; komutu ile local registry'deki imajı çekebilir
- Compsoe, çoklu Docker uygulamalarını oluşturmak ve çalıştırmak için kullanılan bir araçtır
- Compose ile uygulamanın hizmetlerini yapılandırmak için bir YAML dosyası kullanılır
- Daha sonra tek bir komut ile tüm hizmetleri yapılandırmaya başlar ve sistemi başlatırız
- Compose production için çok uygun bir araç değildir. Development aşaması için idealdir
- Compose, Docker Engine ile birlikte gelen bir araç değildir. Bunu ayrıca sisteme kurmamız gerekir.
- Mac ve Windows sistemlerde Docker Desktop kurduğumuzdan bu uygulama ile birlikte kurulu olarak Compose gelmektedir
docker-compose.yml
dosyası içerisinde gerekli konfigürasyonlar tutulurdocker-compose up -d
ile .yml dosyası kullanılarak sistem ayağa kaldırılırdocker compose down
ile sistem kapatılır
- docker-compose komutlarını kullanmak için yml dosyası ile aynı dizinde olmamız önemlidir
docker-compose up
-> aynı dizindeki docker-compose.yml dosyasını kullanarak sistemi başlatırdocker-compose up -d
-> arka planda (detach) çalıştırır- docker objelerini isimlendirirken; sistemdeki diğer objeler ile çakışmasın diye docker-compose.yml dosyasının bulunduğu klasör adıyla başlayan isimlendirme yapar ->
klasorAdi_objeAdi
docker-compose down
-> tüm servisleri (docker objeleri) kapatır ve siler- her şeyi siler fakat volume'leri silmez
docker-compose config
ile docker-config.yml dosyasını gösterirdocker-compose images
-> servislerin hangi imajlarla oluştuğunu gösterirdocker-compose logs
-> tüm servislerin loglarını listelerdocker-compose exec
-> compose ile oluşturduğumuz servisin içinde komut çalıştırırdocker-compose exec <ServiceName> <Command>
- Detaylar için buraya bakabilirsiniz
- İlgili dizinde
docker-compose up -d
komutu sayesinde bu config dosyasından sistemi ayağa kaldırıyorum.http://127.0.0.1/
adresine gittiğimizde başarılı bir şekilde wordpress kurulumunu görmüş olacağız
- İstersek imajımızı compose ayağa kalkarken oluşacak şekilde ayarlayabiliriz
- Bunun için docker-compose.yml dosyası ile aynı dizinde bir Dockerfile oluşturmamız gerekir. Dockerfile içerisinde istediğimiz imajı hazırlarız.
- Compose file içinde ise servisi hazırlarken image yerine
build
key'ini kullanırız ve build olacak Dockerfile'ı aynı dizinde olduğundan.
ile belirtiriz - Daha detaylı bilgi için buraya bakabiliriz
- Kod içerisinde güncelleme yaptığımızda ise önce imajı güncellememiz gerekir. Bunun için de
docker-compose build
komutunu kullanır önce build aldığımız imajı güncelleriz. Sonrasındadocker-compose up
ile servisleri ayağa kaldırırız
- Container Orchestration, containerların dağıtımını, yönetimini, ölçeklendirilmesini ve ağ oluşturulmasını otomatikleştirme işlemine denir
- Yüzlerce container'ı bir arada yönetmek için kullanılan yazılımlardır
- En bilinen araçlar:
- Swarm
- Docker engine ile gelen bir araçtır. Docker tarafından geliştirilmiştir
- Bir Docker ana bilgisayar havuzunu tek bir sanal ana bilgisayara dönüştürür
- Kubernetes
- Neredeyse sektör standardı haline gelmiştir
- Container uygulamalarının dağıtımını, ölçeklendirilmesini ve yönetimini otomatikleştirmek için oluşturulmuş açık kaynaklı bir sistemdir
- Kolay yönetim ve keşif için uygulamayı oluşturan container'ları mantıksal birimler halinde gruplandırır
- Google'da 15 yıldan fazla süreye sahip olan container deneyiminin açık kaynak topluluk dünyası üyelerinin tecrübelerine eklenerek oluşturulmuştur
- Swarm
- Docker Engine'e gömülü bir container orchestration çözümüdür
- Bir docker ana bilgisayar havuzunu tek bir sanal ana bilgisayara dönüştürür
- Hostlar arasında şu portlar açık olmalıdır
- TCP port 2377 -> Cluster yönetimi
- TCP ve UDP port 7946 -> Nodelar arası iletişim
- UDP port 4789 -> Overlay network
- Bir adet manager tarafından diğer hostlar yönetilir
- docker swarm init komutunu çalıştırdığımızda üzerinde bulunduğumuz host sistemi engine moddan swarm mode geçirir
- Swarm birden fazla manager node destekler ve bu sayede yüksek erişilebilirlik sağlar. Bir managerda sorun olursa diğer manager devreye girer ve iş yürümeye devam eder
- Manager nodelardan yalnızca 1 tanesi lider olarak seçilidir ve tüm yönetim lider tarafından yapılır. Diğer manager nodelar pasif durumdadır. Pasif manager nodelardan birine bir komut verip iş yapmasını istersek bu sadece proxy görevi görür ve komutu lider node'a iletir
- Birden fazla manager olan ortamlarda bir adet lider seçilmelidir. Swarm bunu otomatik halleder ve bunun için Raft Consensus algoritmasını kullanır. Raft algoritması; lider seçimi için kuralları belirlemeye yarar. Mesela ortamda 5 manager olan durumda bir şekilde lider olan nodea erişilemezse belirli bir zaman sonra kalan 4 node kendi aralarında oylama yaparak lider belirler. Artık swarm-cluster'ın yönetimi bu lider tarafından yapılır
- Raft algoritması yalnızca (n-1)/2 sayıda nodeun devre dışı kalmasını tolere edebilir. (5 node için max 2 hata tolere) Aksi halde yönetim altyapısı çalışmayacaktır
- Raft algoritmasının düzgün çalışabilmesi için ve lider seçiminin sorunsuz olması için ortamın her zaman tek sayıda manager nodela kurulmuş olması gerekir. 7'den fazla manager olduğu durumlarda ortamda daha fazla sorun çıkması muhtemeldir.
- Swarm cluster kurulur, ve cluster'a worker node olarak dahil ol deriz
- Manager node'dan sertifika çekerler ve emir beklerler
- İstediğimiz sayede worker node ekleyebiliriz
- Bu bölüm için labs.play-with-docker.com adresine gidiyorum ve 5 adet instance oluşturuyorum
- Bir hostu swarm moda alacağız
docker swarm init --advertise-addr 192.168.0.8
bu hostun swarm modunu aktif ediyoruz (192.168.0.8 play with docker tarafından kullandığımız hosta verilen IP)- advertise-addr -> host üzerindeki kullanmak istediğimiz network kartına ait adres
docker swarm join-token manager
-> bir nodeu cluster'a manager olarak eklemek için gerekli olan komutu ve tokeni verecek- manager olarak eklemek istediğimiz node'a (hosta,makinaya,cihaza) gidip ilgili komutu yapıştırdığımızda cluster'a manager olarak eklenecek
docker swarm join-token worker
-> bir node'u cluster'a worker olarak eklemek için gerekli olan komutu ve tokeni verecek- aynı şekilde worker olarak eklemek istediğimiz node'da çalıştırıp nodeu worker olarak cluster'a ekleyeceğiz
- swarm mode'u aktif ettiğimiz node'a gidip
docker node ls
komutu ile cluster hakkında bilgi sahibi olabiliriz - swarm manager olan node'a gidip
docker service create --name test --replicas=5 -p 8080:80 nginx
komutu ile- adı test olan (--name)
- 8080 portu 80 portuna publish edilmiş (-p)
- nginx imajından
- 5 adet container oluştur (--replicas=5)
docker service ps <ServiceName>
-> adı verilen service hakkında bilgi getirir
- Swarm service'lerinde 2 mod vardır.
- Replicated
- Aksini belirtmediğimiz sürece bu modda servis oluşturulur
- Oluşturmak istediğimiz servisin kaç replica içereceğini belirtiriz
- Swarm uygun nodelarda o sayıda replica oluşturur
- Global
- Servisin kaç replica içereceğini belirtmeyiz. Swarm altındaki her node üzerinde 1 replica oluşturur-
- Replicated
docker service create --name test nginx
-> nginx imajından test adında servis oluştur- replika sayısını belirtmediğimiz için 1 adet oluşturdu
docker service ls
-> service listesini görebilirizdocker service ps test
-> test adındaki servisi altındaki tasklara ait detayları görebilirizdocker service logs test
-> test servisi altındaki tüm container'lara ait logları gösterirdocker service inspect test
-> test servisine ait detaylar- Swarm servislerinin en önemli özelliklerinden biri servislere hızlıca yeni replikalar oluşturabiliriz
docker service scale test=3
ile test servisimize yeni 2 replika daha (zaten 1 replika ile oluşturmuştuk) ekliyor. Aynı şekilde azaltabiliriz de
docker service rm test
-> test adındaki servisi silerizdocker service create --name myglb --mode=global nginx
-> servisi global modda oluşturur (her node üzerinde 1 replika)- Update işlemi
- update yapınca servisteki containerlardan birini siler yerine yeni güncellenmiş container'ı koyar ve sıradaki eski container'a geçer, siler yerine güncellenmişi koyar ve diğerine geçer ...
docker service create --name websrv --network over-net -p 8080:5000 --replicas=10 mebaysan/basitflaskimaj
- adı websrv olan
- over-net adında oluşturulmuş network driver'a bağlı
- 8080:5000 port publish yapılmış olan
- 10 adet replikaya sahip bir servis oluştur (play with docker platformu üzerinde over-net adında bir overlay network oluşturdum & 3 manager 2 workerlı bir cluster oluşturmuştum)
--update-delay
-> bu parametre, güncellemeler arasında ne kadar bekleyeceğini belirtmemizi sağlar (bir containeri sil gyerien güncellenmişi koy parametre kadar bekle diğerine geç gibi)--update-parallelism
-> bu parametre sayesinde aynı kanda kaç container'ın güncelleneceğini söyleriz (aynı anda 2 container sil güncelle 5 sn bekle diğer ikisine geç gibi)docker service update --detach --update-delay 5s --update-parallelism 2 --image mebaysan/basitflaskimaj websrv
- arkaplanda (detach)
- 5 saniyede bir (update-delay)
- aynı anda 2 container olacak şekilde
- mebaysan/basitflaskimaj adındaki imajdan
- websrv adındaki servisi güncelle
docker service rollback --detach websrv
-> arkaplanda websrv adındaki servisi bir önceki haline getir
- Overlay network aslında bir network driver'dır
- Farklı merkezlerde bulunan nodelar sanki aynı merkezdeymiş gibi haberleşebilir
- Bir swarm cluster oluşturulduğu zaman ingress adında bir overlay network de otomatik olarak oluşturulur. Aksini belirtmediğimiz sürece oluşturduğumuz servisler bu overlay network'e bağlanır
- İstersek user defined overlay networkler de oluşturabiliriz
- Overlay networklerin temel yönetim katmanının haberleşme altyapısı encryptedir. Fakat buraya bağladığımız containerların birbirleriyle iletişimi varsayılan olarak encrypted değildir. Overlay network oluştururken
--opt encrypted
parametresini kullanarak bu trafiğin de encrypted olmasını sağlayabiliriz. Bu opt encrypted overlay netowrk trafiğini biraz yavaşlatacaktır. - Aynı overlay network'e bağlı servislerin containerları birbirleriyle herhangi bir port kısıtlaması olmaksızın haberleşebilirler ve sanki aynı ağdaymış gibi çalışırlar.
- Swarm altında yaratılan servisler aynı overlay network üzerinde birbirlerine servis isimleriyle ulaşabilir. Docker burada hem dns çözümlemesi hizmeti hem de load balancing hizmeti sağlar
- Overlay network üzerinde port publsh de yapabiliriz. Swarm overlat networklerde ingress routing mesh destekler. Port publish edip Docker host üzerinden o porta erişirsek Docker o host üstünde o portun publish olduğu bir container bulunmasa bile bulunan bir host'a trafiği yönlendirecek ve cevap verecektir
docker network create -d overlay over-net
-> adı over-net olan overlay bir network oluştur
- Conteinar'larda plain text olarak tutmamızın güvenlik zafiyeti oluşturabileceği username ve password gibi verileri secret objeleri şeklinde encrypted olarak transfer edebiliriz
- Docker Swarm, aynı volume ve container'lar gibi birer Docker objesidir
- Swarm altında bir isim ve değer şeklinde secretler oluşturabiliriz. Bu objeler Swarm cluster'ın raft deposunda encrypted olarak saklanıyor. Bu secretleri istediğimiz servislere bağlayabiliyoruz. Secret, Swarm manager'dan servisin çalışacağı container'a transfer ediliyor (encrypted). Bağlandığı service container'larının /run/secrets klasöründe erişilebilecek şekilde map ediliyor. O container bu path içindeki objeye erişiyor ve kullanıyor
docker swarm init
diyerek swarm cluster oluşturuyoruz- Secret oluşturmanın iki yolu vardır. Birincisi metin dosyalarından oluşturmaktır
- username.txt ve password.txt dosyalarımın olduğu dizine gidiyorum.
docker secret create <SecretName> <FilePath>
komutu ile secret oluşturuyoruzdocker secret create username ./username.txt
docker secret create password ./password.txt
docker secret ls
ile Secret'leri listelerizdocker secret rm <SecretName>
ile Secret silerizdocker secret inspect <SecretName>
ile Secret inceleyebiliriz
- username.txt ve password.txt dosyalarımın olduğu dizine gidiyorum.
- İkinci yöntem ise terminalden oluşturmaktır
echo "<SECRET>" | docker create <SecretName> -
echo "Bu bir secrettir" | docker secret create deneme -
docker service create -d --name secrettest --secret username --secret password mebaysan/basitflaskimaj
-> bir servis oluşturduk ve içerisine cluster'daki secretları gönderdikdocker exec -it 0c sh
-> oluşturduğumuz container'a bağlandıkcd /run/secrets
-> secretların tutulduğu dizine gidiyoruz ve orada oluşturduğumuz secret isimleriyle dosyalar görüyoruz. Bunların değerleri de secretların değerleridir- Secret'i güncellemek istersek service'i güncellememiz gerekir
- Önce cluster'da yeni bir secret oluşturuyoruz (varsayalım ki username2 adında olsun)
docker service update --secret-rm username --secret-add username2 secrettest
--secret-rm username
secrettest servisindeki username adlı secreti sil--secret-add username2
ilgili servisteki username secret'in yeni değerini cluster'daki username2 secretinin değeri olarak güncelle
- Docker Compose'daki gibi bir işleme benzer. Stack de bunu swarm ortamında yapmamızı sağlar.
- docker-compose.yml dosyası kullanır
- Docker Compose dosyası ile arasında bazı farklar var
- Docker Engine ile tanımlı komutlar Compose ile kullanılabilirken Stack için kullanılamaz
- Stack için uygun olan komutlar Compose ile kullanılamaz
- İlgili dosyanın bulunduğu dizine gidiyorum
docker stack ls
-> oluşturduğumuz stckleri listelerdocker stack ps
-> stack altındaki taskları görebilirizdocker stack rm <StackName>
-> ilgili stack i silerdocker stack services <StackName>
-> ilgili stack altındaki servisleri listelerdocker stack deploy -c ./docker-compose.yml ilkstack
-> docker-compose.yml'dan bir stack oluşturur ve ayağa kaldırır.- ilkstack adındaki stack'i bu dizindeki docker-compose.yml dosyasından oluşturur
- stacklerde docker-compose.yml pathini belirtmemiz gerekir