Ana içeriğe geç

Docker Build Args: Veri Profesyonelleri için Kapsamlı Rehber

Esnek, güvenli ve tutarlı ortamlar için Docker build argümanlarıyla konteynerleştirme iş akışınızı güçlendirmeyi öğrenin.
· 11 dk. oku

Yapay Zeka ile Keşfedin

Geliştirme ekibinizde tutarsız Docker build'leriyle mi uğraşıyorsunuz? Build argümanları aradığınız şey olabilir. Esnek ve standartlaştırılmış Docker imajları oluşturmak için başvurulan bir çözümdür. Değerleri build sürecinize hardcode etmeden enjekte etmenizi sağlar; bu da Dockerfile'larınızı daha taşınabilir ve bakımı kolay hale getirir.

Docker build arg'ları; farklı taban imajlarının, paket sürümlerinin veya ortamlar arası yapılandırma ayarlarının yönetilmesi gibi yaygın sorunları çözer.

Docker'ın resmi dokümantasyonu, ortam değişkenlerini yanlış kullanmak yerine build'leri parametreleştirmek için build arg'larını önerir. Aynı Dockerfile'dan farklı yapılandırmalara sahip imajlar üretmeniz gerektiği CI/CD boru hatlarında özellikle değerlidirler.

> Docker ve container dünyasına yeni misiniz? Hızlıca yol almak için rehberimizi takip edin.

Bu yazıda, Docker build argümanlarını kullanarak daha verimli, güvenli ve esnek konteynerleştirme iş akışları oluşturmayı göstereceğim.

Docker Build Arg'larına Giriş

Build argümanları (veya build arg'lar) değişkenlerdir; görüntü oluşturma sırasında Docker'a iletilir ve yalnızca imaj inşa süreci boyunca kullanılabilirler. 

Çalışma zamanında konteynerde kalıcı olan ortam değişkenlerinin aksine, build arg'lar yalnızca docker build komutunun bağlamı içinde vardır ve imajınız oluşturulduğunda ortadan kaybolurlar. Fonksiyon parametreleri gibi çalışarak her build'de farklı değerler enjekte etmenize olanak tanırlar.

Build arg'ların başlıca kullanım alanları, esnek ve yeniden kullanılabilir Dockerfile'lar oluşturmaya odaklanır. 

Build arg'ları farklı taban imajlarını belirtmek (örneğin Alpine ile Debian arasında geçiş yapmak), Dockerfile'ı değiştirmeden uygulama sürümlerini ayarlamak veya proxy sunucuları ya da depo URL'leri gibi build zamanı ayarlarını yapılandırmak için kullanabilirsiniz. Bu esneklik, dağıtım hedefine bağlı olarak aynı Dockerfile'ı farklı parametrelerle build etmeniz gereken CI/CD boru hatlarında işinize yarar.

Birden fazla Dockerfile varyantını tutmadan build'lerinizi özelleştirmeniz gerektiğinde build arg'lar parıldar. Özelleştirmeye izin verirken konteyner yapılandırma mantığınızı merkezileştirerek DRY (Kendini Tekrarlama) ilkesine uymanıza yardımcı olurlar. 

Ayrıca, geliştirme, test ve üretim ortamları arasındaki ve yalnızca imajın nasıl build edildiğini etkileyip konteynerin nasıl çalıştığını etkilememesi gereken farkları yönetmek için de idealdirler.

Artık build arg'ların ne olduğunu bildiğinize göre, nasıl kullanılacaklarını göstereyim.

Build Argümanlarını Tanımlama ve Kullanma

Şimdi build argümanlarını uygulamanın pratik yönleriyle işe koyulalım. Docker'ı kurup yapılandırdığınız varsayılmaktadır.

Temel sözdizimi ve kapsam

Dockerfile'ınızda ARG yönergesiyle build argümanları tanımlayabilirsiniz; bu yönerge, ne zaman kullanmanız gerektiğine bağlı olarak FROM yönergesinden önce veya sonra yer alabilir. Temel sözdizimi şöyledir:

# Setting a build arg with a default value
ARG VERSION=latest

# Using the build arg
FROM ubuntu:${VERSION}

İmajı build ederken --build-arg bayrağıyla değerler sağlayabilirsiniz:

docker build --build-arg VERSION=20.04 -t myapp:20.04 .

Görsel 1 - Temel Docker build arg'ları

Görsel 1 - Temel Docker build arg'ları

Build arg'ların kapsamı anlaşılması gereken belirli kuralları izler. FROM yönergesinden önce tanımlanan arg'lar yalnızca FROM'dan önce kullanılabilir ve daha sonra ihtiyaç duyarsanız yeniden tanımlanmalıdır. 

Bunun nedeni, her FROM yönergesinin kendi kapsamına sahip yeni bir build aşaması başlatmasıdır. Bu davranışı, özellikle çok aşamalı build'lerde akılda tutmak neredeyse zorunludur.

Gelişmiş bildirim teknikleri

Farklı yapılandırmaları desteklemek için build arg'ları kullanan eksiksiz bir Flask "Hello World" uygulaması oluşturalım:

> Docker kullanarak bir uygulamayı nasıl konteynerleştireceğinizi öğrenin.

Önce basit bir Flask uygulaması oluşturun (app.py):

from flask import Flask

app = Flask(__name__)


@app.route("/")
def hello_world():
    return "Hello, World!"


if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

Buradayken bir de requirements.txt dosyası oluşturun:

flask==3.1.0

Şimdi esnek yapılandırma için build arg'ları kullanan bir Dockerfile oluşturalım:

# Define build arguments with default values
ARG PYTHON_VERSION=3.13
ARG ENVIRONMENT=production

# Use the PYTHON_VERSION arg in the FROM instruction
FROM python:${PYTHON_VERSION}-slim

# Redeclare args needed after FROM
ARG ENVIRONMENT
ENV FLASK_ENV=${ENVIRONMENT}

# Set working directory
WORKDIR /app

# Copy requirements file
COPY requirements.txt .

# Install dependencies based on environment
RUN if [ "$ENVIRONMENT" = "development" ]; then \
      pip install -r requirements.txt && \
      pip install pytest black; \
    else \
      pip install --no-cache-dir -r requirements.txt; \
    fi

# Copy application code
COPY . .

# Expose port
EXPOSE 5000

# Set default command
CMD ["python", "app.py"]

> Yukarıdaki Dockerfile size karmaşık mı görünüyor? Rehberimizle sıfırdan Docker öğrenin.

Bu imajı belirli bir Python sürümüyle geliştirme için build etmek üzere Terminal'den şunları çalıştırabilirsiniz:

# Building for development with Python 3.11
docker build \
  --build-arg PYTHON_VERSION=3.11 \
  --build-arg ENVIRONMENT=development \
  -t flaskapp:dev .

Görsel 2 - Basit bir Python uygulamasında build arg'lar

Görsel 2 - Basit bir Python uygulamasında build arg'lar

Çok aşamalı build'lerde build arg'ların özel bir şekilde ele alınması gerekir. Flask uygulamamızla birden çok aşamadan argümanların nasıl geçirileceğini gösteren tam bir örnek şöyledir:

# Dockerfile for a multi-stage build
ARG PYTHON_VERSION=3.13

# Build stage
FROM python:${PYTHON_VERSION}-slim AS builder
ARG ENVIRONMENT=production
ENV FLASK_ENV=${ENVIRONMENT}

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .
# In a real app, you might run tests or build assets here
RUN echo "Building Flask app for ${ENVIRONMENT}"

# Production stage
FROM python:${PYTHON_VERSION}-slim
ARG ENVIRONMENT
ENV FLASK_ENV=${ENVIRONMENT}

WORKDIR /app
COPY --from=builder /usr/local/lib/python*/site-packages /usr/local/lib/python*/site-packages
COPY --from=builder /app .

# Add metadata based on build args
LABEL environment="${ENVIRONMENT}" \
      python_version="${PYTHON_VERSION}"

EXPOSE 5000
CMD ["python", "app.py"]

Artık bunu belirli Python sürümü ve ortamla build edebilirsiniz:

docker build \
  --build-arg PYTHON_VERSION=3.12 \
  --build-arg ENVIRONMENT=staging \
  -t flaskapp:staging .

Görsel 3 - Çok aşamalı build'lerde build arg'lar

Görsel 3 - Çok aşamalı build'lerde build arg'lar

Kısacası, bu yaklaşım build'inizin tüm aşamalarında tutarlı bir yapılandırmayı korumanızı sağlar.

Ön tanımlı build argümanları

Docker, önceden tanımlanmış ve önceden bildirmeden kullanabileceğiniz birkaç build arg sağlar. Bunlar şunlardır:

  • HTTP_PROXY ve HTTPS_PROXY: Proxy sunucularının bulunduğu kurumsal ortamlardaki build'ler için faydalıdır.
  • FTP_PROXY: HTTP proxy'lerine benzer ancak FTP bağlantıları içindir.
  • NO_PROXY: Proxy'yi atlaması gereken ana bilgisayarları belirtir.
  • BUILD_DATE ve VCS_REF: Genellikle imaj metaverisi ve versiyonlama için kullanılır.

Bu ön tanımlı arg'lar, belirli ağ yapılandırmalarının olduğu ortamlarda build yaparken kullanışlıdır. Örneğin, katı proxy gereksinimleri olan bir kurumsal ağda şunu kullanabilirsiniz:

docker build --build-arg HTTP_PROXY=http://proxy.example.com:8080 .

Bu yaklaşım Dockerfile'ınızı taşınabilir tutarken kısıtlı ortamlarda da çalışmasını sağlar.

Güvenlik Etkileri ve Risk Azaltma

Build argümanları esneklik sağlasa da, Docker imajlarınızı güvenli tutmak için anlamanız gereken potansiyel güvenlik risklerini de beraberinde getirirler.

Argüman sızıntısı vektörleri

Build arg'lar düşündüğünüz kadar gizli değildir. Birçok geliştiricinin gözden kaçırdığı birkaç vektör üzerinden build arg değerleri sızabilir. İlk olarak, Docker imaj geçmişi tüm build arg'larınızı ortaya çıkarır; yani imajınıza erişimi olan herkes build sırasında kullandığınız değerleri, API anahtarları veya belirteçler gibi hassas bilgiler dahil, görmek için docker history çalıştırabilir.

docker history flaskapp:dev

Görsel 4 - Docker history

Görsel 4 - Docker history

Ara katmanlar da build argümanlarını sızdırabilir. Çok aşamalı bir build kullansanız ve hassas bilgileri içeren katmanı kopyalamasanız bile, build arg değerleri build makinesindeki katman önbelleğinde kalır. Bu, build sunucunuzdaki Docker daemon'ına erişimi olan herkesin bu bilgileri potansiyel olarak çıkarabileceği anlamına gelir.

CI/CD günlükleri de önemli bir risk oluşturur. Çoğu CI/CD sistemi, komut satırında geçirilen build arg'lar dahil olmak üzere tüm build komutunu günlüğe kaydeder.

Örneğin, API_KEY dahil bu komutun tamamı CI/CD günlüklerinde görünecektir:

docker build --build-arg API_KEY=secret123 -t myapp:latest .

Bu günlükler genellikle daha geniş bir geliştirici grubunun erişimine açıktır veya üçüncü taraf sistemlerde saklanır; bu da hassas değerlerin maruz kalma yüzeyini artırır.

Güvenli alternatifler

Hassas bilgiler için build arg'lar yerine Docker BuildKit'in secrets özelliğini kullanmalısınız. BuildKit, build süreci sırasında sırları mount etmenize ve bunları nihai imajda veya geçmişte kalıcı hale getirmemenize olanak tanır.

İşte Docker BuildKit secrets kullanan örnek bir Dockerfile:

FROM python:3.13-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .

# Use secret mount instead of build arg
RUN --mount=type=secret,id=api_key \
    cat /run/secrets/api_key > api_key.txt

EXPOSE 5000
CMD ["python", "app.py"]

Bu imajı bir sır ile build etmek için önce api_key.txt dosyasını oluşturun:

echo "my-secret-api-key" > api_key.txt

Ardından imajı sır ile build edin:

DOCKER_BUILDKIT=1 docker build \
  --secret id=api_key,src=api_key.txt \
  -t flaskapp:secure .

Görsel 5 - BuildKit secrets ile imaj oluşturma

Görsel 5 - BuildKit secrets ile imaj oluşturma

Çalışma zamanında erişilebilir olması gereken yapılandırmalar için ortam değişkenleri tercih edilen yaklaşımdır. İmajın içine gömmeden konteyneri başlatırken ayarlanabilirler:

# Set environment variables at runtime
docker run -e API_KEY=secret123 -p 5000:5000 flaskapp:latest

Üretimde hassas yapılandırmaları güvenli bir şekilde ele almak için, hassas bilgileri yönetmek üzere Secrets gibi güvenli yöntemler sağlayan Kubernetes gibi konteyner orkestrasyon platformlarını kullanmayı düşünün. Docker Swarm da sır yönetimiyle benzer yetenekler sunar.

> Docker tek konteynerleştirme platformu değildir. Podman hakkında okuyarak hangisinin size daha uygun olduğunu öğrenin.

Unutmayın, temel kural şudur: hassas olmayan build zamanı yapılandırma için build arg'ları kullanın; hassas build zamanı ihtiyaçlar için BuildKit secrets kullanın; çalışma zamanı yapılandırması için ise ortam değişkenleri veya orkestrasyon platformu sırlarını kullanın.

Konteyner Ekosistemleriyle Entegrasyon

Artık temeller geride kaldığına göre, build arg'ları daha geniş Docker ekosistemlerinde ve modern build araçlarında nasıl değerlendirebileceğimize bakalım.

Docker Compose

Docker Compose, çok konteynerli uygulamalarınız genelinde build arg'ları tanımlamayı ve paylaşmayı kolaylaştırır.

Takip etmek isterseniz, iki basit Flask servisi için tam proje yapısı şu şekildedir:

flask-project/
├── docker-compose.yml         # Main compose configuration
├── .env                       # Environment variables for compose
├── web/
│   ├── Dockerfile             # Web service Dockerfile
│   ├── app.py                 # Flask application
│   └── requirements.txt       # Python dependencies
├── api/
│   ├── Dockerfile             # API service Dockerfile
│   ├── app.py                 # API Flask application  
│   └── requirements.txt       # API dependencies

Dosya içeriklerini kısaca tek tek üzerinden geçeceğim:

web/app.py

from flask import Flask, render_template

app = Flask(__name__)


@app.route("/")
def index():
    return render_template("index.html", title="Flask Web App")


@app.route("/about")
def about():
    return "About page - Web Service"


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=True)

web/requirements.txt

flask==3.1.0

web/Dockerfile

# Web service Dockerfile
ARG PYTHON_VERSION=3.13

FROM python:${PYTHON_VERSION}-slim

# Redeclare the build arg to use it after FROM
ARG PYTHON_VERSION
ARG ENVIRONMENT=production

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV FLASK_ENV=${ENVIRONMENT}

WORKDIR /app

# Copy and install requirements
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY . .

# Create a simple template folder and file if not exists
RUN mkdir -p templates && \
    echo "<html><body><h1>Hello from Web Service</h1><p>Python version: ${PYTHON_VERSION}</p><p>Environment: ${ENVIRONMENT}</p></body></html>" > templates/index.html

EXPOSE 5000

CMD ["python", "app.py"]

api/app.py

from flask import Flask, jsonify

app = Flask(__name__)


@app.route("/api/health")
def health():
    return jsonify({"status": "healthy"})


@app.route("/api/data")
def get_data():
    return jsonify(
        {"message": "Hello from the API service", "items": ["item1", "item2", "item3"]}
    )


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000, debug=True)

api/requirements.txt

flask==3.1.0

api/Dockerfile

ARG PYTHON_VERSION=3.13

FROM python:${PYTHON_VERSION}-slim

# Redeclare the build arg to use it after FROM
ARG PYTHON_VERSION
ARG ENVIRONMENT=production

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV FLASK_ENV=${ENVIRONMENT}

WORKDIR /app

# Copy and install requirements
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY . .

# Add metadata label based on build args
LABEL python.version="${PYTHON_VERSION}" \
      app.environment="${ENVIRONMENT}"

EXPOSE 8000

CMD ["python", "app.py"]

.env

PYTHON_VERSION=3.10
ENVIRONMENT=development

docker-compose.yml

services:
  web:
    build:
      context: ./web
      dockerfile: Dockerfile
      args:
        PYTHON_VERSION: ${PYTHON_VERSION:-3.13}
        ENVIRONMENT: ${ENVIRONMENT:-development}
    ports:
      - "5000:5000"
    depends_on:
      - api
    
  api:
    build:
      context: ./api
      dockerfile: Dockerfile
      args:
        PYTHON_VERSION: ${PYTHON_VERSION:-3.13}
        ENVIRONMENT: ${ENVIRONMENT:-production}
    ports:
      - "8000:8000"

Özetle, bu, birbirinden izole ortamlarda iki uygulamayı aynı anda, belirli bir build arg setiyle başlatmanın gerçekten basit bir yoludur.

Çok konteynerli kurulumu çalıştırmak için bu komutu kullanabilirsiniz:

docker compose up --build

Görsel 6 - Docker Compose ile build arg'lar

Görsel 6 - Docker Compose ile build arg'lar

Birkaç saniye sonra her iki servisin de çalıştığını göreceksiniz:

Görsel 7 - Docker Compose ile build arg'lar (2)

Görsel 7 - Docker Compose ile build arg'lar (2)

Bu iki uygulama kadar basit olanlar için oldukça detaylı bir kurulum, ancak büyük resim net—build arg'lar compose dosyasında ayarlanır ve bireysel Dockerfile'larda referans verilir.

Ayrıca, ortamınızdan build arg'lara değişken değerleri de geçirebilirsiniz; bu, CI/CD boru hatları için kullanışlıdır:

services:
  web:
    build:
      context: .
      args:
        - PYTHON_VERSION=${PYTHON_VERSION:-3.10}

docker-compose çalıştırırken bu değerleri geçersiz kılmak için ortam değişkenlerini kullanabilirsiniz:

PYTHON_VERSION=3.10 docker-compose up --build

Bu yaklaşım, ihtiyaç duyulduğunda esneklik sunarken ekibiniz genelinde tutarlı build'ler sürdürmenizi sağlar.

BuildKit özellikleri

Docker'ın modern build motoru BuildKit, build sürecinizi build arg'ları çok daha güçlü kılan özelliklerle hızlandırır. BuildKit'i etkinleştirdiğinizde (DOCKER_BUILDKIT=1 ayarlayarak) birkaç yeni yetenek açılır.

Inline cache, uzak imajın build önbelleğinden yararlanarak build performansını artırır. --cache-from bayrağıyla önbellek olarak kullanılacak bir kaynak imaj belirtebilir ve BuildKit bu imajın katmanlarını akıllıca kullanır:

DOCKER_BUILDKIT=1 docker build \
  --build-arg PYTHON_VERSION=3.10 \
  --cache-from flaskapp:dev \
  -t flaskapp:latest .

Bir diğer değerli BuildKit özelliği de belirlenebilir çıktı (deterministic outputs) olup build'lerinizin tekrarlanabilir olmasını sağlar. Nerede veya ne zaman build edildiğinden bağımsız olarak tam olarak aynı imajı istediğinizde bu kritik öneme sahiptir:

# Build with deterministic output
DOCKER_BUILDKIT=1 docker build \
  --build-arg PYTHON_VERSION=3.10 \
  --build-arg BUILD_DATE=2025-05-01 \
  --output type=docker,name=flaskapp:stable \
  .

BuildKit'in günlüklerde sırları maskelemesi (secret redaction) build'ler sırasında hassas bilgileri korur. 

Build arg'ların aksine, ki bunların değerleri build günlüklerinde görünür, BuildKit sırların değerlerini otomatik olarak gizler:

# Create a file with the API key
echo "my-api-key-value" > ./api-key.txt

# Build with secret (value won't appear in logs)
DOCKER_BUILDKIT=1 docker build \
  --secret id=api_key,src=./api-key.txt \
  -t flaskapp:secure .

Dockerfile'ınızda bu sırrı şöyle erişirsiniz:

RUN --mount=type=secret,id=api_key \
    cat /run/secrets/api_key > /app/config/api_key.txt

Bu BuildKit özellikleri, neredeyse her türlü konteynerleştirme iş akışına uyum sağlayabilen daha güvenli, verimli ve tekrarlanabilir bir build sistemi oluşturmak için build arg'larla birlikte çalışır.

Kurumsal Benimseme için En İyi Uygulamalar

Docker build arg'larını büyük ekipler genelinde uygulamak, en azından kafa karışıklığını en aza indirmek ve güvenlik ile performans faydalarını en üst düzeye çıkarmak için standartlaştırılmış yaklaşımlar gerektirir.

Kurumsal ortamlarda build arg'ları benimserken uygun argüman doğrulamasıyla başlayın. 

Her build argümanı için makul varsayılan değerler sağlayarak, argümanlar iletilmediğinde build'lerin beklenmedik şekilde başarısız olmasını önleyin. Ayrıca kritik build arg'ların gereksinimlerinizi karşıladığını doğrulamak için Dockerfile içinde doğrulama kontrolleri eklemelisiniz.

Python sürümü doğrulayan bir örnek şöyledir:

ARG PYTHON_VERSION=3.9
# Validate Python version
RUN if [[ ! "$PYTHON_VERSION" =~ ^3\.[0-9]+$ ]]; then \
      echo "Invalid Python version: ${PYTHON_VERSION}. Must be 3.x"; \
      exit 1; \
    fi

Katman önbelleklemesini optimize etmek, CI/CD boru hatlarında build sürelerini azaltmak için kritik öneme sahiptir. 

Dockerfile yönergelerinizi, nadiren değişen içerikleri (bağımlılık kurulumu gibi) daha sık değişen içeriklerden (uygulama kodu gibi) önce yerleştirerek önbellek isabetlerini en üst düzeye çıkaracak şekilde sıralayın. 

Sık değişebilecek build arg'ları kullanırken, tüm önbelleği geçersiz kılmamak için bunları istikrarlı işlemlerden sonra yerleştirin:

FROM python:3.13-slim

WORKDIR /app

# Dependencies change less frequently - good cache utilization
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Build args that might change often come AFTER stable operations
ARG BUILD_NUMBER
ARG COMMIT_SHA
# Now these args won't invalidate the dependency cache

Build arg'lar aracılığıyla metaveri yönetimi, izlenebilirliği ve uyumluluğu artırır. Build zamanı metaveriyi etiketler olarak enjekte etmek için build arg'ları kullanın:

ARG BUILD_DATE
ARG VERSION
ARG COMMIT_SHA
ARG BUILD_URL

LABEL org.opencontainers.image.created="${BUILD_DATE}" Can you please provide me with access to this document?
      org.opencontainers.image.version="${VERSION}" \
      org.opencontainers.image.revision="${COMMIT_SHA}" \
      org.opencontainers.image.url="${BUILD_URL}"

Bu standartlaştırılmış etiketler Open Container Initiative (OCI) spesifikasyonunu takip eder; bu da imajlarınızın farklı konteyner yönetim araçlarıyla uyumlu olacağı anlamına gelir.

Dokümantasyon sıklıkla göz ardı edilir, ancak kurumsal benimseme için kritiktir. 

Tüm mevcut build arg'ları, amaçlarını, varsayılan değerlerini ve kullanım örneklerini belgeleyen net bir README bölümü oluşturun. Hangi build arg'ların zorunlu hangilerinin isteğe bağlı olduğunu ve farklı argümanlar arasındaki etkileşimleri dahil edin. Geliştiricilerin hangi değerleri sağlamaları gerektiğini anlamalarına yardımcı olmak için bu bilgileri CI/CD boru hattı yapılandırma dosyalarınıza yorum olarak eklemeyi de düşünün:

# Example documented CI configuration
build_job:
  script:
    # BUILD_NUMBER: Unique identifier for this build (required)
    # ENVIRONMENT: Target deployment environment [dev|staging|prod] (required)
    # PYTHON_VERSION: Python version to use (optional, default: 3.9)
    - docker build
      --build-arg BUILD_NUMBER=${CI_PIPELINE_ID}
      --build-arg ENVIRONMENT=${DEPLOY_ENV}
      --build-arg PYTHON_VERSION=${PYTHON_VERSION:-3.9}
      -t myapp:${CI_PIPELINE_ID} .

Gerçek anlamda kurumsal düzeyde benimseme için, sürümlendirilebilen ve doğrulanabilen bir build argüman şeması uygulamayı düşünün. Bu yaklaşım, geriye dönük uyumluluğu korurken build yapılandırmanızı zaman içinde evrimleştirmenize olanak tanır.

Karşılaştırmalı Analiz: Build Arg'lar vs. Ortam Değişkenleri

En iyi uygulamalara uygun, güvenli ve esnek Docker imajları oluşturmak istiyorsanız, build arg'ları ne zaman ve ortam değişkenlerini ne zaman kullanmanız gerektiğini anlamalısınız.

İstediğiniz zaman başvurabileceğiniz bir tablo şöyledir:

Özellik

Build argümanları

Ortam değişkenleri

Kullanılabilirlik

Yalnızca imaj build'i sırasında kullanılabilir

Hem build hem de konteyner çalışma zamanında kullanılabilir

Kalıcılık

Nihai imajda kalıcı değildir (ENV'e açıkça dönüştürülmedikçe)

İmajda kalıcıdır ve çalışan konteynerlere sunulur

Güvenlik

docker history ile imaj geçmişinde görünür

İmaj geçmişinde görünmez ancak konteyner içindeki süreçlerce erişilebilir

Kullanım

Sürümler, build yolları, derleyici bayrakları gibi build zamanı yapılandırmaları için idealdir

Bağlantı dizeleri, özellik bayrakları, günlük seviyeleri gibi çalışma zamanı yapılandırmaları için idealdir

Bildirim

Dockerfile'da ARG yönergesiyle tanımlanır

Dockerfile'da ENV yönergesiyle veya çalışma zamanında tanımlanır

Varsayılan değerler

Varsayılan değer verilebilir: ARG VERSION=latest

Varsayılan değer verilebilir: ENV MODE=production

Kapsam

Her build aşamasıyla sınırlıdır; her FROM'dan sonra yeniden bildirilmelidir

Tüm build aşamalarında kullanılabilir ve alt imajlarca devralınır

Geçersiz kılma yöntemi

--build-arg build zamanı sırasında

-e veya --env konteyner çalışma zamanında

Temel fark zamanlama ve amaçta yatar. Build arg'lar bizzat build sürecini yapılandırırken, ortam değişkenleri çalışan uygulamayı yapılandırır. Örneğin, hangi taban imajın kullanılacağını seçmek için build arg kullanırsınız (ARG PYTHON_VERSION=3.10), ancak uygulamanıza hangi portu dinleyeceğini söylemek için ortam değişkeni kullanırsınız (ENV PORT=8080).

Güvenlik açısından, build arg'lar daha yüksek risk taşır; çünkü imaj geçmişinde kalırlar. 

Farklı türdeki yapılandırmaları ele almak için şu iş akışını düşünün:

# Build-time configuration (non-sensitive)
ARG PYTHON_VERSION=3.13
FROM python:${PYTHON_VERSION}-slim

# Build-time secrets (use BuildKit secrets)
RUN --mount=type=secret,id=build_key \
    cat /run/secrets/build_key > /tmp/key && \
    # Use the secret for build operations
    rm /tmp/key

# Runtime configuration (non-sensitive)
ENV LOG_LEVEL=info

# Runtime secrets (should be injected at runtime, not here)
# This would be provided at runtime with:
# docker run -e API_KEY=secret123 myimage

Pratikte, bazı build arg'ları çalışma zamanında kullanılmaları gerektiğinde ortam değişkenlerine dönüştürmek yaygın bir desendir:

ARG APP_VERSION=1.0.0
# Make the version available at runtime
ENV APP_VERSION=${APP_VERSION}

Kurumsal uygulamalarda bu ayrım, uygulamanın yaşam döngüsünün farklı yönlerinin farklı ekiplerce yönetilmesine olanak tanır. DevOps ekipleri imaj inşası için build arg'ları değiştirebilirken, operasyon ekipleri imajları yeniden build etmeden dağıtım sırasında ortam değişkenlerini ayarlayabilir.

Docker Build Arg'larını Özetleme

Docker build arg'ları yalnızca bir teknik özellik değildir - ekipleriniz ve ortamlarınız genelinde tutarlı şekilde çalışan imajlar oluşturmak için başlıca aracınızdır. 

Onları basit Python projelerinde nasıl kullanacağınızı, hassas bilgilerinizi güvende tutarken nasıl yöneteceğinizi anlattım. Ayrıca build arg'ları Docker Compose gibi araçlarla nasıl entegre edeceğinizi gördünüz.

Build arg'ları, esnek bir konteynerleştirme stratejisinin temeli olarak düşünün. Bir sonraki projenizde Python sürümünü parametreleştirerek küçük başlayın. Buna alıştıktan sonra farklı ortamlar için koşullu mantık eklemeyi deneyin. Farkına varmadan, ekibinizin Dockerfile'ı değiştirmeden özelleştirebileceği gelişmiş çok aşamalı build'ler oluşturuyor olacaksınız.

Daha derine inmeye hazır mısınız? DataCamp'teki şu kurslar bir sonraki en iyi durağınız olacaktır:

FAQs

Docker build argümanları nedir?

Docker build argümanları (build arg'lar), yalnızca imaj inşası sırasında kullanılabilen ve Docker build sürecine ilettiğiniz değişkenlerdir. Dockerfile'ı değiştirmeden özelleştirmenize olanak tanır; böylece konteyner build'leriniz daha esnek ve yeniden kullanılabilir hale gelir. Onları her imaj build'inde ayarlayabileceğiniz parametreler olarak düşünün; farklı ortamları veya yapılandırmaları yönetmek için idealdirler.

Docker'da build arg'lar ortam değişkenlerinden nasıl farklıdır?

Build arg'lar yalnızca imaj inşası sırasında vardır, ortam değişkenleri ise çalışan konteynerde kalıcıdır. Build arg'lar Dockerfile'da ARG yönergesiyle tanımlanır ve build sırasında --build-arg ile iletilir; bu da taban imaj seçimi veya build zamanı yapılandırmalar için idealdir. Ortam değişkenleri ise ENV ile tanımlanır ve çalışma zamanında uygulamanızın ihtiyaç duyduğu yapılandırmalar için tasarlanmıştır.

Docker build arg'larını kullanırken hangi güvenlik endişelerinin farkında olmalıyım?

Build arg'lar birçok geliştiricinin sandığı kadar gizli değildir—değerleri imaj geçmişinde ve CI/CD günlüklerinde görünür. API anahtarları veya parolalar gibi hassas bilgiler için asla build arg kullanmayın; zira imajınıza erişimi olan herkes bu değerlere ulaşabilir. Hassas veriler için nihai imaja veya geçmişe kalıcı olmayan Docker BuildKit secrets kullanın.

GitHub Actions gibi CI/CD boru hatları üzerinden build arg'ları nasıl iletebilirim?

Çoğu CI/CD platformu, yapılandırma dosyaları aracılığıyla Docker build arg'larını destekler. GitHub Actions'ta, workflow YAML'ında docker/build-push-action altında build-args parametresiyle build arg'ları iletebilirsiniz. Güvenlik ihtiyaçlarınıza bağlı olarak ortam değişkenlerine, depo sırlarına veya sabit değerlere referans verebilirsiniz. Bu sayede dal, ortam veya diğer CI değişkenlerine göre farklı yapılandırmalarla build'leri otomatikleştirebilirsiniz.

Bir Dockerfile'da kaç tane build arg kullanabileceğime dair bir sınır var mı?

Build arg sayısında katı bir teknik sınır yoktur, ancak çok fazla kullanmak Dockerfile'ınızı anlamayı ve sürdürmeyi zorlaştırabilir. Veri bilimi projelerinde Python sürümü, çatı seçimleri veya veri kümesi yapılandırmaları gibi kritik değişkenleri parametreleştirmeye odaklanın. 8-10'dan fazla build arg'a ihtiyaç duyduğunuzu fark ederseniz, Dockerfile'ınızı daha küçük ve odaklı dosyalara bölmeyi veya karmaşıklığı yönetmek için Docker Compose kullanmayı düşünün.

Dario Radečić

Yazar

Dario Radečić

Hırvatistan merkezli Kıdemli Veri Bilimci. 700’ün üzerinde yayımlanmış makaleyle 10 M+ görüntüleme elde eden, önde gelen bir teknoloji yazarı. TPOT ile Makine Öğrenimi Otomasyonu kitabının yazarı.

Konular

İlgili