Docker

Docker

Docker

Docker Nedir ?

Docker en net tanımlamayla open source bir ‘container’ teknolojisidir. Docker, aynı işletim sistemi üzerinde, yüzlerce hatta binlerce birbirinden izole ve bağımsız containerlar sayesinde sanallaştırma sağlayan bir teknolojidir. Web uygulamalarımızın kolayca kurulumunu, testini, çalışmasını ve deploymentını sağlar. Bunun yanında sunucu maliyetlerini önemli ölçüde azaltır.

Dockerfile, Docker Image, Docker Container.Docker Registry,Docer CLI Nedir?

Dockerfile

“ Maddenin temel yapıtaşı nasıl atom ise Docker projelerinin temel yapıtaşı Dockerfile’dır. “

Dockerfile, uygulamanın ana root dizininde herhangi bir uzantısı olmayan ve ismi birebir ‘Dockerfile’ şeklinde olan bir dosyadan ibarettir. İçerisinde yayınlanacak olan uygulamanın nasıl bir ortamda çalışacağına dair talimatları barındırmaktadır. Örneğin; geliştirme yapılan herhangi bir Asp.NET Core uygulamasının, hangi işletim sistemi üzerinde kaçıncı versiyonla ayağa kaldırılacağını ve hangi dll dosyalarının yüklü olması gerektiği vs. gibi talimatlar belirtilebilmektedir.

Dockerfile sayesinde verilen talimatlar neticesinde sunucu yapılandırması gibi zahmetli bir işten kurtulanmakta ve böylece geliştiriciye olan bağımlılıkta olabildiğince izole edilmiş olmaktadır. Nihayetinde, işten ayrılan bir personelin ayağa kaldırdığı bir uygulamayı nasıl ve ne şekilde gerçekleştirdiğine dair bir telaşa kapılmaksızın Dockerfile dosyası sayesinde tek bir komut ile aynı proje tekrar aynı özelliklerle ayağa kaldırılabilmekte ve böylece projenin özgürlüğünü desteklemektedir.

Docker Image

Docker build edildikten sonra Dockerfile dosyasında belirtilen talimatlara göre read only özellik gösteren static yapıda image(imaj) dosyası oluşturulur.. Dockerfile içerisinde belirtilmiş her bir satıra karşılık Docker Image içerisinde bir layer oluşur. Dolayısıyla imageler bir katman(layer) topluluğudur. Örneğin; Dockerfile içerisinde 4 satırlık talimat varsa o halde 4 katmanlı bir Docker Image oluşturulacaktır.

Docker Image’lar da Dockerfile dosyası içerisinde belirtilen talimatlara göre işletim sistemi, enviroment ve publish data verileri bulunur. Bir nevi, amaca yönelik container’ların çalışması için önceden tasarlanmış tak çalıştır mantığında işlev gören kalıplardırda diyebiliriz. Docker Image’leri ister kendimiz yaratabilir istersekte belirli firmaların sunduğu hazır Docker kalıplarını kullanabiliriz.

Peki hazır Docker kalıplarını nereden elde edebiliriz?
Bunun için Docker Registry başlığını inceleyelim.

Docker Registry

İmajların kaydedilip dağıtılabildiği bir ortam olarak düşünebiliriz. Sol taraftaki görüntüdeki dolabı Registry gibi düşünürsek eğer her bir raftaki kutuyuda tek bir amaca hizmet eden imajlar olarak değerlendirebiliriz.

Görüldüğü üzere registry’e depolanan bir imaja çok hızlı bir şekilde erişebilir ve gerekirse üzerinde değişiklikler yapıp farklı bir versiyon olarak yeniden gönderebiliriz.

Hazır registry ortamını sağlayan firmalar hangileridir?
Uygulamanıza dair hazır imajlar barındıran mevcuttaki birkaç cloud registry firmasını aşağıda görebilirsiniz.

Peki neden imajları registry etmek isteriz?

  • Yapılan çalışma neticesinde elde edilen imajlarımızı cloud’da ki registry ortamına depolayarak güvence sağlayabilmek için,
  • İhtiyaca dönük sunucular arasındaki imaj transferini daha hızlı ve sağlıklı sağlayabilmek için,
  • Ayağa kaldırılacak uygulamadaki temel dosyaların, işletim sisteminin ve environment(ortam) yapılanmasının getireceği iş yükünden kaçınmak ve hazır imaj kullanarak bu tarz maliyetleri minimize etmek için imajları registry ediyor yahut registry’dan çekip kullanıyoruz…

Docker Container

Docker Image dosyasını Dockerfile içerisindeki talimatlara göre oluşturduktan sonra uygulamanın çalıştırılabilmesi için run edilmesi gerekmektedir. Run neticesinde bir container ayağa kaldırılır ve böylece ilgili uygulama ayağa kaldırılmış olacaktır.

“ Container, Docker Imagelerin çalışabilen instance’larıdır. ”

Bir Docker Image üzerinden istenildiği kadar Container ayağa kaldırılabilir. Burada Docker Image uygulama için bir fabrika görevi görmektedir. Ayrıca Containerlar; durdurulabilir, silinebilir, tekrardan oluşturulabilirler. (Read/Write)

Docker Image ve Container Örneklendirmesi


Yukarıdaki şemaya göz atarsak eğer Dockerfile dosyası içerisinde verilen talimatlar kadar Docker Image içerisinde katman oluşturulduğunu görmekteyiz. Bu imaj üzerinden ayağa kaldırılan tüm container instanceları, öncelikle imaj üzerine eklenen hem okunabilir hem yazılabilir katman üzerinden ayağa kaldırılmaktadırlar. Bu okunabilir/yazılabilir katmanın amacı uygulama içerisinde yapılan tüm işlemlerin gerçekleştirilmesi içindir. İlgili katmanın container’a bağlı olmasından dolayı container silindiğinde de yok olacağından dolayı haliyle yapılan tüm işlemler geri dönüşsüz kaybolmuş olacaktır.

Makale => https://www.gencayyildiz.com/blog/dockerfile-docker-image-docker-registry-ve-docker-container-kavramlari-nelerdir/

Docker CLI

Yandaki görüntüyü incelerseniz eğer Docker’ın birden fazla parçadan bir araya gelmiş bir bütünsel yapılanma olduğunu anlarsınız.

Bu parçalardan; server tarafındanki ana tool olan Docker Daemon ile client tarafından tool olan Docker CLI olmak üzere önem teşkil eden iki parçaya odaklanırsak eğer Docker Daemon esasında Docker Engine’in ta kendisidir ve bir arayüze sahip olmadığı için client tarafındaki Docker CLI aracılığıyla aradaki REST API yapıları kullanılarak istenilen talimatlar Docker Engine’e iletilir. 

Yani içeriğin girişinde vurguladığımız gibi Docker CLI, Docker ile haberleşme görevini üstlenen komut satırıdır.

Makale => https://www.gencayyildiz.com/blog/docker-cli-nedir/ 

 

.Net Console Uygulamasının Dockerize Edilmesi

  • Öncelikle console uygulamamızı oluşturuyoruz.

  • Dockerfile dosyamızı projemize dahil ediyoruz.

  • Otomatik gelen “Dockerfile” dosyasında hazır kodlar mevcut.Ama basit console uygulaması için biz kendimiz yazdık.

Not : Hazır image dosyasını (.net runtime image) Docker Hub’da bulabilirsin.Runtime projenin çalışabilmesini sağlayan araçları barındırırken sdk projenin geliştirilebilmesi için gereken koşullarıda sunar.Boyutu daha az ve performanslı olduğu için image dosyası olarak runtime kullanıyoruz.

Dockerfile Dosya Kodlarının Açıklaması

Not : Dockerfile dosyasındaki her değişiklikten sonra proje tekrar publish edilmelidir.

  • Daha sonra “ docker build -t <image name> . “  komutu ile image oluşturulur.(Image adı küçük harflerden oluşmalıdır.)(Sondaki noktayı unutma.)(Sondaki nokta dockerfile dosyasını nerede arayacağını gösteriyor.Bu yüzden powershell komut satırını Dockerfile dosyasının bulunduğu konumda açman gerekiyor.)

Not : “docker images“ komutu ile mevcut imageleri listeleyebilirsin.

  • Container oluşturmak için “docker create –name <container name> <kullanılacak image>”

Not : docker ps” komutu sadece çalışan containerları listeler.”docker ps -a” tüm containerları listeler.

Not : Bu işlemler anında bilgisayarda Docer Desktop ayakta olmaldıır.Oluşan tüm image ve containerlar buradan da görülebilir.(Docker Desktop da giriş yapmalısın.)

Not : “docker start <container name>” ve “docker stop <container name>” komutları ile containerlar başlatılıp durdurulabilir.

Not : Container ayaktayken (çalışıyorken) arka tarafta programı çalıştırır.Herhangi bir anda çıktıyı gözlemlemek için consoledan “docker attach <container name>” veya Docker Desktop’dan log kısmından izlenebilir.

 

Docker CLI Komutları

  • “ docker run  --name <container name> <seçilen image name> “

Bu komut hem conteiner oluşturur hem de oluşturulan containerı çalıştırır.Yani create ve start komutlarının birleşimidir.(Otomatik attach durumuna geçer.)

  • “ docker rm <container name> ”

İlgil containerın silinmesini sağlar.

  • “ docker rmi <image name> ”

İlgil imageın silinmesini sağlar.Ancak imageı silebilmen için öncelikle o imageı kullanan containerları silmen gerekiyor.

  • “ docker run --rm --name <container name> <seçilen image name> “

Run komutuyla tamamen aynı işi yapar.Tek fark --rm ekl ile oluşturulan dockerın durdurulduğu anda silinmesini sağlar.

  • “ docker build -t <image name>:<Tag Name> .”

Image’a tag eklemek için kullanılır.

Not : Image’e tag ekleme yöntemiyle aynı şekilde containera da tag eklenebilir.

  •  “ docker rmi image-id/name --force “
  • “ docker rm container-id/name --force “

Çalışan bir containerda görevli bir image’ı asla silemezsin.Silebilmen için containerı durdurman ve silmen gerekiyor.Ancak çalışmayan (durdurulmuş) bir containerda görevli imagı –force parametresi ile silebilirsin.

Ayrıca çalışan bir containerıda silmek için –force parametresi kullanılır.

  • “ docker pull mcr.microsoft.com/dotnet/sdk:6.0 “

Yayınlanmış image dosyaslarını çekmek için kullanılır.

  • “ docker push sadikcantuluk/consoleapp:tagname ”

Bu komut imagelerini Docker Hub’da oluşturduğun repositoryine göndermeni sağlar.

Not : docker tag : “ docker tag busybox sadikcantuluk/consoleapp:v1 ” Bu komut, busybox imajını sadikcantuluk/consoleapp:v1 adıyla etiketler.

Açıklama: busybox imajının kopyası sadikcantuluk/consoleapp:v1 olarak yeniden etiketlenir. Bu, imajın Docker Hub'a veya başka bir kayıt defterine yüklenmesini kolaylaştırır.

 

ASP .Net Core MVC Projesinin Dockerize Edilmesi

  • MVC projemizi oluşturduk.Daha sonra projemizi folder yapısına publish ettik.Ardından Dockerfile dosyamızı yazdık.Base image olarak bu sefer .Net Runtime image’i yerine ASP .NET Core Runtime image’ini kullandık.

  • Base image’i kullanarak yeni bir image oluşturduk.

“ docker build -t aspcoredockerapp .”

  • Daha sonra run komutu ile hem conteiner yapımızı oluşturup otomatik attach durumuna geçirdik.

“ docker run -p 5000:80 --name aspcoredocker_container aspcoredockerapp:v1 ”

Açıklama : Bu komut, Docker kullanarak bir konteyner oluşturur ve çalıştırır. Komutun her bir parçasının ne anlama geldiğini detaylı bir şekilde açıklayalım:

  1. docker run : Bu, Docker konteyneri oluşturmak ve çalıştırmak için kullanılan komuttur.
  2. -p 5000:80 : Bu, port yönlendirmesini belirtir. Sol taraftaki 5000 ana makinedeki (host) portu, sağ taraftaki 80 ise konteynerin içindeki portu ifade eder. Bu durumda, ana makinedeki 5000 numaralı port, konteynerdeki 80 numaralı porta yönlendirilir. Böylece, ana makinede 5000 numaralı port üzerinden yapılan istekler, konteynerdeki 80 numaralı porta iletilir.
  3. --name container1 : Bu, konteynere bir ad verir. Bu durumda, konteynerin adı container1 olur. Konteyner adı, onu diğer konteynerlerden ayırt etmek için kullanılır.
  4. denemeimage:v1 : Bu, kullanılacak Docker imajını belirtir. denemeimage imajın adıdır ve v1 ise imajın etiketidir. Etiketler, imajın belirli bir sürümünü belirtmek için kullanılır.

Komutun tamamı şu anlama gelir:

Docker, denemeimage:v1 imajını kullanarak container1 adında bir konteyner oluştur ve çalıştır. Bu konteynerdeki 80 numaralı portu, ana makinedeki 5000 numaralı porta yönlendir. Bu sayede, ana makinede 5000 numaralı port üzerinden yapılan istekler, konteynerin 80 numaralı portuna iletilir ve konteynerin içindeki uygulama bu istekleri yanıtlar.

Not : Container çalışır durumda ise içindeki projemiz belirttiğimiz portta ayağa kalkar.Ve container durdurulana kadar proje ayakta kalır.Ne zaman container durdurulur yayında olan proje durur.

.Net Core CLI

.NET Core CLI (Command Line Interface - Komut Satırı Arayüzü), .NET Core uygulamalarını geliştirmek, derlemek, test etmek, yayınlamak ve çalıştırmak için kullanılan bir araçtır. Bu komut satırı arayüzü, çeşitli platformlarda (Windows, macOS, Linux) çalışabilen çapraz platform bir araç setidir. .NET Core CLI, özellikle geliştiricilerin hızlı ve etkili bir şekilde .NET Core projelerini yönetmelerini sağlar.

.NET Core CLI'nin sağladığı başlıca komutlar ve işlevler şunlardır:

  • dotnet new: Yeni bir .NET projesi veya çözüm dosyası oluşturur. Örneğin:

 

      dotnet new console -o MyConsoleApp

      Bu komut, MyConsoleApp adlı bir klasörde yeni bir konsol uygulaması oluşturur.

  • dotnet build: .NET projesini derler. Bu komut, projeyi derler ve derleme hatalarını bildirir.
  • dotnet run: .NET projesini çalıştırır. Bu komut, projeyi derler ve ardından çalıştırır.
  • dotnet test: Test projelerini çalıştırır ve test sonuçlarını raporlar.
  • dotnet publish: Uygulamayı dağıtım için hazırlar. Bu komut, uygulamayı belirli bir hedef ortam için paketler.

dotnet publish -c Release -o ./publish

      Bu komut, projeyi Release modunda derler ve ./publish klasörüne paketler.

  • dotnet restore: Projede belirtilen bağımlılıkları geri yükler. Bu komut, proje dosyasında belirtilen NuGet paketlerini indirir ve yükler.
  • dotnet add package: Projeye bir NuGet paketi ekler.

dotnet add package Newtonsoft.Json

  • dotnet clean: Derleme çıktısını temizler. Bu komut, derleme sırasında oluşturulan dosyaları siler.
  • dotnet sln: Çözüm dosyası (.sln) ile ilgili işlemler yapar, projeleri ekler veya çıkarır.

 

dotnet sln add MyProject.csproj

.NET Core CLI, geliştiricilere otomasyon betikleri yazma, sürekli entegrasyon (CI) ve sürekli dağıtım (CD) süreçlerinde komutları kullanma olanağı da sağlar. Bu araç, hem basit komutlarla proje yönetimi hem de gelişmiş yapılandırma ve dağıtım işlemleri için oldukça esnek ve güçlü bir çözümdür.

Not : .Net Core SDK yüklü her yerde .NET Core CLI komut satırıda çalışır.

ASP .Net Projesinin SDK Image’i Üzerinden .NET Core CLI Komutlarıyla Publish Edilmesi ve Docker Üzerinden Ayağa Kaldırılması

Dockerfile Dosyası

# Bu image, .NET SDK'sının 6.0 sürümünü kullanır.

  • FROM mcr.microsoft.com/dotnet/sdk:6.0

# "app" adında bir çalışma klasörü oluşturur ve bu klasöre geçiş yapar.

  • WORKDIR /app

# 1. nokta, Dockerfile dosyasının bulunduğu dizini ifade eder (tüm klasör ve dosyaları).

# 2. nokta, image içerisinde WORKDIR ile oluşturulmuş çalışma klasörünü (app) ifade eder.

  • COPY . .

# .NET CLI yapısını kullanarak .NET komutlarını çalıştırmayı sağlar.

# restore komutu, projenin bağımlılıklarını ve kütüphanelerinin varlığını ve güncelliğini kontrol eder.

  • RUN dotnet restore

# ASP.NetWebAppDeckor.csproj projesini çalışma dizinimizde (/app) oluşturulacak  "out" klasörüne Release modda publish eder.

# Eğer "out" yerine "/out" şeklinde bir tanımlama yapılırsa, "out" dizini /app içerisinde oluşmaz.

  • RUN dotnet publish ASP.NetWebAppDeckor.csproj -c Release -o out

# Çalışma dizinini "out" olarak değiştirir.

  • WORKDIR out

# Çevresel değişkenleri tanımlar. Bu değişkenler, Docker konteyneri çalıştırıldığında uygulamanız tarafından erişilebilir olur.

# Bu ifade, ASP.NET Core uygulamasının http protokolü üzerinden herhangi bir IP adresinde (* ifadesi wildcard anlamındadır)  ve 4500 portunda dinleyeceğini belirtir.

Açıklama : Bu kod bir Dockerfile'da kullanılan bir çevresel değişkeni (environment variable) tanımlar. Kodun amacı, ASP.NET Core uygulamanızın hangi URL'ler üzerinden erişilebilir olacağını belirlemektir. Daha ayrıntılı açıklamak gerekirse:

  • ENV: Dockerfile içinde çevresel değişkenleri tanımlamak için kullanılır. Bu değişkenler, Docker konteyneri çalıştırıldığında uygulamanız tarafından erişilebilir olur.
  • ASPNETCORE_URLS="http://*:4500": Bu ifade, ASP.NET Core uygulamasının http protokolü üzerinden herhangi bir IP adresinde (* ifadesi wildcard anlamındadır) ve 4500 portunda dinleyeceğini belirtir.

Bu kodun işlevi ve kullanım amacı şu şekildedir:

  1. Port Ayarlama: Uygulamanızın hangi port üzerinden erişileceğini belirler. Bu örnekte, 4500 portu kullanılmıştır.
  2. IP Adresi Ayarlama: Uygulamanızın hangi IP adreslerinde dinleyeceğini belirler. * kullanıldığında, tüm IP adreslerinde dinleme yapılır. Bu, konteynerin içinde çalışan uygulamanın dış dünyadan erişilebilir olmasını sağlar.
  3. Konteynerde Çalıştırma: Docker konteyneri içinde çalışacak olan ASP.NET Core uygulamasının hangi URL'ler üzerinde çalışacağını belirleyerek, uygulamanın doğru şekilde yönlendirilmesini sağlar.

Özetle, bu kod, Docker konteyneri içinde çalışan ASP.NET Core uygulamanızın belirli bir port ve IP adresi üzerinden erişilebilir olmasını sağlar. Bu, uygulamanızın doğru şekilde yönlendirilmesi ve dış dünyadan erişilebilir olması için önemlidir. 

# Uygulamanın başlatılacağı komutu tanımlar. Bu komut, Docker konteyneri çalıştırıldığında ASP.NetWebAppDeckor.dll dosyasını çalıştırır.

  • ENTRYPOINT ["dotnet", "ASP.NetWebAppDeckor.dll"]

 

CMD Üzerinden İmage ve Container İşlemleri

“ docker build -t aspcoredockerapp:v2 . “

“ docker run -p 5000:4500 --name aspcoredockerapp_container3 aspcoredockerapp:v2 “

  • http://localhost:5000/ ayakta.

 

Docker Multi-Stage Build

Bu Dockerfile, bir ASP.NET Core uygulamasının multi-stage build yapısını kullanarak oluşturulmasını ve çalıştırılmasını sağlar. Multi-stage build, tek bir Dockerfile içinde birden fazla bağımsız yapı (birden fazla image kullanılarak) aşaması tanımlayarak daha küçük ve daha verimli imageler oluşturmayı mümkün kılar. Bu yapıyı ve yukarıdaki kodu adım adım açıklayalım:

  • FROM mcr.microsoft.com/dotnet/sdk:6.0 as build: Bu, .NET SDK içeren bir taban imajını kullanarak build adı verilen bir yapı aşaması başlatır.
  • WORKDIR /app: Çalışma dizinini /app olarak ayarlar.
  • COPY *.csproj .: Proje dosyalarını konteynırın çalışma dizinine kopyalar.
  • RUN dotnet restore: Proje bağımlılıklarını indirir ve geri yükler.
  • COPY . .: Tüm dosyaları çalışma dizinine kopyalar.
  • RUN dotnet restore: Bu adım gereksiz olabilir, çünkü bağımlılıklar zaten geri yüklendi. Ancak, bu ikinci dotnet restore aynı işlemi tekrar yapar.
  • RUN dotnet publish ASP.NetWebAppDeckor.csproj -c Release -o out: Projeyi "Release" konfigürasyonunda derler ve /app/out dizinine yayınlar.
  • FROM mcr.microsoft.com/dotnet/aspnet:6.0: Bu, .NET Runtime içeren bir taban imajını kullanarak çalıştırma aşamasını başlatır.
  • WORKDIR /app: Çalışma dizinini /app olarak ayarlar.
  • COPY --from=build /app/out .: İlk yapı aşamasından (build aşamasından) derlenen ve yayınlanan dosyaları çalışma dizinine kopyalar.
  • WORKDIR out: Çalışma dizinini out olarak ayarlar. Bu, yukarıdaki COPY komutuyla taşınan dosyaların bulunduğu yerdir.
  • ENV ASPNETCORE_URLS="http://*:4500": Uygulamanın hangi URL ve port üzerinden çalışacağını belirtir.
  • ENTRYPOINT ["dotnet","ASP.NetWebAppDeckor.dll"]: Konteynır başladığında çalıştırılacak komutu belirler. Bu, uygulamanın başlatılması için dotnet ASP.NetWebAppDeckor.dll komutunu çalıştırır.

Bu Dockerfile, iki aşamada bir ASP.NET Core uygulamasını derler ve çalıştırır:

  1. Build Aşaması: Uygulamayı derler ve yayınlar.
  2. Çalıştırma Aşaması: Yayınlanan uygulamayı daha küçük bir runtime imajında çalıştırır.

Bu yaklaşım, daha küçük ve daha verimli Docker imajları oluşturmanıza yardımcı olur çünkü sadece çalıştırma için gerekli olan dosyalar son imaja dahil edilir.

Best Practice

  •  
    • İki kod arasındaki fark

Dockerfile'da .csproj dosyasını ve diğer bağımlılık dosyalarını önce kopyalayıp, ardından dotnet restore komutunu çalıştırmak, Docker cache mekanizmasından yararlanarak daha hızlı ve daha verimli build süreçleri sağlar.

  • COPY *.csproj .: Bu komut, sadece .csproj dosyasını konteynırın çalışma dizinine kopyalar.

1.) Cache Kullanımı ve Daha Hızlı Build Süreçleri: Docker, her komutun çıktısını cache'ler. Eğer .csproj dosyası veya bağımlılık dosyaları değişmezse, dotnet restore komutunun çıktısı cache'den alınır ve yeniden indirilmez. Bu da build süresini önemli ölçüde kısaltır.

Bu yapı, sadece .csproj dosyaları değiştiğinde dotnet restore komutunu çalıştırır. Diğer dosyalar değişse bile bağımlılıkların yeniden indirilmesine gerek kalmaz.

2.) Gereksiz Bağımlılıkların İndirilmesini Önleme: Tüm dosyaları (örneğin, kaynak kodu, statik dosyalar, vb.) kopyalayıp sonra dotnet restore çalıştırmak, gereksiz yere bağımlılıkların indirilmesine neden olabilir. Bu, build sürecini uzatır ve gereksiz ağ trafiğine yol açar.

Bu yaklaşım, her değişiklikte bağımlılıkların yeniden indirilmesine yol açabilir, bu da build süresini uzatır.

3.) Daha Verimli Kaynak Kullanımı: Daha az indirme ve daha az yeniden yapılandırma ile kaynak kullanımı optimize edilir. Bu, hem yerel geliştirme ortamlarında hem de CI/CD süreçlerinde daha verimli build süreçleri sağlar.

Kısaca; COPY *.csproj . ve RUN dotnet restore komutlarını tüm dosyaları kopyalamadan önce kullanmak, Docker build süreçlerinde daha hızlı, verimli ve optimize bir yapı sağlar. Bu yaklaşım, Docker cache mekanizmasından tam anlamıyla yararlanarak bağımlılıkların gereksiz yere yeniden indirilmesini önler ve build sürelerini önemli ölçüde kısaltır. Bu nedenle, bu yapı best practice olarak kabul edilir.

Uygulama

.dockerignore

.dockerignore dosyası, Docker imajları oluşturulurken belirli dosya ve dizinlerin göz ardı edilmesini sağlamak için kullanılan bir dosyadır. Bu dosya, Docker imajlarının daha küçük ve daha verimli olmasına yardımcı olur, çünkü gereksiz dosyalar konteynıra dahil edilmez. .dockerignore dosyası, .gitignore dosyasına benzer şekilde çalışır ve hangi dosya veya dizinlerin hariç tutulacağını belirtmek için benzer bir sözdizimi kullanır.

Örneğin, bir .dockerignore dosyası aşağıdaki gibi görünebilir:

 

Docker’da Üretilen Verilerin Kalıcılığını Sağlama

Amacımız fiziksel dosyaların kalıcılığını sorgulamak. Docker’da çalıştırılan bir container içerisinde ayağa kaldırılmış uygulamamızın ürettiği fiziksel dosyaların kalıcılığının containerın çalışması sona erdiğinde yahut container silindiğinde ne olduğunu konuşacağız.

Hatırlarsanız eğer image üzerinden bir container ayağa kaldırıldığı zaman image üzerindeki katmanların üstüne bir okunabilir ve yazılabilir katman eklenmekteydi. İşte bu katman container üzerinde çalışan uygulamanın yayın esnasında ürettiği verileri içerisinde tutmakta lakin container kapatıldığında silindiğinden dolayı tüm kayıtlar geri dönüşsüz kaybolmaktadır.

Docker belli başlı yöntemlerle içerisinde üretilen dataları kalıcı kılmakta ve böylece test süreçlerindeki verisel açıdan yaşanan karmaşıklığı önleyerek sürecin eşzamanlı bir şekilde olmasını sağlamakla birlikte bir yandan da veri kayıplarını engellemektedir.

Docker tarafından üretilen dataların kalıcılığının sağlanması için aşağıdaki üç farklı yöntem geliştirilmiştir.

  • Bind Mount
    Container tarafından üretilen dataların ana makinadaki işletim sistemi üzerinde oluşturulan bir alanda depolanmasıdır. Bir image’den oluşturulan tüm containerlar aynı alanda depolama yapacağı için bir containerın kaydettiği dataya diğer containerlarda erişebilecek ve müdahalede bulunabilecektir. Böylece her bir containerın bağımsız bir data üretmesi engellenmiş ve datanın koyulduğu yer merkezileştirilmiş olacaktır.

Bind Mount, ana makine üzerinde depolama yaptığı için yönetimde Docker CLI komutları kullanılamamaktadır. İşletim sistemi üzerinden manuel bir yönetim gerekmektedir.

  • Volume
    Container tarafından üretilen dataların işletim sistemi üzerinde değil Docker’ın kendi içerisindeki bir alanda kalıcı olarak tutulmasıdır. Volumler Docker içerisinde olmasından dolayı CLI ile yönetilirler. Docker seviyesinde olduklarından dolayı backup alınmaları, restore edilmeleri ve hatta migrate edilmeleri oldukça kolaydır. Bind Mount’a nazaran cloud’da tutulabilirler ve böylece Docker’ın bulunduğu sunucunun çökebilmesi yahut fiziksel bir zarar görebilmesi ihtimaline karşı önlem alabilirler. Ayrıca hem Windows hem de Linux işletim sistemlerinde çalışabilmektedirler.
  • TMPFS Mount
    Container tarafında üretilen dataların memory’e geçici olarak kaydedilmesidir. Genellikle ana makinada yahut containerda geçici olarak saklanacak veriler için tercih edilmektedir.

Makale => https://www.gencayyildiz.com/blog/dockerda-uretilen-verilerin-kaliciligini-saglama/

 

Asp .Net Core MVC SaveImage Projesi ile Docker Volume

  • Başlangıçta oluşturulan her container publish içindeki resimlerle ayağa kalkar.

  • Ancak tüm containerlar birbirinden bağımsızdır.Bundan sonra her hangi bir containerda meydana gelen değişiklik sadece o containerı ilgilendirir.
  • 5000 ve 5001 portlarında çalışan containerlardaki resimler silindi ve farklı resimler yüklendi.Herhangi bir containerdaki değişiklik diğer bir containera yansımadı.

 

 

Bind-Mount Volume Kullanımı

  • Öncelikle masaüstünde yeni bir “imagesnew” adında klasör oluşturduk.
  • Daha sonra containerı aşağıdaki koda göre oluşturarak bind-mount tanımı yaptık.

“ docker run -d -p 5000:4500 --name mycon1 --mount type=bind,source="C:\Users\sadik\OneDrive\Masaüstü\imagesnew",target="/app/wwwroot/images" 3de “

Açıklama:

  1. docker run: Bu komut, yeni bir Docker container başlatmak için kullanılır.
  2. -d: Container'ı arka planda (detached mode) çalıştırır.
  3. -p 5000:4500: Bu bayrak, container'ın içindeki 4500 numaralı portu host makinenizin 5000 numaralı portuna yönlendirir. Bu, host makinenizin 5000 portuna gelen isteklerin container'ın 4500 portuna yönlendirilmesini sağlar.
  4. --name mycon1: Bu, container'a mycon1 adını verir. Bu isim, container'ı kolayca yönetmek ve referans almak için kullanılır.
  5. –moun type=bind,source="C:\Users\sadik\OneDrive\Masaüstü\imagesnew",target="/app/wwwroot/images": Bu bayrak, bind mount kullanarak host makinenizdeki bir dizini container içindeki bir dizine bağlar. Burada:
    • type=bind: Bind mount kullanıldığını belirtir.
    • source="C:\Users\sadik\OneDrive\Masaüstü\imagesnew": Host makinenizdeki bağlanacak olan dizinin yolu.
    • target="/app/wwwroot/images": Container içindeki bağlanacak olan dizinin yolu. Bu dizin, host makinenizdeki source dizini ile eşleşir ve container içinde bu yoldaki dosyalara erişim sağlar.
  6. 3de: Bu, başlatılacak olan Docker imajının ID'si veya adıdır.

“target” Parametresi:

target parametresi, bind mount kullanıldığında container içindeki bağlanacak olan dizini belirtir. Bu, host makinenizdeki belirli bir dizini container içinde belirli bir dizine bağlamanızı sağlar. Bu durumda:

  • source="C:\Users\sadik\OneDrive\Masaüstü\imagesnew": Bu, host makinenizdeki dizindir.
  • target="/app/wwwroot/images": Bu, container içindeki dizindir.

Bu yapılandırma ile host makinenizdeki C:\Users\sadik\OneDrive\Masaüstü\imagesnew dizinindeki dosyalar, container içindeki /app/wwwroot/images dizininde kullanılabilir hale gelir. Bu, container'ın, host makinenizdeki dosyalara doğrudan erişmesini sağlar. Özellikle dosya yükleme veya paylaşma senaryolarında kullanışlıdır.

“ 5001 portu “

“ C:\Users\sadik\OneDrive\Masaüstü\imagesnew “

Volume Kullanımı

  • Öncelikle bir images adında bir docker volume üretiyoruz.

“ docker volume create images “

  • Sonra bu volümü kullanarak containerlarımızı oluşturuyoruz.

“ docker run -d -p 5000:4500 --name mycon1 --volume images:/app/wwwroot/images 3de “

“ docker run -d -p 5001:4500 --name mycon2 --volume images:/app/wwwroot/images 3de “

Makale => https://www.gencayyildiz.com/blog/docker-volume-ile-verilerin-kaliciligini-saglama/

ASP.NET Environment Kavramı

ASP.NET Core uygulamalarında, "environment" kavramı, uygulamanın hangi ortamda çalıştığını belirlemek için kullanılır. Bu kavram, uygulamanın belirli bir ortamda çalışırken nasıl davranması gerektiğini kontrol etmeye yardımcı olur. ASP.NET Core, Development, Staging, ve Production gibi yaygın olarak kullanılan ortamları destekler, ancak uygulama ihtiyaçlarına göre farklı ortamlar da tanımlanabilir.

  • Development Ortamı: Geliştiricilerin çalıştığı, sık sık kod değiştirdiği, hata ayıklama ve testlerin yapıldığı ortam.
  • Production Ortamı: Nihai kullanıcıların uygulamaya eriştiği, yüksek performans ve güvenlik gerektiren, kararlı ve optimize edilmiş ortam.

Makale => https://www.gencayyildiz.com/blog/asp-net-core-environment-nedir-konfigurasyonu-nasil-yapilir/

Container İçin Environment Belirleme

  • Asp .Net projesinde default olarak Development Environment’ı gelirken oluşturulan Docker Containerlarda ise Production Environment’ı gelir.Bu containerlardaki Environment’ı değiştirerek bir container oluşturmak için aşağıdaki komut kullanılır.

“ docker run --env ASPNETCORE_ENVIRONMENT=Development -d -p 5001:4500 --name mycon2 022 ”

Makale => https://www.gencayyildiz.com/blog/docker-container-icin-environment-belirleme/

Çok Katmanlı Asp.Net Core(mvc) Projesini Dockerize Yapmak

Gençay Yıldız Makaleden ;

Docker’da çok katmanlı mimari ile geliştirilmiş bir Asp.NET Core uygulamasının nasıl Dockerize edildiğini merak ediyorsanız eğer aşağıdaki örnek talimatları inceleyebilirsiniz.

N-Tier Architecture ile geliştirilen uygulamanın Dockerize edilebilmesi için Dockerfile dosyasının solution dizininde oluşturulmasına özen gösteriniz. Ardından aşağıdaki talimatlara benzer nitelikte içeriğini oluşturabilirsiniz;

Makale => https://www.gencayyildiz.com/blog/asp-net-core-uygulamasini-dockerize-etmek/ 

Başka Bir Örnek;

  1. FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as build
    • Bu satır, yapı aşaması için temel görüntüyü belirtir. Microsoft'un kapsayıcı kayıt defterinden .NET Core SDK 3.1 görüntüsünü kullanır.
  2. WORKDIR /app
    • Kapsayıcı içindeki çalışma dizinini /app olarak ayarlar.
  3. COPY ./UdemyNLayerProject.Core/*.csproj ./UdemyNLayerProject.Core/
    • UdemyNLayerProject.Core dizinindeki .csproj dosyasını, kapsayıcı içindeki ilgili dizine kopyalar.
  4. COPY ./UdemyNLayerProject.Data/*.csproj ./UdemyNLayerProject.Data/
    • UdemyNLayerProject.Data dizinindeki .csproj dosyasını, kapsayıcı içindeki ilgili dizine kopyalar.
  5. COPY ./UdemyNLayerProject.Service/*.csproj ./UdemyNLayerProject.Service/
    • UdemyNLayerProject.Service dizinindeki .csproj dosyasını, kapsayıcı içindeki ilgili dizine kopyalar.
  6. COPY ./UdemyNLayerProject.Web/*.csproj ./UdemyNLayerProject.Web/
    • UdemyNLayerProject.Web dizinindeki .csproj dosyasını, kapsayıcı içindeki ilgili dizine kopyalar.
  7. *COPY .sln .
    • Çözüm dosyasını (.sln) ana makineden kapsayıcı içindeki mevcut çalışma dizinine kopyalar.
  8. RUN dotnet Restore
    • Projenin bağımlılıklarını ve araçlarını geri yükler.
  9. COPY . .
    • Ana makineden kalan dosyaları, kapsayıcı içindeki çalışma dizinine kopyalar.
  10. RUN dotnet publish ./UdemyNLayerProject.Web/*.csproj -o /publish/
    • Web projesini derler ve çıktıyı /publish dizinine yerleştirir.
  11. FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
    • Çalışma zamanı aşaması için temel görüntüyü belirtir ve Microsoft'un kapsayıcı kayıt defterinden .NET Core ASP.NET 3.1 görüntüsünü kullanır.
  12. WORKDIR /app
    • Kapsayıcı içindeki çalışma dizinini /app olarak ayarlar.
  13. COPY --from=build /publish .
    • Yapı aşamasından yayınlanan çıktıyı, çalışma zamanı aşamasındaki çalışma dizinine kopyalar.
  14. ENV ASPNETCORE_URLS="http://*:5000"
    • ASPNETCORE_URLS ortam değişkenini http://*:5000 olarak ayarlar, bu da uygulamanın 5000 numaralı portta dinlemesini sağlar.
  15. ENTRYPOINT ["dotnet", "UdemyNLayerProject.Web.dll"]
    • Kapsayıcının giriş noktasını tanımlar; bu, UdemyNLayerProject.Web.dll uygulamasını çalıştırmak için dotnet komutunu kullanır.

Özetle, bu Dockerfile, çok katmanlı bir ASP.NET Core (MVC) projesini Docker kapsayıcısında yapılandırmak ve çalıştırmak için kullanılır. Çok aşamalı yapı kullanılarak önce uygulama derlenir ve yayınlanır, ardından yayınlanan çıktı çalışma zamanı görüntüsüne kopyalanarak çalıştırılır.

 

Unit Test İçeren Asp.Net Core(mvc) Projesini Dockerize Yapmak

 

Docker Compose

  • Docker compose dosyasının oluşturulması.

  • Docker Compose dosyamızı solution içine yani projeleri kapsayacak şekilde en üst dizinde oluşturuyoruz.Solution’a sağ tıkladığımızda Compose dosyası seçeneği gelmiyor ancak herhangi bir projeye sağ tıklarsak bu seçenek geliyor ve üst dizinde yerini alıyor.

Not: Prjeler içinde oluşturulan default DockerFile dosyaları Docker Compose işlemi için oluşturulmuştur. Yani mesela Copy . dediğin zaman buradaki nokta docker-compose.yml dosyasının bulunduğu dizini ifade eder.

Docker Compose Komutları

docker compose build

Image oluşturmak için kulanılır. (Build veya Rebuild) yaparken Start Projenin Docker da olmamasına dikkat et.(Herhangi bir başka proje olur.)Çünkü Docker konumunda olursa build işlemi anında otomatik docker compose build işlemide yapar.Yine komutlarını herhangi bir projenin dizininde çalıştırabilirsin.

 docker compose create ve docker compose

Create komutuyla oluşturulan imaglerden birer tane stop durumunda container oluşturulur.Start komutuylada bu containerları başlatabilirsin.

docker compose stop ve docker compose rm

Stop komutu çalışan containerı durdurur rm komutu ise durmuş containerı siler.

docker compose up ve docker compose down

Up (build.recreate,start) komutu ile imagler oluşturulur bu imagelerden containerlar oluşturulur ve bu containerlar çalıştırılır.Tek komut ile.

Not: Up komutu eğer mevcut bir image varsa onu kullanır yeniden build etmez.Yani sen projende değişiklik yaptıysan önce docker compose build ile değişikliklerini kaydetmen lazım ya da imagları silip direkt up komutu üzerinden yeni bir imaj üretilmesini sağlayabilirsin.

Down (stop,remove) komutu ile çalışan tüm containerlar durdurulur ve silinir. Tek komut ile.

Attach olmadan ayağa kaldırmak için;

docker compose pause/unpause

  • docker stop: Konteyneri durdurduğunda, bellekte kullanılan kaynaklar tamamen serbest bırakılır. Konteyner kapatıldığı için, ona tahsis edilen tüm bellek geri alınır.
  • docker pause: Konteyneri duraklattığında, bellekteki veriler korunur ve serbest bırakılmaz. Konteyner duraklatılır, ancak bellekteki veriler yerinde kalır, dolayısıyla bellek kullanımı devam eder.

Yani bir containerı stop komutu ile durdurduğumuzda verilerimizde kaybolur. Ama pause ile durdurup tekrar unpause ettiğimizde verilerimize yeniden erişebiliriz.

docker compose up --scale micServis1=3 --scale micServis2=2

 Bu komut istenilen imagelerden istenildiği kadar container ayağa kaldırmak için kullanılır.Bu komutu kullanırken 2 şeye dikkat edilmelidir;

  1. docker-compose.yml de base dosyada Container isimleri kaldırılmalıdır. Çünkü ayağa kalkan container sayısına göre kendisi containerları isimlendirecektir.

  1. docker-compose.override.yml dosyasında port kısmında bizim bilgisayarımızda ayağa kalkıcak portlar ya tanımlanmalıdır bu portları belirlemek dockera bırakılmalıdır ya da portlar tanımlanacaksa aralık vererek tanım yapılmalıdır.Ancak aralıklı tanımlamada bazen çakışmalar oluyor ve containerlar ayağa kalkmıyor en iyisi port belirlemeyi dockera bırakmaktır.

VEYA

 

Oluşturulan Imagein Docker Hub’a Gönderilmesi

  • Öncelikle Docker Hub da oturum açıyoruz ve orada repository oluşturuyoruz.

  • Daha sonra terminal üzerinden önce emin olmak için logout sonra login komutunu kullanarak Docker Hub hesabımızı bağlıyoruz.

  • Göndereceğimiz image dosyasının ismini sadikcantuluk/[ProjeName]:tagname şeklinde değiştiriyoruz. (docker-compose.yml)

Not : Version environmentını insiyatif olarak .env dosyası üzerinden tanımlayarak kullandık.

  • Docker-compose.override.yml de herhangi bir değişiklik yapmadık.

  • Daha sonra docker compose build ile image yapımızı oluşturuyoruz.Ardından docker compose push komutu ile image yapımızı Docker Hub repositorymize gönderiyoruz.

 

 

Docker Compose SQL Server Ayağa Kaldırma

  • Öncelikle Docker Hub dan Sql Server image dosyasına gidiyoruz.Burada ki talimatlara göre gerekli değişiklikleri kodumuza ilave ediyoruz.

 

  • Docker Compose docker-compose.yml dosyamızda sql server servisini oluşturduktan sonra buradaki environmentları aynı isimle docker-compose.override.yml dosyasına eklememiz gerekiyor.

docker-compose.yml

 docker-compose.override.yml

  • Son olarak da verilerimizi korumak için bir volüme ekliyoruz.

docker-compose.yml

Not : volumes tanımını service ile aynı hiyerarşide tanımlıyoruz.

  • Daha sonra bu oluşturduğumuz volümü sqlserver ile bağdaştırıyoruz

docker-compose.override.yml

Not : “/var/opt/mssql”  bu tanım volümün hangi değerleri tutacağını gösteriyor.SQL Server dataları bu adreste tuttuğu için bizde bu yolu vererek bu verilerin image içinde depolanmasını ve bu imageden oluşturulacak containerlarda veri kaybı olmamasını sağlıyoruz.

  • Son olarak docker compose up sqlserver komutuyla containerı oluşturup ayağa kaldırıyoruz.

SQL Server Managment Üzerinden Sql Server Containera Bağlanma

Not : Server name kısmında localhostdan sonra virgül kullanılır sonra port yazılır. (localhost,1433)

Yorumlar

Yorum yapabilmek için lütfen giriş yapın.

Henüz yorum yapılmamış. İlk yorumu siz yapın!