Docker Nedir ve Nasıl Kullanılır?

Beyza Alkış
GoTurkiye
Published in
6 min readJul 9, 2023

Merhabalar, Go Türkiye’nin mentorship programındayım ve golang dilini öğreniyorum, docker konusunu işlemeye başladık ve ben de docker üzerine araştırmaya başladım, bu yazımda;

  • Docker
  • Docker Nasıl Kullanılıyor?
  • Docker Engine ve Ana Bileşenleri
  • Docker Images Kavramı ve Golang ile Docker Image
  • DockerFile ve Komutları
  • Docker Layers
  • Docker Cache
  • Multi-Stage Build

konularını ele alarak detaylıca açıklamaya çalışacağım.

Docker, konteyner(container) adı verilen sanal ortamlarda uygulama geliştirmek, uygulamaları dağıtmak ve yönetmek için kullanılan açık kaynaklı bir platformdur. Docker ile Linux, MacOs ve Windows üzerinde Linux ve Windows sanal makinelerini çalıştırabiliriz.

Docker kullanmadan bir sistemi oluşturmak için ekstra çaba gösterilen yorucu bir süreçken docker ile yürütülen bütün süreçler birkaç saniyede gerçekleşebilmektedir.

Docker web sistemlerinin, kurulumunu, dağıtımını ve test edilmesini rahatlıkla gerçekleştirebiliyor. Bu sayede docker aslında “Benim bilgisayarımda çalışıyordu sunucuda neden çalışmadı?” sorununu ortadan kaldırıyor.

Docker’ın sanallaştırma altyapısı diğer sanal makinelerden biraz daha farklıdır. Docker, Docker Engine üzerinden işletim sistemine erişim sağlar ve sistem araçlarını paylaşımlı bir şekilde kullanır.

Docker,

  • Daha az kaynakta daha çok iş yükü çalıştırır.
  • Çoklu bulut platformlarında çalışabilen son derece taşınabilir iş yükleri geliştirir.
  • Sanal makinelere uygun maliyetli bir alternatif geliştirir.

Docker Temel Bileşenleri

1. Docker Engine (DE)

Docker Engine, Docker’ın temel bileşenidir ve Docker uygulamalarının çalıştığı ortamı sağlayan yazılım bileşenidir. Docker Engine, konteyner oluşturma, çalıştırma ve yönetme işlemlerini gerçekleştirir.Docker sisteminin çekirdeğini oluşturur ve ana makineye kurulur.

Docker Engine’in ana bileşenleri:

a. Docker Daemon: Docker Engine’in çekirdek bileşenidir. Arka planda çalışan bir süreçtir ve Docker ile etkileşimleri yönetir. Docker Daemon, Docker konteynerlerini oluşturma, çalıştırma, durdurma, silme gibi işlemleri gerçekleştirir. Ayrıca, Docker imajlarının indirilmesi, depolanması ve yönetilmesi gibi işlemleri de yönetir.

b. Docker CLI (Command Line Interface): Docker Engine’e komut satırı arayüzüyle erişmenizi sağlar. Docker CLI, kullanıcıların Docker Daemon ile etkileşim kurmasını ve konteynerlerin yönetimini yapmasını sağlar. Kullanıcılar, Docker CLI aracılığıyla konteynerlerin oluşturulması, başlatılması, durdurulması, silinmesi gibi işlemleri gerçekleştirebilir. Docker CLI komutları, Dockerfile adı verilen yapılandırma dosyalarından imajların oluşturulması gibi işlemleri de yönetir.

c. Docker API: Docker Engine, bir RESTful API (Application Programming Interface) sağlar. Bu API, Docker Daemon ile etkileşim kurmak ve Docker işlemlerini programatik olarak yönetmek için kullanılabilir. Docker API, uygulama geliştiricilerinin Docker konteynerlerini programlama dilleri veya araçlar aracılığıyla yönetmelerine olanak tanır.

2. Docker Images

Sanal makineler için anlık görüntüler gibi Docker Images’de değişmeyen kaynak kodu, kitaplıkları, araçları ve bir uygulamayı çalıştırmak için gerekli olan tüm dosyalardan oluşan salt okunur dosyalardır. Docker Images’da görüntüler değişmez bir görüntüde değişiklik yapıldığında yeni bir görüntü oluşturulmalıdır.

Docker Images, herhangi bir dilde yazılmış uygulamaları çalıştırmak için kullanılan Docker konteynerlerinin temel yapı taşlarıdır. Docker imajları, bir Go uygulamasının tüm bağımlılıklarını içeren ve çalıştırılabilir bir konteyner haline getiren şablonlardır.

Docker Images’ı, herhangi bir dilde yazılmış uygulamaların kolaylıkla taşınabilir, paylaşılabilir ve dağıtılabilir olmasını sağlar. Bu sayede uygulamanızı farklı ortamlarda çalıştırabilir ve uygulama bağımlılıklarıyla ilgili sorunları en aza indirebilirsiniz.

Go dili ile geliştirilmiş bir uygulamanın Docker image’ını oluşturmak için:

a. İlk olarak, Go uygulamanızı Docker konteynerine dahil etmek için bir Dockerfile oluşturmanız gerekmektedir. Dockerfile, Go uygulamasının çalıştırılacağı Docker imajının nasıl oluşturulacağını belirtir.

b. Dockerfile’da, Go uygulamanızın çalışması için gereken temel imajı (FROM) belirtmeniz gerekecektir. Genellikle golang:latest veya golang:alpine gibi resmi Go imajlarını temel olarak kullanabilirsiniz.

c. Dockerfile’da, Go uygulamanızın Docker imajına nasıl dahil edileceğini belirtmelisiniz. Bu, Go uygulamanızın kaynak dosyalarını kopyalamak, bağımlılıkları yüklemek ve uygulamayı derlemek gibi adımları içerebilir.

d. Dockerfile’da, Go uygulamanızın nasıl çalıştırılacağını belirtmelisiniz. Bu, çalıştırılacak komutları (CMD) veya başlatılacak bir giriş noktasını (ENTRYPOINT) belirlemeyi içerebilir.

e. Dockerfile’ı oluşturduktan sonra, Docker Engine kullanarak Docker imajını oluşturmanız gerekecektir. Bu, Dockerfile’ın bulunduğu dizinde aşağıdaki gibi bir komutu çalıştırarak gerçekleştirilebilir: (Burada <image-name>, oluşturduğunuz Docker imajının adını temsil eder.)

docker build -t <image-name> .

f. Docker imajınız başarıyla oluşturulduktan sonra, Docker Engine kullanarak bu imajdan bir Docker konteyneri çalıştırabilirsiniz: (Burada <container-name>, çalıştıracağınız Docker konteynerinin adını temsil eder.)

docker run -d --name <container-name> <image-name>

3. DockerFile

Dockerfile, herhangi bir dilde yazılmış uygulamanın Docker imajını oluşturmak için kullanılan bir metin dosyasıdır. DockerFile, Docker Engine tarafından yorumlanarak bir Docker imajının yapısını ve içeriğini tanımlar. DockerFile, Golang uygulamalarını Docker konteynerlerinde taşınabilir ve tekrarlanabilir bir şekilde çalıştırmak için kullanılan önemli bir yapılandırma dosyasıdır.

DockerFile’ın komutlar ve yönergeleri:

a. Başlangıç noktası (FROM): Docker imajının hangi temel imajdan türetileceğini belirtir. Go uygulamaları için genellikle resmi Go imajları (golang:latest, golang:alpine gibi) kullanılır.

FROM golang:alpine

b. Çalışma dizini ayarı (WORKDIR): Docker imajının içinde çalıştırılacak komutların çalışacağı dizini belirtir. Bu adım, diğer adımların çalışacağı varsayılan dizini belirler.

WORKDIR /app

c. Uygulama dosyalarının kopyalanması (COPY veya ADD): Golang uygulamanızın Docker imajına dahil edilecek dosyalarını kopyalar.

COPY . .

d. Bağımlılıkların yüklenmesi: Eğer uygulamanız dış bağımlılıklara sahipse, bu adımda bağımlılıkların yüklenmesi yapılır. Bu adımda genellikle Go modül kullanılır.

RUN go mod download

e. Uygulamanın derlenmesi (RUN): Go uygulamanızı derleyerek çalıştırılabilir bir dosya oluşturur.

RUN go build -o myapp

f. Uygulamanın çalıştırılması (CMD veya ENTRYPOINT): Docker konteyneri başlatıldığında çalıştırılacak komutu belirtir.

CMD ["./myapp"]

Bu adımları içeren DockerFile’ı oluşturduktan sonra, Docker Engine kullanarak Docker Images oluşturabilirsiniz. Aşağıdaki komutla Docker Images oluşturabilirsiniz: (<image-name>, oluşturduğunuz Docker Images adını temsil eder. DockerFile'ın bulunduğu dizindeki "." ifadesi, DockerFile'ı kullanarak imagesın oluşturulacağı dizini temsil eder.)

docker build -t <image-name> .

4. Docker Layers (Katmanlar)

Docker, katmanlar (layers) olarak adlandırılan yapılar kullanılarak oluşturulur. Her Docker Images, birden çok katmana sahiptir. Her katman, bir önceki katmandan farklılık gösteren bir dosya veya yapısal değişikliği temsil eder. Bu katmanlar, konteynerlerin oluşturulması, dağıtılması ve paylaşılması sırasında büyük bir esneklik sağlar.

Her bir Docker layer (katmanı), bir dosya veya bir dizi dosya değişikliğini içerir. Örneğin, bir Docker Images oluştururken, önceden oluşturulmuş bir temel imaj (base image) alınır ve üzerine katmanlar eklenir. Her bir katman, yeni bir dosya veya dosya değişikliği ekleyerek veya mevcut dosyaları değiştirerek önceki katmandan türetilir. Bu şekilde, katmanlar bir araya gelerek son imajı oluşturur.

Docker layers (katmanları), dosya sistemine yapılan değişiklikleri izler ve katmanlar arasında bir farkı sadece değişen kısımları saklayarak depolama alanından tasarruf eder. Bir Docker imajı oluşturulurken, her bir katman önceki katmanın üzerine biner ve sonuç olarak son imaj elde edilir. Bu katmanlar, Docker konteynerinin hafif ve hızlı olmasını sağlar ve imajın güncellenmesi veya paylaşılması gerektiğinde sadece değişen katmanların yeniden oluşturulmasını gerektirir.

Docker layers (katmanları), konteynerlerin performansını artırırken, imageların depolama alanında daha verimli bir şekilde yönetilmesine olanak sağlar. Katmanlar, paylaşılabilirlik ve yeniden kullanılabilirlik sağlar ve Docker ekosisteminde imajların dağıtılmasını ve yönetilmesini kolaylaştırır.

5. Docker Cache

Docker cache, Docker Imagelar oluşturulurken ve DockerFile dosyaları işlenirken kullanılan bir mekanizmadır. Docker, yapılandırma talimatları olan DockerFile’ları kullanarak Docker Imagelar otomatik olarak oluşturur. Bu işlem sırasında, her bir DockerFile komutu bir konteyner katmanını temsil eder.

DockerFile’da bir komut çalıştırıldığında, Docker önce önbelleğe bakar ve aynı komutu içeren bir önceki katmanın varlığını kontrol eder. Eğer aynı komut daha önce çalıştırıldıysa ve önbellekte depolandıysa, Docker bu komutu tekrar çalıştırmaz ve önbellekten doğrudan ilgili katmanı kullanır. Bu, tekrarlanan işlemlerin hızlı bir şekilde tamamlanmasını sağlar ve imaj oluşturma süresini azaltır.

Docker cache, imaj oluşturma sürecini hızlandırırken, aynı zamanda bazı durumlarda beklenmedik sonuçlara neden olabilir. Örneğin, bir DockerFile’da bir komut değiştirildiğinde ve imaj yeniden oluşturulduğunda, Docker cache eski komutun önbelleğini kullanmaya devam edebilir. Bu, DockeFile’da yapılan değişikliklerin yansıtılmamasına ve beklenmeyen sonuçlara yol açabilir. Bu durumu önlemek için, imajı güncellemek için --no-cache bayrağı kullanılabilir. Bu, tüm komutları önbelleklemeyi atlayarak her seferinde taze bir imaj oluşturulmasını sağlar.

6. Multi-Stage Build

Go, Docker’da multi-stage build (çoklu aşamalı derleme) olarak adlandırılan bir teknik kullanarak uygulamaların Docker imajlarını oluşturmak için kullanılabilir. multi-stage build, son derece hafif ve optimize edilmiş Docker imajları oluşturmak için kullanılan bir yaklaşımdır.

Go dilinin statik olarak derlenen doğası, multi-stage build için idealdir. Bu yöntemde, DockerFile içinde birden fazla aşama (stage) tanımlanır ve her aşama, imajın farklı bir bölümünü oluşturmak için kullanılır. Her aşama, bir önceki aşamadan aldığı gerekli bileşenleri kullanarak imajı oluşturur.

Multi-Stage Build kullanmanın faydaları:

a. Küçük ve optimize edilmiş imajlar: İlk aşamada, Go uygulamanızın derlenmiş çalıştırılabilir dosyasını üretiriz. Ardından, ikinci bir aşamada bu çalıştırılabilir dosyayı alıp son derece hafif bir temel imajda çalışacak bir Docker Image oluştururuz. Böylece sonuç, sadece çalıştırılabilir dosya ve gerekli bağımlılıkları içeren optimize edilmiş bir imaj olur.

b. Güvenlik: İkinci aşamada, sadece uygulamanızın çalıştırılabilir dosyasını içeren temel bir imaj kullanırız. Bu, imajın sadece gereken minimum bileşenlere sahip olmasını sağlar ve saldırı yüzeyini küçültür.

c. Hızlı derleme süreleri: İlk aşamada, Go uygulamanızı derleriz. Bu aşamada, tüm bağımlılıklar indirilir ve derleme gerçekleştirilir. İkinci aşamada ise, derleme işlemi tamamlanmış çalıştırılabilir dosyayı alır ve bu dosyayı temel imajda çalıştırmak için kullanır. Bu, daha hızlı derleme süreleri sağlar ve gereksiz tekrarlamaları önler.

Go multi-stage build Dockerfile’ı:

# İlk aşama: Derleme aşaması
FROM golang:alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

# İkinci aşama: Çalışma aşaması
FROM alpine
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]
  • Umarım faydalı olmuştur, diğer yazılarımda görüşmek üzere :)

--

--