Golang ile backend servisler geliştirirken sadelik ve hız benim için hep öncelikliydi. Yazdığım uygulamaların taşınabilir ve izole bir şekilde çalışmasını sağlamak için yıllardır Docker kullanıyorum. Bu yazıda, Go uygulamalarını nasıl containerize ettiğimi, farklı base imajlar arasında nasıl seçim yaptığımı ve özellikle scratch ile nasıl minimal imajlar oluşturduğumu kendi deneyimlerimle anlatacağım.

Başlangıç olarak aşağıdaki gibi çok basit bir Go HTTP servisi kullandım. Bu servis, Berlin saatini döndürüyor:

Go
package main

import (
	"fmt"
	"net/http"
	"time"
)

func handler(w http.ResponseWriter, r *http.Request) {
	loc, _ := time.LoadLocation("Europe/Berlin")
	currentTime := time.Now().In(loc)
	fmt.Fprintf(w, "Berlin time: %s", currentTime.Format("15:04:05"))
}

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}

Bu örnek küçük gibi görünse de bir detay var: time.LoadLocation() timezone dosyalarına ihtiyaç duyuyor. Bu da Docker imajı seçerken göz önünde bulundurmamız gereken bir konu.

Dockerfile: Minimal ve Performanslı Build Süreci

Bu uygulamayı build etmek için aşağıdaki gibi iki aşamalı bir Dockerfile hazırladım:

Dockerfile
FROM golang:alpine AS build
RUN apk --no-cache add tzdata
WORKDIR /app
ADD . .
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp

FROM scratch AS final
COPY --from=build /app/myapp .
COPY --from=build /usr/share/zoneinfo /usr/share/zoneinfo
ENV TZ=Europe/Berlin
CMD ["/myapp"]

scratch base imajı tamamen boştur. Ne bir paket yöneticisi vardır, ne bir shell. Sadece sizin koyduğunuz binary ve dosyalar bulunur. Bu sayede imaj boyutu ciddi anlamda küçülür (çoğu zaman 5MB’tan az). Ancak bu sadeliğin bir bedeli var: ihtiyacınız olan her şeyi kendiniz taşımalısınız. Örneğin, yukarıdaki örnekte timezone dosyalarını tzdata üzerinden aldım ve scratch imajına manuel olarak kopyaladım. Aksi takdirde saat bilgisi yanlış çıkıyor.

Docker Base İmajlarını Seçerken Nelere Dikkat Ettim?

Geçmişte farklı imajlarla denemeler yaptım. Her birinin farklı avantajları var:

🧊 alpine, alpine3.22, alpine3.21

  • Küçük ve sade bir dağıtım. Ancak golang:alpine imajı baz alındığında toplam boyut genellikle 500MB–1GB civarına ulaşabiliyor.
  • apk paket yöneticisi sayesinde tzdata gibi ek ihtiyaçlar kolayca kurulabiliyor.
  • Build aşamasında oldukça hızlı çalışıyor.
  • Scratch öncesi minimal build ortamı olarak gayet uygun.

🧱 bookworm, bullseye

  • Debian tabanlı imajlardır. bookworm güncel, bullseye bir önceki sürüm.
  • Ancak golang:bookworm veya golang:bullseye gibi imajlar 500MB ile 1GB arasında olabilir.
  • Sistem bağımlılıkları, native C kütüphaneleri veya debug araçları gerekiyorsa tercih edilir.
  • apt paket yöneticisiyle çalıştığı için çoğu geliştiriciye daha tanıdık gelebilir.

⚙️ scratch

  • En minimal yapı, hiçbir şey içermez
  • Maksimum güvenlik, minimum imaj boyutu
  • Ancak timezone dosyaları ve diğer gerekli bağımlılıkları kendiniz taşımalısınız
  • Sadece statik olarak derlenmiş binary’lerle kullanılabilir (CGO_ENABLED=0 şart)

Hangi İmaj Ne Zaman Kullanılır?

  • Geliştirme aşamasında hızlı çalışmak için alpine ya da bookworm tercih ederim.
  • Üretim ortamında, özellikle küçük servislerde scratch mükemmel bir seçim.
  • Sistem bağımlılığı olan, native kütüphane kullanan uygulamalarda alpine veya bullseye daha risksiz.

Kendi uygulamalarımda genelde önce golang:alpine ile build edip, son aşamada scratch’a geçerek temiz ve küçük bir üretim imajı elde ediyorum. Bu yapı sayesinde CI/CD süreçleri hızlanıyor, image scanning araçları daha az uyarı veriyor ve dağıttığım container’lar hem güvenli hem hızlı çalışıyor.

Tecrübeyle Sabit: Minimalizm Gerçekten İşe Yarıyor

Yıllardır Go ile yazdığım servisleri Docker ile taşırken öğrendiğim en önemli şey şu oldu: ne kadar az şey, o kadar az sorun. scratch gibi sade yapıların avantajını ancak denediğinizde fark ediyorsunuz. Daha hızlı build, daha küçük boyut, daha az yüzey alanı.

Sen de Go ile geliştiriyorsan ve Docker kullanıyorsan, bu yaklaşımı mutlaka denemeni öneririm. Hafiflik, sadelik ve performans gerçekten kazandırıyor.

Diğer Bağlantılar

Kategoriler:

Golang, Yazılım,