Docker - The core part (Image & Container)

Docker - The core part (Image & Container)

  • Docker bizim containerları hazırlamak için kullandığımız tooldur.
  • Docker kullanmamızın nedenlerinden birisi ise, biz kendi projemizi node.js’in belirli spesifik bir sürümü ile örneğin v13 ile yapıp, herhangi bir node.js uygulaması çalıştıran siteye yüklersek orası belki v12 node.js kullandığı için uygulamamız hata verebilir, fakat docker ile uygulamalarımızı standartlaştırarak containerlar oluşturur ve bu containerları docker destekleyen bir sunucuya(AWS gibi…) yüklersek, uygulamalarımız her zaman bizim belirlediğimiz standartlara göre çalışacaktır.

Install Docker

  • Önce Hyper-V ve Containers’ı Turn Wiondows feature on/of kısmından aktif ediyoruz.
  • Sonra Dockerın sitesite giderek kullandığımız OS’e göre Dockerın kendisini yüklüyoruz.

docker … --help

  • Başlamadan öcne bilmemiz gereken en önemli şeylerden birisi de, terminalde çalışırken tüm docker komutlarının detaylarını --help yaparak inceleyebiliriz.

docker images --help
docker image --help
docker container --help

IMAGES

Dockerfile

  • Her türlü uygulamayı içine sadece Dockerfile ekleyerek docker ile bir imageye çeviririz.

  • Image uygulamamız için gerekli olan herşeyi içine alır.

  • Ve biz bu imageyi dockera vererek containerla çalıştırmasını isteriz.
  • Imagemiz hazır olduktan sonra registirye göndeririz. Burası docker hub yani github gibi bir yerdir herkes kullanabilir. Daha sonra registirydeki bu imagemizi buradan herhangi bir docker çalıştıran makinada uygulamamızı çalıştırabiliriz.

  • Ve ayrıca imageler aşağıdakileri de içerir.

.dockerignore

  • Tabi ki de node_modules klasörünü docker imagesine koymak istemeyiz çünkü çok büyük boyutlarda olabilirler bunun içinde .dockerignore dosyası oluşturup içine istemediğimiz dosyaları ve klasörleri yazarız. Aşağıdaki gibi…

CONTAINERS

  • Containerı ise bir piknik sepeti gibi düşünebilirsiniz. Nasıl piknik yapmak için tek ihtiyacımız olan bir piknik sepeti ise, bir projede ihtiyacımız olan her şey bir container içinde olur.

Images vs Containers

  • Aynı image birden fazla container ile çalışabilir.
  • Imageler kendilerine has environment variableslarına sahip olabilirler.
  • Imageler uygulamamızı ve kodlarımızı taşır ve onların blueprintsleridir.
  • Imagesler read ve only iken containerlar write, read ve execute accesine sahiptirler.
  • Imagesler bir layerdır, containerlarda aslında onların parent layerlarıdır diyebiliriz.
  • Birbirlerini etkilemeden aynı imageyi farklı bir çok container ile çalıştırabiliriz.
  • Containerlar, imageler üzerinde yalıtılmış isolated edilmiş bir yazılım birimidir.

DOCKER BASIC EXAMPLE

  • Gelin ilk basit uygulamamızı birlikte dockerize edelim.
  • Elimizde aşağıda ki gibi app.js dosyası olan ve log basan bir dosyamız var.
  • İlk olarak Dockerfile adında bir dosya oluşturuyoruz.

  • Daha sonra FROM ile bu imagemizin çalıştıracağı imageyi ayarlıyoruz. app.js’i node.js ile çalıştıracağımız için, node.js’e sahip bir image layerını burada seçmemiz gerekiyor ki Docker bu imageyi alıp bizim çalıştırmasını istediğimiz node.js dosyasını yani app.js’i çalıştırabilsin.
  • Ve daha sonra distrubitionu seçiyoruz. Alpine bir linux distrubitiondur. Bizim node imagesini direk kullanmak yerine node:alpine kullanmamızın nedeni, boyutu ve performans açısından direkt olarak node.js imagesinden daha performanslı olmasıdır.

  • Aşağıda ki resimde dockerhub’da aratarak bulduğum, aynı zamanda yukarıda da FROM ile kullandığımız node:alpine gibi bir image görüyorsunuz aslında.

  • Daha sonra COPY diyerek “.” ile tüm dosyalari kopyala yapıyoruz ve “/app” klasorüne kopyalansın diyoruz.
  • Ve daha sonra CMD ile komutu çalıştır diyoruz. İlk önce bunu normalde kendi makinamızda çalıştırsaydık node app.js diyeceğimiz için burada da dockerın node ile calıştırmasını söylüyor ve dosyanın yerini veriyoruz. Kopyaladığımız dosyaları app adında bir klasöre atmıştık hatırlarsanız.

  • Veya WORKDIR ile bir çalışma yolu belirleyerek daha sonra node app.js de yapabiliriz CMD ile.

  • Ver ilk Dockerfile’mızı oluşturduk. Şimdi imagemizi oluşturup çalıştırabiliriz. Fakat bu detaylara daha sonra geleceğim.

Dockerfile

  • Dockerfile içinde aşağıdaki alanlar bulunur. Tüm bu kısımları detaylıca birlikte göreceğiz merak etmeyin.

FROM specify BASE iamge
WORKDIR Working directory calisma dizini
COPY kopyalamaya yarar
ADD kopyalamya yarar
RUN execute etmeye yarar kodlari
ENV environment variables tanimlariz
EXPOSE dockerin imageyi calistiracagi portu ayarlar
USER uygulamayi calistiracak useri tanimlar
CMD commandin execute edilmesini saglar her acildiginda
ENTRYPOINT commandin execute edilmesini saglar her acildiginda

EXAMPLE of CREATE-REACT-APP

  • Yukarıdaki bilgiler ışığında create-react-app ile daha complex bir uygulama oluşturup bunu dockerıze edebiliriz. Ben create-react-app react-app yapıyorum.

FROM

  • Dockerhub’da bir image buluyoruz FROM da kullanacağımız. Biz react projesini dockerıze edeceğimiz için bir node.js imagesi buluyoruz. Alpine sürümlerinin boyutları az olduğu için onları tercih ediyoruz.

  • Terminali açıp Dockerfile’mızın olduğu konuma geliyoruz. Ve aşağıdaki kodları uygulayarak neler yaptığını görüyoruz.

docker build .

  • Aslında şimdi Dockerfilemızı build alıp image oluşturarak, node:14.16.0-alpine3.13 deki linux terminale bağlanabiliriz.
  • Burada ki “.” ile ise Dockerfile mizin olduğu konumu söyleriz.

docker images

  • Makinemizde oluşturduğumuz veya çektiğimiz tüm imageleri gösterir. (Intermediate imageler hariç)

docker images -a

  • Tüm imageleri gösterir.

docker image ls

  • Tüm imageleri listeler. docker images ile aynı işlevi gerçekleştirir bir nevi.

docker image prune

  • Kullanılmayan imageleri siler.
  • Kullanilmayan imageleri sildikten sonra imageleri listelersek sadece kendi olusturdugumuz ve pull yaptigimiz imageleri goruruz.

docker image prune -a

  • Kullanılsın kullanımlasın tüm imageleri siler.

docker rmi imageName:tag/imageId

docker image rm imageName:tag/imageId

  • Prune ile silinmeyen yukarıda ki gibi imageleri silmek içinse asağıda ki gibi docker image dedikten sonra remove anlamına gelen rm ve image adınıveya idsini yazariz.
    docker image rm react-app
    docker image rm df3

docker ps

  • Çalışan bütün containerları gösterir.

docker ps -a

  • Bütün containerları gösterir.

docker container ls

  • Tüm containerları listeler. docker ps -a ile aynı işlevi gerçekleştirir bir nevi.

docker container prune

  • Kullanılmayan containerları siler.

docker rm containerName/containerId

docker container rm containerName/containerId

  • prune ile silinmeyen containerları silmek içinse asağıda ki gibi docker container dedikten sonra remove anlamina gelen rm ve container adını veya idsini yazarız.
    docker container rm react-app
    docker container rm df3

docker rm -f containerName/containerId

docker container -f rm containerName/containerId

  • Çalışan containerları force yaparak önce durdurur sonra siler. Yukarıda ki kodla çalışan containerları silemeyiz.

docker stop containerId

  • Bu şekilde de belirli bir container id ye sahip containerin çalışmasını durdururuz.

docker start -i containerId

  • Bu şekilde de belirli bir container id ye sahip containerı çalıştırırız. Id’nin ilk 3 karakteri de yeterli olur. Veya id yerine containerName de yazabilirsiniz.
  • -i terminal ile interact olmasını sağlar yani terminale bağlnamasını sağlar.

exit

  • -it ile interactive bir şekilde başlattığımız containerlar Docker container sessionunu kapatır ve terminalden çıkar. Fakat containerı tamamen silmez bunu bizim yapmamız gerekiyor.

Naming/Tagging Images

  • Developmentda tagsiz kullanmakta sorun yok ama productionda tagging kesinlikle yapmalıyız. Çünkü ileride yeni tagli versiyonda bir sorun çıkarsa eski tagi bilerek tekrar hemen dönebiliriz.

docker build -t imageName .

  • Imageleri listelediğimizde eğer imagelere sadece imageName verdiysek latest tagını görürüz default olarak.

docker build -t imageName:tag .

  • Oluşturacağımız imagelere -t ile tag ekleyerek isimlendirebiliriz.

docker build -t react-app:v0.0.01 .

  • Yukarıda oluşturacağımız image için react-app isimlendirmesi yaptık ve tag olarakda v0.0.01 olsun dedik.

  • Genel olarak latest tagini her zaman en son versiona sahip olan image olarak tutmalıyız. Ve latest tagindeki imageyi docker ile çalıştırtmalıyız.
  • Tagleri hem dockerfile da yada hemde run timeda asagidaki gibi yazabiliriz.
  • Tag verirken bir kac cesit tag verme turu vardir.
    Versiyon numarası ile: docker build react-app:v0.0.01 .
    Sıralamalı : docker build react-app:0 .

tag

docker image tag imageId/imageName:tag imageId/imageName:tag

  • Bu kodla varolan bir imageyi kopyalayarak yeniden yeni bir isim ve tagle yeni bir image oluşturabiliriz. Veya varolan bir imageyi seçerek, başka bir varolan imagenin bu imageye dönüşmesini sağlayabiliriz. Örneğin yukarıdaki kodda ilk imageId ile seçtiğimiz image bizim için bir referans, daha sorna sında seçtiğimiz ise yeni oluşturtmak istediğimiz image olacak. Veya ikinci seçtiğimiz image adında bir image zaten varsa onu alıp bizim ilk seçtiğimiz imageye çevirtiriz.
  • tagi kullanmadan önce aşağıda ilk olarak Dockerfile’a WORKDIR /app adında bir satır daha ekleyerek bir değişiklik yapıyorum.

  • Sonra build alarak v0.0.02 tagli yeni imagemi oluşturuyorum.

  • Yukarıda göreceğiniz üzere yeni son version imagemin idsi latest versiondan farklı. Bunu düzeltmemiz gerekiyor.

docker image tag 5af react-app:latest

  • Ve aşağıda 5af id si ile başlayan imageyi seçiyoruz ve artık react-app:latest adında bir image yoksa bunu oluşturmasını veya varsa da bu imagenin artık 5af id li image ile aynısı olmasını istiyoruz.

docker image tag 5af react-app:v0.0.03

  • Veya hiç olmayan bir image adı ve tagiyle yeni bir image kopyası oluşturabilirdik. tabi ben daha sonra bu v0.0.03'ü aşağıda ki kod ile kaldırıyorum.
    docker image rm react-app:v0.0.03

docker run

docker run imageId/imageName

  • Bu kodla oluşturduğumuz imageleri çalıştırabiliriz.

docker run react-app

docker run react-app:v0.0.01
docker run react-app:latest
docker run 34870cf3b371
docker run 348

  • Yukarıda bir imageyi genel olarak çalıştırabileceğiniz bir birinden farklı şekilde yöntemleri gösterdim. ister image adıyla, ister image adı ve versiyon numarası ile, ister id ile istersenizde idnizin 3 karakteri ile imagelerimizi çalıştırabiliriz.

docker run node

  • Bu şekilde çalıştırırsak dockerhub dan node imagesinin son güncel imagesini alıp, makinemize kurup, arka planda bir container oluşturup, node imagesini çalıştıracaktır.

docker run -it imageId/imageName

  • -it ile interactive diyerekde imagelerimizi çalıştırarak ardından terminale bağlanabiliriz.

docker run -it node

  • Bu şekilde yaparsak -it ile interactive diyeceğimiz için docker node’un son imagesini indirip yeni bir container oluşturup, bu imageyi kullanarak node imagesini interactive olarak çalıştıracak ve terminale bağlanacaktır. Asagidaki gibi.
  • Ve aşağıda göreceğiniz üzere node imagesini run yapip -it ile terminale bağlandığım zaman nodeun versionu 15.4.0, benim kendi makinemdeki ise 14.15.4. Yani burda çalışan container aslında bir sanal makine.

**NAMING CONTAINERS

docker run -d --name fakeName imageId**

  • Aynı containerı farklı bir isim ile çalıştırmak böylelikle aynı containerı aynı anda 2 kere çalıştırabiliyor olacağız.

  • Ve şimdi 2 containerımız var bunlardan birisi blue-sky

docker run --rm imageName

· İmagenin çalıştırıldığı container durdurulduğunda, containerın otomatik olarak silinmesini sağlar.

docker build -it react-app .

  • Ve şimdi eğer aşağıda ki gibi docker run yapip -it yani interactive şeklinde oluşturduğumuz imagemizi çalıştırırsak sanal docker makinasında çalışan bir node terminalini çalıştırmış olacağız çünkü “FROM”a “node”u vermiştik hatırlıyorsanız.

  • Eğer bu şekilde başlatmayı denersekte hata alırız çünkü alpine linux imagesi bash ile birlikte gelmez, shell ile gelir. O yüzden boyutu azdır.

  • Fakat sh ile shelli çalıştırsaydık hem linux dosya sistemini görebilirdik hem de node versiyonumuzu görebilirdik çalışan docker makinamızda.

COPY / ADD - WORKDIR

  • Şimdi uygulama dosyalarımızı imageye kopyalamamız gerekiyor.
  • WORKDIR ile çalışma dizinini /app yapıyoruz. Bu şekilde containerımızı çalıştırdığımızda /app dizininde uygulamamız ayarlanıp başlatılacak.
  • COPY ile tüm package ile başlayan dosyalar ve README.md dosyasını /app/ klasörüne kopyalıyoruz.
  • Veya dilersek 2. COPY deki gibi . ile tüm dosyaları seçerek /app/ klasörüne kopyalayabiliriz.
  • Veya . ile tüm dosyaları seçerek ikinci nokta ile de olduğumuz klasçre yani /app/’e kopyalayabiliriz. Buradaki 2. COPY deki birinci . bizim Dockerfilenin bulunduğu dizini, ikinci . ise imagenin WORKDIR’ini temsil eder yani /app/ dizinini.

  • ADD ile ise bir link ekleyebiliriz veya file.zip gibi sıkıştırılmış dosyalariı açarak istediğimiz yere çıkartabiliriz.

RUN

  • Dockerı yukarida ki haliyle çalıştırdığımızda dependenciesler yüklü olmadığı için sorun olacaktır. O yüzden dependenciesleri imagemizi çalıştırdıktan sonra yükletmeliyiz aşağıda ki gibi.
  • Aşağıdaki gibi RUN komutuyla npm komutumuzu çalıştırarak gerekli dependenciesleri yükleyebiliriz.

  • Aşağıdaki gibi 2 tane komut da çalıştırabiliriz fakat apt komutu FORM daki imagemizden gelen alpine surumu linuxde olmadığı için hata alırız.

ENV

  • Environment variableları ise aşağıda ki gibi ya aralarında bir boşluk bırakarak yada = ile tanımlayabiliriz ben = ile tanımlamayı tercih ediyorum.

  • Ve daha sorna imagemizi oluşturup containerimızı shellde interactive olarak imagemizi çalıştırdığımız da istersek bu environmentlerı aşağıda ki gibi görebiliriz..

  • Veya shell ile çalıştırdığımız için istersek yazdırabiliriz de echo yaparak.

EXPOSE

  • Expose ile port exposing işlemlerimizi yapabiliriz. Dockerda port atadığımızda çalışan port containerda çalışır host üzerinde çalışmaz bunu anlamamız gerekir.

  • En son oluşturduğumuz Dockerfile bir üstteki Dockerfile’dır. Gelin bunu build alalım ve npm start ile birlikte çalıştıralım ve react-app uygulamamızı çalıştırıp, -it ilede interactive olarak bağlanarak uygulamamızın çalıştığından emin olalım.

docker run react:app:latest npm start

  • Direk npm start komutunu yukarıda ki gibi yazarak run time terminal kodlarımızı burada da çalıştırarak react-app uygulamamızı sanal makinamız üzerinde çalıştırabiliriz.

Burada çalışan localhost:3000 kullandığınız sistemdeki 3000 değildir. Bu containerın ait olduğu sanal sistem üzerinde uygulamamızın çalıştığı porttur. Bu portu daha sorna göstereceğim işlemlerle kendi işletim sistemimizdeki porta bind etmeyi öğreneceğiz.

CMD

  • Sürekli yukarıda ki gibi containerı başlatırken npm start yapmak güzel değildir. İşte bunun için docker bunun yerine bize CMD keyini vermiş bu komutlarımızı burada aşağıda ki gibi Dockerfile içinde tanımlayabiliriz.
  • CMD kodunu sadece bir kere yazabiliriz 2. Bir CMD komutu olursa hangisi en sonda olursa o sadece çalışır.

  • CMD’leri 2 şekilde tanımlayabiliriz.

  • Shell form şeklinde yukarıda ki gibi,
  • Execute form şeklinde array içinde string gibi
    (Benim tavsiyem her zaman execute form yapısında olanı kullanmanızdır.)

CMD vs RUN

  • RUN build-time talimatıdır yani build-time da çalışır.
  • CMD ise run-time talimatıdır yani containerımızı çalıştırırken çalışır.

ENTRYPOINT

  • CMD ile yaptıkları işlemde, kullanımları da aslında bire bir aynıdır. Yine 2 şekilde tanımlanır. Yani shell form veya execute form şeklinde.

ENTRYPOINT vs CMD

  • Eğer CMD tanımladıktan sonra aşağıda ki gibi containerı çalıştırırken farklı bir command eklersek bu komut, Dockerfile içindeki CMD deki komutu ezer fakat ENTRYPOINT deki komutu ezemez.

  • Veya illa da ezdireceksek aşağıda ki gibi --entrypoint şeklinde tanımlamamız gerekiyor.

LAYERS

  • Yukarıda ki en son bıraktığımız Dockerfilemıza bakarak, Layerlar Dockerfile ile oluşturacağımız imageler içerisinde ki katmanlardır. Docker ilk başta node imagesini alır ve bir layera koyar. Node imagesi ise kendi içinde bir kaç layerdır. Kalan kodlarda ki her bir satırda aslında farklı bir kaç layer oluşturur.

docker history imageId/imageName

  • Layerları görmek için aşağıda ki kodu yazıyoruz. Ve burada gmrdüğünüz her satır bir layerdır aslında.

CACHING

  • Image oluşturulurken ilk başta cache verisi olmadığı için kullanılamaz. Fakat ne zaman dosyalarımızda bir değişiklik olursa ve tekrar build alırsak o zaman bazı layerlar cacheden alınır bazıları ise yeniden oluşturulur. Docker bunu yaparken değişiklik olan kısıma kadar olan tüm heryeri cachelediği veriden alır, kalan kısımları tekrar hesaplayarak yeni build oluşturur.
  • Caching yapısını daha iyi görebilmek için ilk önce tüm imagelerimizi siliyoruz. Eğer çalışan bir container varsa imageyi silemeyiz o yüzden önce tüm containerları siliyoruz daha sonra tüm imageleri siliyoruz.
  • Ve en son Dockerfilemızı hatırlıyoruz aşağıda ki gibiydi.

  • Şimdi ilk image buildini alıyoruz. Gördüğünüz gibi bazı layerları şimdi ilk defa cacheliyorum zaten başındada CACHED diye yazıyor bunlar. Ve zamanıda görüyorsunuz npm install yapmak 79 saniyemizi almış. Hiç istemeyeceğimiz bir şey.

  • Hiçbir değişiklik yapmadan gelin şimdi v0.0.01 adında yeni bir tag ile yeni bir build alalım. Aşağıda göreceğiniz üzere 1.5 saniye almış en uzun işlem çünkü npm installı tekrar yapmadı ve CACHED olmuş veriyi kullandı hiçbir değişiklik olmadığı için.

  • Daha iyi farkı görmek adına bir tane ünlem işareti ekleyip bir değişiklik yapalım react-app uygulamamız içindeki App.js içine ve sonra gelin v0.0.02 buildinin ne kadar süreceğini gözlemleyelim. Gördüğünüz gibi yine 76 saniye npm install yapıyor. Dosyamızdaki bir karakter değişikliğinden ötürü.

  • Yukarıdaki gibi durumlar için biz ne kadar değişiklik yaparsak yapalım, aşağıdaki gibi kendi yöntemlerimizi geliştirerek bu gibi uzun süren işlemleri her defasından cacheden kullanarak önlememiz gerekmektedir.

  • Bu durumda biz Dockerfile içinde package.jsonumuzu ilk önce /app dizinine kopyalıyorum ve daha sonra npm install işlemini yapıyorum. Ve bu yüzden docker diğer dosyaları daha almadığı için değişiklik olup olmadığını bilmeyecek ve 3. ve 4. satırdaki COPY ve RUN işlemlerini her defasında cachelediği veriden kullanacak. Tabi package.json içinde bir değişiklik olmazsa.

  • Ve şimdi tekrar tüm containerslarımızı ve imagelerimizi silip temizledikten sonra yeniden bir temiz bir build alıyoruz. Terminaldeki ilk buildi görüyorsunuz 92 saniye sürmüş. Daha sonra App.js içine gidip “t” adında ekstra bir karakter daha ekliyorum ve yeni bir image oluşturuyorum v0.0.01 tagi ile. Daha sonra göreceğiniz docker CACHED olmuş verileri kullanarak diğer imageyi sadece 1.2 saniyede oluşturuyor.

Port Binding (-p)

docker run -p ourOSPort:dockerPort imageId/imageName:tag

  • -p ile çalıştırdığımız containerın portunu kendi makinamızdaki port ile binding yani bağlama işlemlerini yapabiliriz.

docker run -p 8000:80 imageId/imageName:tag

  • Yukarıda -p ile containerımızın çalıştığı hosttaki 80 portunu alıyoruz ve bunu bizim OS deki 8000 portuna bağlıyoruz. Burada ki 80 aynı zamanda bizim Dockerfile daki EXPOSE portumuzdur.

Attach (-a) ve Detach(-d) Mods

  • Attach mod, imagemizi docker run ile container oluşturup çalıştırdığımızda terminalin çalıştırdığımız imagenin terminalinde durduğu moddur. docker run komutu default olarak attached modda çalışır.

docker run -p 8000:80 -d imageId

  • d ile docker run yaparsak containerımızı detach modda başlatırız ve bu şekilde aşağıdaki resimdeki gibi imagenin terminaline düşmeyiz ve halen kendi terminalimizde oluruz.
  • Default olarak -d eklemeden bir container çalıştırırsak containerımız, attached mod olarak çalışır.

docker attach containerId

  • Eger -d ile detach modda başlatsanız bile daha sornadan docker attach containerId ile çalışan containerınızı restart atmadan attach moda geçerek imagenizin terminaline bağlanabilirsiniz.

docker logs containerId

  • Belirtilen çalışan containerin terminalinin o ana kadar ki loglarını basar.

docker logs -f containerId

  • -f ekleyerek loğları terminal izler gibi canlı izleyebiliriz. -f follow anlamındadır.

docker exec

  • Çalışan docker containerında komut çalıştırmamızı sağlar. Mesela aşağıda c1 diye identifier ettiğimiz yani isimlendirdiğimiz containerda ls komutunu çalıştırarak imagenin WORKDIR indeki yani app/ klasöründe ki dosyaları görüyoruz.

  • Veya istersek aşağıda ki gibi -it ile interactive olarak canlı olarak, çalışan containerın terminaline bağlanıp kod yazabiliriz ve daha sonrada exit ile terminalden çıkabiliriz.

docker run vs docker exec

  • Run containerı başlatırken, exec çalışan bir containera baglanır.

docker run vs docker start

  • docker run yeni bir container oluşturarak containerı çalıştırır. Docker start ise sadece daha önce stop edilmiş bir containerı çalıştırır.

COPYING FILES BETWEEN HOST AND CONTAINER

  • Aşağıda önce containerlarimızı listeliyoruz.
  • Daha sonra çalışan birine interactive oluyoruz ve log.txt adında bir dosya oluşturuyoruz ve exit yaparak container terminalinden çıkıyoruz.

docker cp containerId:/path/fileName.txt ourPath

  • Daha sonra ana makinamızda yani işletim sistemimizdeki terminalde, docker cp yaparak container idmizi verdikten sonra : yaparak pathimizi dosya adıyla birlikte yazıyoruz ve o dosyayı bulup “.” ile bulunduğumuz dizine kopyalamasını söylüyoruz. Gördüğünüz gibi daha sonra ls ile container içinde tanımlanan dosyayı listeleyebiliyoruz.

  • Veya istersek ana makinamızda secret.txt adında bir dosya oluştururuz

  • ve bunu çalışan containera aşağıda ki gibi atabiliriz.

docker cp filename containerId:/path

  • Ve cp yaparak kopyalanacak dosyayı seçeriz daha sonra container id ve pathi aşağıda ki örnekte resimdeki gibi yazarız.
  • Daha sorna listelediğimizde gördüğünüz gibi dosyamızın oraya kopyalandığını görebiliriz.

IMPORTING and EXPORTING IMAGES

  • Bazen imagelerimizi ana makinamıza export etmek yani indirmek veya ana makinamızda indirilmiş imageleri dockera import etmek yani yüklemek isteyebiliriz.

SAVE

docker image save -o outputFileName imageId/imageName:tag

  • -o ile output alacağımız çıktı dosya ismini belirliyoruz ve daha sonra hangi taglı image olduğunu söylüyoruz.

  • Ve aldığımız output zipli dosyasının içi aşağıda ki gibi linux sisteminde bir docker image dosyası elde ediyoruz.

LOAD

docker image load -i react-app.tar

  • Load ornegini gosterecegimiz icin ilk localdeki imagemizi asagidaki gibi siliyoruz.

  • Sonra imagemizi load ile aşağıda ki gibi yüklüyoruz.
  • -i import demektir.