Docker build check, Dockerfile'ınızı ve derleme seçeneklerinizi derlemeyi çalıştırmadan önce denetleyen yerleşik bir lint özelliğidir. Normal docker build komutu kontrolleri zaten her seferinde çalıştırır ve ihlalleri uyarı olarak gösterir; docker build --check . ise hiçbir adımı çalıştırmadan yalnızca kontrolleri yapar ve ihlal bulursa sıfırdan farklı bir çıkış koduyla biter. Dockerfile'ın başına # check=error=true yazarsanız normal derleme de ihlal durumunda durur.

Bu yazıda build check'lerin nasıl çalıştığını, uyarıların nasıl okunacağını, belirli kuralları atlamayı, uyarıları hataya çevirmeyi, deneysel kuralları açmayı ve kontrolleri CI ile Bake'e bağlamayı resmî belgelere göre anlatıyoruz. Dockerfile yazımının temelleri için Dockerfile rehberine, konu haritası için Docker öğrenme rehberi sayfasına bakabilirsiniz.

Build check nedir, ne işe yarar?

Build check nedir, ne işe yarar? Derlemeyi çalıştırmadan önce Dockerfile'ı ve derleme seçeneklerini doğrulamak., Dockerfile'ın ve seçeneklerin güncel en iyi uygulamalarla uyumlu...

Belgelere göre build check'ler Dockerfile 1.8 ile gelen bir özelliktir. Normalde bir derleme başlattığınızda Docker Dockerfile adımlarını ve derleme seçeneklerini olduğu gibi yürütür. Build check'lerle Docker, adımları yürütmek yerine verdiğiniz Dockerfile'ı ve seçenekleri inceler ve tespit ettiği sorunları raporlar. Belgeler bunu Dockerfile ve derleme seçenekleri için gelişmiş bir lint, ya da derlemenin kuru çalıştırma (dry-run) modu olarak tarif eder. Üç kullanım amacı sayılır:

  • Derlemeyi çalıştırmadan önce Dockerfile'ı ve derleme seçeneklerini doğrulamak.
  • Dockerfile'ın ve seçeneklerin güncel en iyi uygulamalarla uyumlu olduğundan emin olmak.
  • Olası sorunları ve kötü kalıpları (anti-pattern) önceden görmek.

Kontrollerin tam listesi ve her kuralın açıklaması Docker belgelerindeki Build checks reference sayfasında yer alır. Bu yazıda belgelerin örneklerinde geçen iki kural üzerinden gidiyoruz: CMD için JSON dizi söz dizimini öneren JSONArgsRecommended ve stage adlarının yazımıyla ilgili StageNameCasing.

Hangi sürümler gerekir?

Belgelere göre build check'ler Buildx 0.15.0 ve sonrasında, docker/build-push-action 6.6.0 ve sonrasında, docker/bake-action 5.6.0 ve sonrasında desteklenir. Özellik Dockerfile 1.8 ile geldiği için Dockerfile frontend sürümü de önemlidir. # syntax=docker/dockerfile:1 satırı en son 1.x sürümünü izlediğinden belgelerdeki tüm check örnekleri bu satırla başlar. Sunucunuzdaki Buildx sürümünü docker buildx version komutuyla görebilirsiniz; belgelere göre Buildx, Docker Engine ile birlikte kurulan bir CLI eklentisidir. Frontend kavramı ve sürüm kanalları BuildKit ve Buildx yazısında anlatılıyor.

Kontroller her derlemede çalışır

Ayrı bir komut çalıştırmanıza gerek yoktur: bir derleme başlatmak kontrolleri varsayılan olarak çalıştırır ve ihlalleri derleme çıktısının sonunda gösterir. Belgelerdeki örnekte derleme başarıyla tamamlanır, ama bir uyarı raporlanır:

bash
docker build .
[+] Building 3.5s (11/11) FINISHED
...

1 warning found (use --debug to expand):
  - Lint Rule 'JSONArgsRecommended': JSON arguments recommended for CMD to prevent unintended behavior related to OS signals (line 7)

Kısa mesaj üç bilgi taşır: kuralın adı, açıklama ve sorunun Dockerfile'daki satır numarası. Uyarılar bu modda derlemeyi durdurmaz; çıkış kodu 0 olur. Bu yüzden derleme günlüklerini okumadan geçen bir ekip uyarıları uzun süre fark etmeyebilir. Uyarıları görünür kılmanın iki yolu aşağıdaki bölümlerde: ayrıntılı çıktı ve uyarıları hataya çevirmek.

Ayrıntılı çıktı: --debug

Bir uyarının nedenini görmek için --debug bayrağını kullanabilirsiniz. Belgelere göre ayrıntılı çıktı kuralın belgesine bir bağlantı ve sorunun bulunduğu Dockerfile parçasını içerir:

bash
docker --debug build .
[+] Building 3.5s (11/11) FINISHED
...

 1 warning found:
 - JSONArgsRecommended: JSON arguments recommended for CMD to prevent unintended behavior related to OS signals (line 4)
JSON arguments recommended for ENTRYPOINT/CMD to prevent unintended behavior related to OS signals
More info: https://docs.docker.com/go/dockerfile/rule/json-args-recommended/
Dockerfile:4
--------------------
   2 |
   3 |     FROM alpine
   4 | >>> CMD echo "Hello, world!"
   5 |
--------------------

>>> işareti sorunlu satırı gösterir. Bu örnekte sorun, CMD talimatının shell form ile yazılmış olmasıdır.

Derlemeden yalnızca kontrol: --check

Kontrolleri derleme yapmadan çalıştırmak için normal docker build komutuna --check bayrağını eklersiniz. Bu durumda adımlar yürütülmez; yalnızca kontroller çalışır ve bulunan sorunlar yukarıdaki ayrıntılı biçimde raporlanır.

bash
docker build --check .

Belgelerin vurguladığı fark çıkış kodundadır: normal derlemenin aksine --check ile ihlal raporlanırsa komut sıfırdan farklı bir kodla çıkar. Bu, onu deploy betiklerine ve CI adımlarına koymayı kolaylaştırır; ihlal varsa sonraki adım çalışmaz. Yerel CLI yardım metninde --check bayrağı --call=check için bir kısaltma olarak listelenir; GitHub Actions ve Bake tarafında aynı yöntem call adıyla seçilir.

Uygulamalı örnek: JSONArgsRecommended uyarısını düzeltmek

Uygulamalı örnek: JSONArgsRecommended uyarısını düzeltmek

Bir Node.js uygulamasını başlatan şu Dockerfile'ı düşünün. Derlenir ve çalışır, ama son satır shell form kullandığı için kontrol bir uyarı üretir:

dockerfile
# syntax=docker/dockerfile:1
FROM node:22
WORKDIR /app
COPY index.js .
CMD node index.js

Kuralın mesajı, JSON argümanlarının işletim sistemi sinyalleriyle ilgili beklenmedik davranışı önlemek için önerildiğini söyler. Belgelerin Dockerfile kavramları sayfası da exec form ile shell form arasında SIGTERM ve SIGKILL gibi sinyallerin nasıl yakalandığı konusunda ince farklar olduğunu belirtir. Building best practices sayfası ise CMD talimatının neredeyse her zaman CMD ["executable", "param1", "param2"] biçiminde kullanılmasını önerir. Aynı sayfanın ENTRYPOINT örneği, uygulamanın container'ın PID 1 süreci olmasının container'a gönderilen Unix sinyallerini almasını sağladığını anlatır; sunucuda container'ı durdururken uygulamanın bu sinyali görmesi istediğiniz davranıştır. Düzeltilmiş hâli şöyledir:

dockerfile
# syntax=docker/dockerfile:1
FROM node:22
WORKDIR /app
COPY index.js .
CMD ["node", "index.js"]

Exec form ile shell form arasındaki farkın tamamı, ENTRYPOINT ile birlikte kullanım dahil, CMD ve ENTRYPOINT farkı yazısında anlatılıyor. Düzeltmeden sonra docker build --check . komutunun bu kural için uyarı vermemesi gerekir.

Uyarıyı hataya çevirmek: check=error=true

Varsayılan olarak ihlaller uyarıdır ve çıkış kodu 0'dır. Dockerfile'a check=error=true direktifini eklerseniz Docker kontroller çalıştıktan sonra, asıl derleme başlamadan hata verir. Belgelerdeki örnek:

dockerfile
# syntax=docker/dockerfile:1
# check=error=true

FROM alpine
CMD echo "Hello, world!"
bash
docker build .
[+] Building 1.5s (5/5) FINISHED
...

 1 warning found (use --debug to expand):
 - JSONArgsRecommended: JSON arguments recommended for CMD to prevent unintended behavior related to OS signals (line 5)
Dockerfile:1
--------------------
   1 | >>> # syntax=docker/dockerfile:1
   2 |     # check=error=true
   3 |
--------------------
ERROR: lint violation found for rules: JSONArgsRecommended
echo $?
1

Direktif belgelerdeki tüm örneklerde syntax satırının hemen altında, dosyanın en başında yer alır. Parser directive'lerin diğer yorumlardan ve talimatlardan önce gelmesi kuralını burada da uygulamanız, satırın sıradan bir yorum sanılmasını önler.

Aynı ayarı Dockerfile'ı değiştirmeden komut satırından da verebilirsiniz. Bunun için BUILDKIT_DOCKERFILE_CHECK build argümanı kullanılır:

bash
docker build --check --build-arg "BUILDKIT_DOCKERFILE_CHECK=error=true" .

İki yolun kullanım yeri farklıdır. Direktif Dockerfile ile birlikte versiyon kontrolüne girer ve projeyi derleyen herkes için geçerli olur. Build argümanı ise yalnızca o çağrıyı etkiler; örneğin geliştirme makinesinde uyarıyla yetinip CI'da sıkı davranmak için kullanılabilir.

Belirli kuralları atlamak: check=skip

Varsayılan olarak tüm kontroller çalışır. Bazı kuralları bilinçli olarak atlamak istiyorsanız check=skip direktifine kural kimliklerini virgülle ayrılmış bir liste olarak verirsiniz. Belgelerdeki örnek iki kuralı birlikte atlar:

dockerfile
# syntax=docker/dockerfile:1
# check=skip=JSONArgsRecommended,StageNameCasing

FROM alpine AS BASE_STAGE
CMD echo "Hello, world!"

Belgelere göre bu Dockerfile hiç ihlal üretmez. Örnekteki iki durum, atlanan iki kurala karşılık gelir: büyük harfle yazılmış BASE_STAGE stage adı ve shell form CMD. Aynı listeyi build argümanıyla da verebilirsiniz; tüm kontrolleri kapatmak için ise skip=all kullanılır:

bash
docker build --check --build-arg "BUILDKIT_DOCKERFILE_CHECK=skip=JSONArgsRecommended,StageNameCasing" .
dockerfile
# syntax=docker/dockerfile:1
# check=skip=all

skip=all pratikte kontrolleri devre dışı bırakır ve ileride eklenecek yeni stable kuralların uyarılarını da göremezsiniz. Bir kuralı atlamanız gerekiyorsa yalnızca o kuralı adıyla atlamak ve nedenini Dockerfile'da bir yorumla belirtmek daha izlenebilir bir yoldur.

skip ve error birlikte

Bazı kuralları atlarken kalanları hataya çevirmek için iki parametreyi noktalı virgülle (;) ayırarak aynı direktifte ya da aynı build argümanında verirsiniz:

dockerfile
# syntax=docker/dockerfile:1
# check=skip=JSONArgsRecommended,StageNameCasing;error=true
bash
docker build --check --build-arg "BUILDKIT_DOCKERFILE_CHECK=skip=JSONArgsRecommended,StageNameCasing;error=true" .

Deneysel kontroller

Bazı kontroller stable olmadan önce deneysel olarak sunulur ve varsayılan olarak kapalıdır. Hangi deneysel kontrollerin bulunduğu Build checks reference sayfasında listelenir. Hepsini açmak için experimental=all kullanılır:

bash
docker build --check --build-arg "BUILDKIT_DOCKERFILE_CHECK=experimental=all" .

Direktif olarak # check=experimental=all yazabilir ya da yalnızca istediğiniz deneysel kuralların kimliklerini virgülle verebilirsiniz. Belgelerdeki önemli bir öncelik kuralı vardır: experimental, skip'ten önce gelir. Yani skip=all ayarlayıp deneysel kontrolleri açarsanız deneysel kontroller yine de çalışır:

dockerfile
# syntax=docker/dockerfile:1
# check=skip=all;experimental=all

Seçeneklerin özeti

AmaçDockerfile direktifiBuild argümanı değeri
Uyarıyı hataya çevircheck=error=trueBUILDKIT_DOCKERFILE_CHECK=error=true
Belirli kuralları atlacheck=skip=Kural1,Kural2BUILDKIT_DOCKERFILE_CHECK=skip=Kural1,Kural2
Tüm kontrolleri atlacheck=skip=allBUILDKIT_DOCKERFILE_CHECK=skip=all
Atla ve hata vercheck=skip=Kural1;error=trueBUILDKIT_DOCKERFILE_CHECK=skip=Kural1;error=true
Deneysel kuralları açcheck=experimental=allBUILDKIT_DOCKERFILE_CHECK=experimental=all

CI ve Bake ile kullanmak

GitHub Actions'ta kontroller pull request'lerin diff görünümünde ek açıklama olarak gösterilir. docker/build-push-action adımında call girdisini check yaparsanız, belgelere göre derleme yapılandırmasında herhangi bir check uyarısı bulunduğunda iş akışı başarısız olur. Belgelerdeki kalıp, önce bu doğrulama adımını, ardından asıl derleme ve push adımını çalıştırmaktır. GitHub Actions ile Docker derlemenin genel kurulumu GitHub Actions CI/CD rehberinde.

Bake kullanıyorsanız özel bir girdi gerekmez. Belgeler, asıl hedefi miras alıp call özelliğini check yapan ayrı bir hedef tanımlamayı önerir:

hcl
target "build" {
  dockerfile = "Dockerfile"
  args = {
    FOO = "bar"
  }
}
target "validate-build" {
  inherits = ["build"]
  call = "check"
}
bash
docker buildx bake validate-build

validate-build hedefi build hedefinin bağlamını, Dockerfile'ını ve argümanlarını devralır; böylece kontroller gerçek derlemeyle aynı seçeneklerle çalışır. docker/bake-action içinde bu hedefi çağırmak ya da call: check girdisini doğrudan vermek de belgelerde gösterilen yollardır. Bake hedefleri ve kalıtım docker buildx bake yazısında ayrıntılı olarak anlatılıyor.

Kendi sunucunuzda CI kullanmıyorsanız aynı mantığı deploy betiğinize taşıyabilirsiniz: betiğin başında docker build --check . çalıştırın; komut ihlal bulursa sıfırdan farklı kodla çıkacağı için kabuk betiğiniz orada durur ve bozuk bir imaj hiç üretilmez.

Bu parçaları birleştiren makul bir düzen şöyle özetlenebilir: geliştirme sırasında editör eklentisi ve normal derlemedeki uyarılar size erken geri bildirim verir; ortak depoya giren Dockerfile'larda bilinçli olarak atladığınız kuralları check=skip ile adıyla yazarsınız; CI ya da deploy betiği ise --check veya BUILDKIT_DOCKERFILE_CHECK=error=true ile kalan her ihlalde durur. Böylece kurallar ekibin her üyesi için aynı biçimde uygulanır ve uyarılar derleme günlüklerinde kaybolmaz.

Sık yapılan hatalar

Sık yapılan hatalar: Uyarıların derlemeyi durduracağını sanmak, --check ile imaj üretildiğini sanmak, skip=all ile tüm uyarıları susturmak, Deneysel kuralların varsayılan...
  • Uyarıların derlemeyi durduracağını sanmak: varsayılan çıkış kodu 0'dır; durdurmak için check=error=true ya da --check gerekir.
  • --check ile imaj üretildiğini sanmak: bu modda adımlar yürütülmez, yalnızca kontroller çalışır.
  • skip=all ile tüm uyarıları susturmak: yeni kuralların uyarılarını da kaybedersiniz; kuralları adıyla atlayın.
  • Deneysel kuralların varsayılan çalıştığını sanmak: açıkça experimental= ile açmanız gerekir.
  • Direktifi dosyanın ortasına yazmak: belgelerdeki gibi syntax satırının hemen altına, en başa koyun.

Sık Sorulan Sorular

check=error=true derlemenin hangi aşamasında hata verir?

Belgelere göre kontroller çalıştıktan sonra, asıl derleme adımları başlamadan. Yani ihlal varsa hiçbir RUN adımı yürütülmez ve yarım kalmış bir imaj oluşmaz; çıkış kodu 1 olur.

Kural listesini nerede bulurum?

Tüm kontroller ve açıklamaları Docker belgelerindeki Build checks reference sayfasındadır. --debug çıktısındaki "More info" bağlantısı da ilgili kuralın sayfasına götürür.

Kontrolleri yalnızca CI'da sıkı yapmak mümkün mü?

Evet. Dockerfile'a direktif yazmak yerine CI komutunda BUILDKIT_DOCKERFILE_CHECK=error=true build argümanını verirseniz yerel derlemeler uyarıyla devam eder, CI ise ihlalde durur.

Compose ile build check çalıştırabilir miyim?

Belgelerde Compose için ayrı bir check seçeneği anlatılmaz. Compose dosyası Bake tarafından okunabildiği için Bake hedefi üzerinden ya da doğrudan docker build --check ile ilgili Dockerfile'ı denetleyebilirsiniz. Compose dosyasından Bake kullanımı Bake yazısında.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: Docker öğrenme rehberi · CMD ve ENTRYPOINT farkı · BuildKit ve Buildx · docker buildx bake · GitHub Actions CI/CD · Dockerfile yazma rehberi