docker build . komutundaki o küçük nokta aslında önemli bir şey söyler: “build bağlamı (build context) bu dizindir.” Docker, build başlarken bu dizinin içeriğini build motoruna gönderir. Dizinde büyük dosyalar, node_modules ya da gizli bir .env varsa; build yavaşlar, imaj şişer ve — en kötüsü — o gizli dosya imajın içine girebilir.

Bağlam gerçekte ne kadar büyük?

Örnek bir proje düşünelim: 50 MB’lık bir veri dosyası, 20 MB’lık bir node_modules klasörü, bir .env dosyası ve küçük bir app.txt. Dockerfile ise yalnızca tüm klasörü kopyalıyor:

FROM temel-imaj
COPY . /app

BuildKit’in ayrıntılı çıktısında (--progress=plain) bağlamın boyutu görünür:

$ docker build --progress=plain -t ornek:1 .
...
#5 transferring context: 70.02MB 0.9s done

Tek satırlık uygulama için 70 MB gönderildi — ve COPY . /app bunların hepsini (gizli .env dahil) imaja yazdı. Her docker build‘da bu transfer tekrar edilir.

.dockerignore ile çözüm

Bağlam dizininin köküne .dockerignore dosyası koyun. Biçimi .gitignore‘a benzer; listelenen yollar build bağlamına hiç gönderilmez:

node_modules
*.bin
.env
.git

Aynı build’i yeniden çalıştırdığımızda:

#5 transferring context: 124B 0.0s done

$ docker run --rm ornek:2 ls -A /app
.dockerignore
Dockerfile
app.txt

70 MB’dan 124 bayta düştü; .env, node_modules ve büyük dosya imajda yok. Bu dosya aynı zamanda önbelleği de korur: ilgisiz bir dosya (örneğin bir log) değiştiğinde COPY . . katmanı gereksiz yere geçersiz kalmaz.

!

.dockerignore bir güvenlik önlemi olarak da düşünülmelidir: .env, *.pem, .git gibi dosyaları buraya yazmak, COPY . . ile yanlışlıkla imaja girmelerini engeller. Detay için Container Image Güvenliği yazısına bakın.

Sık kullanılan kalıplar

Satır Ne yapar?
node_modules Bağımlılıkları imaj içinde npm ci ile kurduğunuz için host’taki kopyayı dışarıda bırakır
.git Depo geçmişini (genellikle büyük) bağlamdan çıkarır
*.log, tmp* Geçici ve log dosyaları
.env* Ortam ve gizli bilgi dosyaları
Dockerfile, .dockerignore İmaja girmesi gerekmeyen yapılandırma (bu dosyalar yine de build’e okunur)
!istisna.txt ! ile bir önceki kuralın istisnası tanımlanır

Not: Yukarıdaki deneyde Dockerfile ve .dockerignore‘ı listeye yazmadığımız için COPY . /app bunları da imaja kopyaladı (ls çıktısındaki iki dosya). Listeye yazarsanız imaja girmezler; build motoru yine de onları build talimatları için okur.

Büyük bağlamı fark etmenin yolları

  • docker build --progress=plain çıktısında transferring context satırına bakın; yüzlerce MB görüyorsanız bir şeyler fazla.
  • Build başlamadan önce uzun süre “bekliyorsa” bu çoğunlukla bağlamın gönderilmesidir, derleme değil.
  • İmaj beklenenden büyükse docker run --rm imaj ls -A /app ile içine neyin girdiğine bakın.

Hızlı kontrol listesi

  • Projenizin kökünde .dockerignore var mı?
  • .git, node_modules, log ve .env dosyaları listede mi?
  • COPY . . yerine mümkünse yalnızca gereken dosyaları mı kopyalıyorsunuz?
  • transferring context boyutu makul mü?

Sıradaki adım: build’i bir de önbellek açısından hızlandırmak için Build Cache ve BuildKit yazısına geçin. Dockerfile’ınızı otomatik kontrol etmek için sitemizdeki Dockerfile Kontrolcüsü aracını da kullanabilirsiniz.