Docker derlemesinin sonucunun nereye ve hangi biçimde yazılacağını exporter belirler; exporter'ı --output (kısaca -o) bayrağıyla seçersiniz. Varsayılan çıktı yerel imaj deposuna yüklenen bir container imajıdır. --output type=local,dest=./out ile imaj yerine derlenen dosya sistemini bir klasöre, type=tar ile bir tar arşivine, type=oci veya type=docker ile bir imaj düzeni tarball'ına yazabilir, type=registry ile doğrudan registry'ye gönderebilirsiniz.

Bu yazıda yedi exporter'ı, --load ve --push kısaltmalarının arka planını, Docker ile tek başına çalışan ikili dosya üretmeyi, çok platformlu çıktıları, birden fazla exporter'ı aynı anda kullanmayı ve sıkıştırma seçeneklerini resmî belgelere göre anlatıyoruz. Builder ve driver kavramları BuildKit ve Buildx yazısında, genel konu haritası Docker öğrenme rehberi sayfasında.

Exporter türleri

Exporter türleri: image, registry, local, Kök dosya sistemini yerel bir tar arşivine paketler

Belgelere göre Buildx şu exporter'ları destekler:

ExporterÜrettiği çıktı
imageDerleme sonucundan bir container imajı
registryimage ile aynı, ama sonucu belirtilen registry'ye gönderir
localDerlemenin kök dosya sistemini yerel bir klasöre açar
tarKök dosya sistemini yerel bir tar arşivine paketler
ociSonucu OCI image layout biçiminde yerel dosya sistemine yazar
dockerSonucu Docker Image Specification v1.2.0 biçiminde yerel dosya sistemine yazar
cacheonlyÇıktı üretmez; derlemeyi çalıştırıp yalnızca önbellek oluşturur

Genel söz dizimi --output type=TÜR[,parametre=değer...] biçimindedir. Belgelerin hatırlattığı nokta şudur: yaygın kullanım senaryolarının çoğunda exporter'ı açıkça yazmanız gerekmez. Exporter'ı yalnızca çıktıyı özelleştirmek ya da diske kaydetmek istediğinizde belirtirsiniz; --load ve --push seçenekleri Buildx'in uygun exporter ayarlarını kendisinin çıkarmasını sağlar.

--load ve --push aslında neyi seçer?

--load, --output type=docker için bir kısaltmadır ve sonucu yerel imaj deposuna yükler. Yüklenen imajlar derleme biter bitmez docker run ile kullanılabilir ve docker images listesinde görünür. Varsayılan docker driver'ıyla derlenen imajlar zaten otomatik yüklenir; bu yüzden tek sunuculu kurulumlarda --load yazmanız çoğu zaman gerekmez.

bash
docker buildx build --tag benim/uygulama:dev --load .
docker buildx build --output type=docker,name=benim/uygulama:dev .

--push ise --tag ile birlikte kullanıldığında image exporter'ı seçer ve push parametresini açar. Belgelere göre aşağıdaki üç komut aynı işi yapar:

bash
docker buildx build --tag registry.example.com/benim/uygulama:1.0 --push .
docker buildx build --output type=image,name=registry.example.com/benim/uygulama:1.0,push=true .
docker buildx build --output type=registry,name=registry.example.com/benim/uygulama:1.0 .

Çıktı belirtmezseniz: cacheonly

Bir exporter seçmez ve --load gibi kısaltmaları da kullanmazsanız Buildx varsayılan olarak cacheonly exporter'ını kullanır. İstisna docker driver'ıdır; orada docker exporter devreye girer. cacheonly varsayılan olarak seçildiğinde Buildx bir uyarı yazar: sonuç yalnızca build önbelleğinde kalır, registry'ye göndermek için --push, Docker'a yüklemek için --load kullanmanız istenir. docker-container builder'a geçen birinin imajını bulamamasının nedeni çoğunlukla budur.

cacheonly'yi bilerek de seçebilirsiniz. Belgeler onu bir test derlemesi yapmak ya da önce derleyip dışa aktarımları sonraki komutlarla oluşturmak için önerir; önbellek oluştuğu için sonraki derlemeler hemen tamamlanır.

bash
docker buildx build --output type=cacheonly .

Docker ile ikili dosya derlemek: local exporter

Bazen uygulamanızı imaj olarak dağıtmak istemezsiniz; sadece derlenmiş bir dosyaya ihtiyacınız vardır. docker build --output bayrağına bir dosya yolu verirseniz Docker, derlemenin sonunda build container'ının içeriğini ana makinedeki o konuma çıkarır. Bu local exporter'dır. Belgeler bunun Go ve Rust gibi tek ikili dosyaya derlenen dillerde iyi çalıştığını belirtir. Avantajı, derleme araç zincirini sunucunuza kurmadan Docker'ın izolasyonunu kullanmanızdır. Belgelerdeki Rust örneği:

dockerfile
# syntax=docker/dockerfile:1
FROM rust:alpine AS build
WORKDIR /src
COPY <<EOT hello.rs
fn main() {
    println!("Hello World!");
}
EOT
RUN rustc -o /bin/hello hello.rs

FROM scratch
COPY --from=build /bin/hello /
ENTRYPOINT ["/hello"]
bash
docker build --output=. .

COPY <<EOT söz dizimi bir here-document'tır ve programı Dockerfile içinde satır içi oluşturur. İlk stage programı derler, ikinci stage ise yalnızca ikili dosyayı boş scratch imajına kopyalar. --output=. son stage'in dosya sistemini geçerli klasöre yazdığı için klasörde yalnızca hello dosyası oluşur. Belgelerin vurguladığı gibi local exporter multi-stage derlemelerde çok kullanışlıdır, çünkü yalnızca en az sayıda yapıtı, örneğin kendi başına çalışan ikili dosyaları dışa aktarmanızı sağlar. Multi-stage temelleri için Dockerfile rehberine bakın.

Çok platformlu çıktı ve platform-split

Local exporter, çok platformlu derlemelerle birlikte her hedef için ayrı ikili dosya üretebilir. Varsayılan davranışta her platform için bir alt klasör oluşur. Belgelerdeki örnek busybox ile platform adını içeren dosyalar üretir:

dockerfile
FROM busybox AS build
ARG TARGETOS
ARG TARGETARCH
RUN mkdir /out && echo foo > /out/hello-$TARGETOS-$TARGETARCH

FROM scratch
COPY --from=build /out /
bash
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  --output type=local,dest=./output \
  .

Bu komut output/linux_amd64/hello-linux-amd64 ve output/linux_arm64/hello-linux-arm64 dosyalarını üretir. platform-split=false verirseniz tüm platformların dosyaları aynı klasörde birleşir; belgelere göre birden fazla platform aynı adda dosya üretirse dışa aktarma hatayla durur. Bu yüzden düz klasör istiyorsanız dosya adına platformu eklemelisiniz.

Tek platformlu derlemede ise alt klasör oluşmaz, dosya doğrudan hedef klasöre yazılır. Tek platformda da alt klasör istiyorsanız platform-split=true parametresini açıkça vermeniz gerekir. platform-split parametresi yalnızca local exporter'da vardır.

KomutSonuç
--platform iki platform, varsayılanoutput/linux_amd64/... ve output/linux_arm64/...
--platform iki platform, platform-split=falseTüm dosyalar output/ altında; aynı ad hata verir
--platform tek platform, varsayılanDosya doğrudan output/ altında
--platform tek platform, platform-split=trueoutput/linux_amd64/... alt klasörü

tar exporter

tar exporter, local ile aynı içeriği üretir ama sonucu bir tar arşivine paketler. Ortak parametre dest'tir. Derlenen yapıtı tek dosya olarak başka bir sunucuya taşımak ya da bir sürüm arşivine eklemek istediğinizde kullanışlıdır.

bash
docker buildx build --output type=tar,dest=./yapit.tar .

İmaj düzenini dosyaya yazmak: oci ve docker exporter

oci exporter derleme sonucunu OCI image layout biçiminde bir tarball'a, docker exporter ise Docker image layout biçiminde yazar. dest parametresi tarball'ın yolunu belirler. Belgelerdeki örnekte --output type=oci,dest=./image.tar ile oluşturulan arşiv açıldığında içinde blobs/sha256 klasörü, index.json, manifest.json ve oci-layout dosyaları bulunur.

bash
docker buildx build --output type=oci,dest=./image.tar .

Bu exporter'ların bir kısıtı vardır: belgelere göre varsayılan docker driver'ı oci ve docker exporter'larını desteklemez; bu çıktılar için docker-container ya da başka bir driver kullanmanız gerekir. Driver karşılaştırma tablosunda tarball çıktısının docker driver'da işaretsiz olması da bundandır. Ayrıca tar=false parametresi çıktıyı tarball yerine klasör düzeni olarak bırakır; oci-mediatypes varsayılan olarak oci için açık, docker için kapalıdır.

Image exporter parametreleri

Image exporter parametreleri: name, push, push-by-digest, registry.insecure

Image ve registry exporter'ları birçok parametre alır. Sunucu kullanımında en sık işe yarayanlar belgelerdeki tablodan şunlardır:

ParametreVarsayılanAçıklama
nameyokİmaj adı; virgülle birden fazla ad
pushfalseOluşturduktan sonra registry'ye gönder
push-by-digestfalseİmajı ad olmadan gönder
registry.insecurefalseGüvensiz registry'ye göndermeye izin ver
compressiongzipuncompressed, gzip, estargz veya zstd
oci-mediatypesfalseManifest'lerde OCI medya türlerini kullan
rewrite-timestampfalseDosya zaman damgalarını SOURCE_DATE_EPOCH değerine çek
storetrueSonucu worker'ın imaj deposuna kaydet

name parametresi --output değerinin içinde CSV olarak okunur. Bu yüzden birden fazla ad vermek istediğinizde name alanının tamamını tırnak içine almanız gerekir:

bash
docker buildx build \
    --output 'type=image,"name=registry.example.com/myapp:1.0,registry.example.com/myapp:latest",push=true' .

Aynı sonucu komut satırında --tag bayrağını tekrarlayarak da alabilirsiniz; çoğu durumda bu daha okunaklıdır. Exporter'lar ayrıca annotation.ANAHTAR=DEĞER biçiminde OCI annotation eklemeyi destekler; belgelerdeki örnek org.opencontainers.image.title annotation'ını kullanır.

Birden fazla exporter aynı anda

--output bayrağını tekrarlayarak tek bir derlemede birden fazla exporter kullanabilirsiniz. Belgelere göre bu özellik hem Buildx hem BuildKit için 0.13.0 veya üstünü gerektirir. Belgelerdeki örnek tek derlemede üç iş yapar: imajı registry'ye gönderir, sonucu yerel klasöre çıkarır ve yerel imaj deposuna yükler.

bash
docker buildx build \
  --output type=registry,tag=registry.example.com/benim/uygulama:1.0 \
  --output type=local,dest=./cikti \
  --load .

Bu kalıp, örneğin bir sürüm çıkarırken hem imajı yayımlamak hem de aynı derlemeden çıkan dosyaları sürüm notuna eklemek için kullanılabilir; derlemeyi iki kez çalıştırmanız gerekmez.

Sıkıştırma seçenekleri

Sıkıştırma seçenekleri: Fastest, 3-6 (varsayılan), Better, 9-22

Sıkıştırılmış bir çıktı üretirken algoritmayı compression, düzeyi compression-level ile seçersiniz. Belgelere göre parametreleri değiştirmek gereken depolama alanını azaltıp imaj indirme sürelerini iyileştirebilir, ama derleme süresini artırır. Düzey aralığı gzip ve estargz için 0-9, zstd için 0-22'dir; genel kural olarak sayı büyüdükçe dosya küçülür ve sıkıştırma uzar.

bash
docker buildx build \
  --output type=image,name=registry.example.com/benim/uygulama:1.0,push=true,compression=zstd .

zstd için 0-22 aralığı BuildKit içinde dört iç düzeye eşlenir. Bu yüzden komşu değerler aynı sonucu verebilir; belgelerdeki örnekte 5 ve 6 aynı çıktıyı üretir:

compression-levelİç düzeyYaklaşık zstd düzeyi
0-2Fastest1
3-6 (varsayılan)Default3
7-8Better7
9-22Best11

force-compression=true, önceki bir imajdan gelen katmanları istenen algoritma öncekinden farklıysa yeniden sıkıştırmaya zorlar. Aynı sıkıştırma ve OCI medya türü seçenekleri önbellek dışa aktarımında da kullanılır; ayrıntılar build cache yazısında.

Compose ve Bake ile çıktı

Bake hedeflerinde aynı exporter söz dizimi output özelliğiyle yazılır. Belgelerdeki bin hedefi örneğin output = ["type=local,dest=build/bin"] ile ikili dosyayı yerel klasöre çıkarır; test hedefleri ise type=cacheonly ile imaj üretmeden çalışır. Compose dosyalarında bu alanlar doğrudan build altında yoktur; Bake ile okunan Compose dosyalarında x-bake uzantısının output alanı kullanılır. Ayrıntılar docker buildx bake yazısında.

Sık yapılan hatalar

  • docker-container builder ile çıktı belirtmemek: sonuç cacheonly olarak önbellekte kalır; --load veya --push ekleyin.
  • Varsayılan driver ile oci ya da docker tarball beklemek: bu exporter'lar docker driver'da desteklenmez.
  • platform-split=false ile aynı adlı dosyalar üretmek: dışa aktarma hatayla durur; dosya adına platformu ekleyin.
  • Birden fazla imaj adını tırnaksız vermek: name alanı CSV olarak okunduğu için tüm alanı tırnaklayın ya da --tag tekrarlayın.
  • Yüksek zstd düzeyinin her zaman daha küçük dosya vereceğini sanmak: 9 ile 22 arası aynı iç düzeye eşlenir.

Sık Sorulan Sorular

docker build --output varsayılan builder ile çalışır mı?

Belgelerdeki ikili dosya örneği docker build --output=. . komutunu varsayılan kurulumla kullanır ve local exporter'ı devreye sokar. oci ve docker tarball exporter'ları ise varsayılan docker driver'da desteklenmez.

local ile tar arasındaki fark nedir?

İkisi de derlemenin kök dosya sistemini dışa aktarır. local dosyaları bir klasöre açar, tar aynı içeriği tek bir arşiv dosyasına paketler. platform-split parametresi yalnızca local'da vardır.

Test derlemesi için hangi exporter uygun?

Belgeler cacheonly exporter'ını önerir: derleme çalışır, önbellek oluşur ama hiçbir çıktı dışa aktarılmaz. Bake belgelerindeki test ve lint hedefleri de bu exporter'ı kullanır.

Aynı derlemeden hem imaj hem dosya alabilir miyim?

Evet; Buildx ve BuildKit 0.13.0 ve üstünde --output bayrağını tekrarlayarak birden fazla exporter kullanabilirsiniz.

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 · BuildKit ve Buildx · Multi-platform build · Build cache backend'leri · docker buildx bake · Dockerfile yazma rehberi