Bir Dockerfile, Docker’a bir imajın nasıl inşa edileceğini adım adım anlatan metin tabanlı bir tariftir. Her satır bir katman (layer) oluşturur ve bu katmanlar önbelleğe alınarak sonraki build’lerin çok daha hızlı olmasını sağlar.
Basit bir Node.js uygulaması için Dockerfile
Aşağıdaki örnek, basit bir Node.js API’sini paketleyen tipik bir Dockerfile’dır:
# 1. Temel imaj: resmi, hafif Node.js imajı
FROM node:20-alpine
# 2. Çalışma dizinini belirle
WORKDIR /app
# 3. Bağımlılık dosyalarını önce kopyala (katman önbelleği için)
COPY package*.json ./
RUN npm install --production
# 4. Uygulama kodunun geri kalanını kopyala
COPY . .
# 5. Konteyner dışına açılacak portu belirt
EXPOSE 3000
# 6. Container başladığında çalışacak komut
CMD ["node", "server.js"]
Neden COPY package*.json önce gelir?
Docker, her komutu ayrı bir katman olarak önbelleğe alır. package.json değişmediği sürece, npm install katmanı tekrar çalıştırılmaz — Docker önbellekten okur. Kodunuzu değiştirdiğinizde sadece son katmanlar yeniden inşa edilir. Bu basit sıralama, build sürelerini dakikalardan saniyelere indirebilir.
İmajı build etmek ve çalıştırmak
docker build -t benim-api:1.0 .
docker run -d -p 3000:3000 benim-api:1.0
Multi-stage build ile boyutu küçültmek
Derleme (compile) gerektiren dillerde (Go, TypeScript, Java gibi) tek aşamalı bir Dockerfile, build araçlarını da nihai imaja taşır ve gereksiz yere şişirir. Multi-stage build, bu sorunu birden fazla FROM bloğu kullanarak çözer:
# --- build aşaması ---
FROM golang:1.22 AS builder
WORKDIR /src
COPY . .
RUN go build -o app .
# --- production aşaması ---
FROM alpine:3.20
COPY --from=builder /src/app /app
ENTRYPOINT ["/app"]
İlk aşama Go derleyicisini içeren ağır bir imaj kullanır; ikinci aşama ise sadece derlenmiş binary’yi alıp birkaç megabaytlık minimal bir Alpine imajına kopyalar. Nihai imajda Go derleyicisi, kaynak kod veya build araçları bulunmaz — sadece çalıştırılabilir dosya kalır.
İyi pratik: mümkün olduğunca küçük taban imajlar (alpine, distroless) tercih edin, .dockerignore dosyasıyla gereksiz dosyaları build bağlamından hariç tutun ve tek bir Dockerfile içinde gereksiz katman sayısını artırmaktan kaçının.
.dockerignore neden önemli?
node_modules, .git gibi dizinler build context’e dahil edildiğinde hem build süresi uzar hem de imaj boyutu gereksiz yere büyür. Proje köküne bir .dockerignore dosyası eklemek, tıpkı .gitignore gibi çalışır:
node_modules
.git
*.log
.env
Dockerfile’ı öğrendikten sonra doğal bir sonraki adım, birden fazla servisi (API, veritabanı, cache) birlikte yönetmek. Bunun için Docker Compose’u bir sonraki yazıda ele alıyoruz.