İçeriğe geç

Docker Üzerinde Çalışan Dotnet Uygulamasının Build Süreçlerini Hızlandırmak

Dockerfile’ları düzenleyerek daha hızlı build işlemi nasıl gerçekleştirebiliriz?

  • Önsöz
  • Problemin Tanımı
  • Docker Build Anında Çalışan Cache Nedir ve Nasıl Yararlanacağız?
  • Dotnet Uygulamasına Ait Dockerfile’ları Nasıl Yapılandırılabiliriz?
  • Dotnet Uygulamasına Ait Örnek Dockerfile
  • Use Case : Uygulamanın Docker İçerisinde Harici Başka Bir Uygulamaya veya Dış Kaynağa İhtiyaç Duyması

Önsöz

Bu yazı dotnet docker performansı özelinde detaylar içermektedir fakat dotnet haricinde uygulama geliştirenlerde faydalanabilir. Derinlemesine incelenmesi gereken kaynakların bağlantılarını ve anahtar kelimelerini yazı içerisinde bulabilirsiniz. Aklınıza takılan sorular, eklemek veya düzeltmek istediğiniz yerler olursa bana paylaştığım iletişim kanallarından ulaşabilirsiniz.


Yazıya devam etmeden önce Dockerfile içerisinde kullanılan Instruction’ları (komut) hatırlamak ve üzerinden geçmek için orijinal kaynağına bakabilir veya Gökhan Şengün’ün yazısından Türkçe olarak okuyabilirsiniz.

Docker Build Anında Çalışan Cache Nedir ve Nasıl Yaralanacağız?

Kısaca docker build cache, build işlemini esnasında imaj içerisinde değişikliğe sebep olacak ADD, RUN vb. komutlardan sonra kontrollerini gerçekleştirip farklılıkları hesaplaması yapılan işlemden sonra oluşan aşamayı daha sonra kullanmak üzere saklamasıdır.

Docker build cache doğru kullanıldığı zaman bize hız ve disk alanı kazandırır

Problemimizin çözümü için bizler bu cache yapısını mümkün olan en iyi şekilde kullanmaya çalışacağız.

Dotnet Uygulamasına Ait Dockerfile’ları Nasıl Yapılandırılabiliriz?

  • Dockerfile’ı karışımıza alıp build ederken sürekli değişmeyecek parçaları ayırmak.
  • Mümkün olduğun kadar tüm değişmez stepler ile bir base imaj oluşturmak ve bu base imajları kullanmak.
  • Değişken olan parçalar için değişme ihtimalinin sıklığına göre artan şekilde sıralamak.
docker katmanları

Bir örnek vermek gerekir ise Dockerfile’ınız içerisinde sürekli olarak wget/apt-get ile çekip context’e eklediğini bir dosya veya kütüphane olduğunu düşünün.

Aşağıda SUPERVISORD’yi eklediğimiz base imajın içerisindeki layer oluşturacak bir komutun ekran görüntüsünü paylaşıyorum. Her imaj içerisinde ihtiyacımız olan bu harici uygulamayı içeren bir base imaj yarattık ve bunu kullanmaya başladık bu sayede sık değişmeyen bir step’i daha yukarı taşımış olduk.

Konuya hızlı bir giriş yapmak için başta Multi-stage buildler ile alakalı Ahmet Alp Balkan’ın youtube videosunu ve diğer docker videolarını tavsiye ederim.

Dotnet Uygulamasına Ait Dockerfile

Lütfen aşağıdaki Dockerfile’a bir göz atınız.

COPY . .

olan kısma kadar *.sln dosyamızı, var ise .nugetconfig’lerimizi ve *.csproj dosyalarımı context’e ekliyoruz ve ardından dotnet restore komutumuzu çalıştırıyoruz.

Solution içerisinde aynı stepleri gerçekleştirecek bir çok Dockerfile’ınızı compose içerisinde build olması için tetikleyeceksiniz.

Bir defa değişmeyen kısımları cache’leyen docker build sonrakiler için çok daha hızlı çalışacak.

FROM mcr.microsoft.com/dotnet/core/sdk:3.1.300-buster AS build
WORKDIR /src

# Docker build cache'inden yararlanarak hızlandırıyoruz.
COPY "eShopOnContainers-ServicesAndWebApps.sln" "eShopOnContainers-ServicesAndWebApps.sln"

COPY "Services/Basket/Basket.API/Basket.API.csproj" "Services/Basket/Basket.API/Basket.API.csproj"
COPY "Services/Catalog/Catalog.API/Catalog.API.csproj" "Services/Catalog/Catalog.API/Catalog.API.csproj"
COPY "Services/Identity/Identity.API/Identity.API.csproj" "Services/Identity/Identity.API/Identity.API.csproj"
COPY "Services/Location/Locations.API/Locations.API.csproj" "Services/Location/Locations.API/Locations.API.csproj"
COPY "Services/Marketing/Marketing.API/Marketing.API.csproj" "Services/Marketing/Marketing.API/Marketing.API.csproj"
COPY "Services/Ordering/Ordering.API/Ordering.API.csproj" "Services/Ordering/Ordering.API/Ordering.API.csproj"
COPY "Services/Payment/Payment.API/Payment.API.csproj" "Services/Payment/Payment.API/Payment.API.csproj"
COPY "Web/WebMVC/WebMVC.csproj" "Web/WebMVC/WebMVC.csproj"

# dotnet restore işlemimizi bir aşama olarak çalıştırıyoruz.
RUN dotnet restore "eShopOnContainers-ServicesAndWebApps.sln"

COPY . .

# dotnet build işlemini çalıştırıyoruz --no-restore komutu ile tekrar restore etmesinin önüne geçiyoruz
RUN dotnet build -c Release --no-restore

WORKDIR /src/Web/WebMVC

# uygulamamızı publish ediyoruz.
RUN dotnet publish -c Release -o /app --no-restore --no-build 

FROM nesbilgi/debian:aspnet-3.1.4 AS runtime
WORKDIR /app
COPY --from=build /app .

ENTRYPOINT ["dotnet", "WebMVC.dll"]
docker-compose build

komutu birden fazla kez çalıştırdığımızda bazı steplerin cache kullandığını aşağıdaki ekran görüntüsünde görebilirisiniz.

Daha önce cache’e alınan bu stepler benzer bir katman oluştuğunda cache üzerinden çağırılarak kullanılır. Bu cache’ler build esnasında imajlar arasında ortak olarak kullanılırlar.

Örneğin;

eShopOnContainers-ServicesAndWebApps.sln

dosyasını kopyalandığı komut daha önce çalıştırıldığı için Using cache ile tekrar aynı komutun çalışmasına gerek kalmadan işletilmektedir.

Use Case : Uygulamanın Docker İçerisinde Harici Başka Bir Uygulamaya veya Dış Kaynağa İhtiyaç Duyması

Örneğin,
Dockerfile içerisinde ihtiyaçtan dolayı harici bir projeyi context’inize dahil etmeniz gerekirse belirli bir tag ile bu işlemi gerçekleştirmeniz sürekli aynı dosyaları almanızı sağlayacaktır.

RUN git clone — branch <tag> <repository>

Yine benzer bir şekilde apt-get ve türevi bir paket yöneticisi ile bir paket kurar iken versiyon belirtmeniz daha doğru olacaktır.

apt-get install <package name>=<version>

Bu tarz ihtiyaçlarınızı toparlayarak bir base imaj yaratmak ve kendi privite/public registry’leriniz üzerinde yayınlayıp oradan kullanmak daha faydalı olacaktır.


Örneğin sürekli ihtiyacımız olduğu için aşağıdaki gibi bir base imaj oluşturup etiketleyerek registry üzerine gönderdiğimiz bir imajımız bulunmaktadır.

FROM mcr.microsoft.com/dotnet/core/runtime:3.1.4-buster-slim

# # # # # # # # # # # # # # # # # # # # # # #
# INSTALL SUPERVISORD
RUN set -xe && \
	apt-get update && apt-get install -y --no-install-recommends \
	supervisor && \
	apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*


# # # # # # # # # # # # # # # # # # # # # # #
# INSTALL WKHTMLTOPDF
ENV WKHTMLTOX wkhtmltox_0.12.5-1.buster_amd64.deb
ENV BUILD_PACKAGES build-essential
ENV MAIN_PACKAGES fontconfig libfreetype6 libjpeg62-turbo libxext6 libpng16-16 libx11-6 libxcb1  libxrender1 xfonts-75dpi xfonts-base 

COPY deps/$WKHTMLTOX /


RUN set -xe \
	&& apt-get update -qq \
	&& apt-get install --no-install-recommends -yq $BUILD_PACKAGES $MAIN_PACKAGES \
	&& dpkg -i ${WKHTMLTOX} \
	&& apt-get remove -y $BUILD_PACKAGES \
	&& apt-get autoremove -y \
	&& apt-get clean \
	&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
	&& rm -rf ${WKHTMLTOX} \
	&& truncate -s 0 /var/log/*log
Tarih:Docker

İlk Yorumu Siz Yapın

Bir Cevap Yazın