2024-05-15Hünkar Döner

İdeal Bir Dockerfile Nasıl Olmalı? En İyi Pratikler

DockerBest PracticesSecurityContainer
İ

İdeal Bir Dockerfile Nasıl Olmalı?

Bir uygulamanın Dockerize edilmesi (konteynerleştirilmesi) sadece FROM ubuntu yazıp içine her şeyi yüklemek değildir. Kötü yazılmış bir Dockerfile; güvenlik açıklarına, devasa imaj boyutlarına ve yavaş build sürelerine neden olur.

İşte ideal bir Dockerfile için en iyi pratikler:

1. Doğru Base Image Seçimi

ubuntu veya debian gibi büyük ve genel amaçlı imajlar yerine, uygulamanıza özel minimal imajları tercih edin.

  • Alpine: Çok küçüktür (5MB) ancak glibc yerine musl kullandığı için bazı uyumluluk sorunları olabilir.
  • Distroless: Google tarafından geliştirilen, içinde shell (bash) bile olmayan, sadece uygulamanın çalışması için gerekenleri içeren en güvenli imajlardır.

2. Multi-Stage Builds Kullanın

Go veya Java gibi derlenen dillerde, derleme (build) araçlarını (compiler, maven) son imaja taşımayın. Multi-stage build ile sadece derlenmiş binary'yi son imaja kopyalayın.

# Stage 1: Build
FROM golang:1.16 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

# Stage 2: Runtime
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/myapp .
CMD ["./myapp"]

3. Katman (Layer) Sayısını Azaltın

Her RUN, COPY ve ADD komutu yeni bir katman oluşturur. Komutları zincirleyerek (chaining) tek bir RUN komutunda birleştirin.

  • Kötü:
    RUN apt-get update
    RUN apt-get install -y python3
    
  • İyi:
    RUN apt-get update && apt-get install -y python3 \
        && rm -rf /var/lib/apt/lists/*
    
    (Not: apt-get clean yaparak cache'i temizlemek imaj boyutunu küçültür.)

4. Root Kullanıcısını Kapatın

Konteynerler varsayılan olarak root yetkisiyle çalışır. Bu büyük bir güvenlik riskidir. Uygulamanızı çalıştırmak için özel bir kullanıcı oluşturun.

RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

5. .dockerignore Kullanın

git geçmişi, test dosyaları veya yerel node_modules klasörü gibi gereksiz dosyaların imaja kopyalanmasını engellemek için .dockerignore dosyası oluşturun. Bu, build süresini (context sending) hızlandırır.

6. Sürüm Sabitleme (Pinning)

node:latest gibi etiketler (tags) kullanmayın. Bu, bugün çalışan build'in yarın bozulmasına neden olabilir. Daima spesifik versiyon kullanın: node:14.17.0-alpine.