0Pricing
Linux Command Line & Bash Scripting Mastery · Ders

Yalın Dockerfile'lar ve Kabuk Giriş Noktaları Yazma

Sinyal işleme ve yapılandırma şablonlaması içeren çok aşamalı derleme betikleri ile sağlam giriş noktası uyarlayıcıları yazın.

Yalın Dockerfile'lar ve Kabuk Giriş Noktaları Yazma, CoddyKit'te ücretsiz bir Linux Command Line & Bash Scripting Mastery dersidir. Bu, 4 dersinin 1. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Linux Command Line & Bash Scripting Mastery öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Linux Command Line & Bash Scripting Mastery kursu toplamda 4 dersten oluşur.

Yalın Dockerfile'lar DevOps için neden önemlidir

Üretim ortamlarında bir Docker imajındaki her megabaytın bir maliyeti vardır: daha yavaş indirme, daha geniş saldırı yüzeyi ve israf edilen kayıt deposu alanı. Sağlam kabuk başlatma noktalarıyla birleştirilmiş yalın Dockerfile'lar, olgun DevOps uygulamalarının ayırt edici özelliklerindendir.

  • Çok aşamalı derlemeler, derleme zamanındaki araçları son çalışma zamanı imajından ayırarak boyutu büyük ölçüde azaltır.
  • Başlatma noktası aracı komut dosyaları, kapsayıcıları başlatan küçük kabuk komut dosyalarıdır: yapılandırma dosyalarına şablon uygular, ortam değişkenlerini doğrular, sinyalleri işler ve son olarak ana süreci exec ile çalıştırır.
  • Birlikte, Kubernetes, ECS ve çıplak metal ortamlarındaki güvenilir ve taşınabilir kapsayıcı iş yüklerinin temelini oluştururlar.

Bu derste her iki uygulama alanı da uçtan uca ele alınır; doğrudan işlem hatlarınıza ekleyebileceğiniz üretim kalitesinde kalıplar sunulur.

Çok Aşamalı Bir Dockerfile'ın Anatomisi

Çok aşamalı bir Dockerfile, birden fazla FROM yönergesi kullanır. Her aşama yalıtılmış bir katman kümesidir; yalnızca ihtiyaç duyduğunuz yapıtları bir sonraki aşamaya kopyalarsınız.

  • Aşama 0 (builder): derleyicileri, test çalıştırıcılarını ve derleme bağımlılıklarını kurar.
  • Aşama 1 (runtime): en küçük temel imajdan (ör. alpine, distroless) başlar ve yalnızca derlenmiş ikili dosyaları veya uygulama paketlerini kopyalar.
  • Son imajda, açıkça kopyalamadığınız sürece gcc, make veya kaynak kodu bulunmaz.

Aşamaların sınırları arasında dosya almak için COPY içinde --from=<stage> kullanın. Okunabilirlik ve docker build --target ile belirli bir aşamayı seçebilmek için aşamaları AS <name> ile adlandırın.

# ---- Stage 0: builder ----
FROM golang:1.22-alpine AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags='-s -w' -o /app/server ./cmd/server

# ---- Stage 1: runtime ----
FROM gcr.io/distroless/static-debian12
COPY --from=builder /app/server /server
ENTRYPOINT ["/server"]

Katmanları Küçültme ve Önbelleği Geçersiz Kılma

Her RUN, COPY ve ADD yönergesi yeni bir katman oluşturur. Yönergelerin kötü sıralanması, derleme önbelleğini gereksiz yere geçersiz kılar ve CI işlem hatlarını yavaşlatır.

  • Bağımlılık bildirimlerini (package.json, go.mod, requirements.txt) kaynak kodunu kopyalamadan önce kopyalayın; böylece bağımlılık kurulumu bağımsız olarak önbelleğe alınır.
  • İlişkili komutları && ile zincirleyin ve ara katmanlarda paket önbelleği bırakmamak için temizleme işlemini aynı RUN katmanında yapın.
  • Paket yöneticilerinde --no-cache kullanın ve kurulumdan sonra liste dosyalarını kaldırın.
FROM python:3.12-slim AS builder
WORKDIR /app

# 1. Install deps first (cached until requirements change)
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt

# 2. Copy source (cache busted only when code changes)
COPY src/ ./src/

FROM python:3.12-slim
COPY --from=builder /install /usr/local
COPY --from=builder /app/src /app/src
WORKDIR /app
CMD ["python", "-m", "src.main"]

BuildKit Gizli Bilgileri ve SSH Yönlendirmesi

Özel kayıt depoları, SSH anahtarları ve API belirteçleri imaj katmanlarında asla görünmemelidir. Docker BuildKit iki güvenli mekanizma sağlar:

  • --secret: gizli bir dosyayı tek bir RUN adımı içinde bağlar, ancak katmana kalıcı olarak eklemez. /run/secrets/<id> üzerinden erişin.
  • --ssh: özel anahtarları imaja gömmeden kimlik doğrulaması yapabilmesi için ana makinenin SSH aracısı yuvasını derleme ortamına yönlendirir.

BuildKit'i DOCKER_BUILDKIT=1 ile veya docker buildx build aracılığıyla etkinleştirin. # syntax=docker/dockerfile:1 yönergesi bu özelliklerin kullanılmasını sağlar.

# syntax=docker/dockerfile:1
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./

# Mount NPM token as a secret — never stored in the image
RUN --mount=type=secret,id=npm_token \
    NPM_TOKEN=$(cat /run/secrets/npm_token) \
    npm ci --prefer-offline

# Usage at build time:
# DOCKER_BUILDKIT=1 docker build \
#   --secret id=npm_token,src=~/.npmrc-token \
#   -t myapp:latest .

Sağlam Bir Başlatma Noktası Aracı Komut Dosyası Yazma

Başlatma noktası aracı komut dosyası, Dockerfile içinde ENTRYPOINT olarak ayarlanan bir kabuk komut dosyasıdır. Görevi, denetimi ana sürece devretmeden önce çalışma zamanı ortamını hazırlamaktır.

İyi yapılandırılmış bir aracı komut dosyası şu sırayı izler:

  • 1. adım: Herhangi bir hatanın işlemi erkenden durdurması için set -euo pipefail ayarlanır.
  • 2. adım: Gerekli ortam değişkenleri doğrulanır ve yararlı bir iletiyle hızlıca hata verilir.
  • 3. adım: Ortam değişkenlerinden yapılandırma dosyalarına şablon uygulanır.
  • 4. adım: Düzgün kapatma için sinyal işleyicileri kaydedilir.
  • 5. adım: exec "$@" — kabuk ana süreçle değiştirilir; böylece PID 1 aracı komut dosyası değil, uygulama olur.

Son exec kritik öneme sahiptir: bu komut olmadan Kubernetes veya Docker çalışma zamanı tarafından gönderilen sinyaller alt sürece iletilmez.

#!/usr/bin/env bash
set -euo pipefail

# Step 2: validate required env vars
REQUIRED_VARS=(DATABASE_URL APP_SECRET PORT)
for var in "${REQUIRED_VARS[@]}"; do
  if [[ -z "${!var:-}" ]]; then
    echo "[entrypoint] ERROR: required env var '$var' is not set" >&2
    exit 1
  fi
done

# Step 3: template config (see next scene)

# Step 4: signal handling (see scene after that)

# Step 5: hand off to CMD
exec "$@"

envsubst ile Yapılandırmaya Şablon Uygulama

envsubst (GNU gettext paketinden gelir ve Alpine'de gettext olarak bulunur), bir şablon dosyasındaki ${VAR} yer tutucularını mevcut ortam değişkeni değerleriyle değiştirir.

  • İmajla birlikte bir *.tmpl yapılandırma şablonu gönderin; başlatma noktası bunu başlangıçta oluşturur.
  • İlişkisiz dolar işaretlerinin (ör. nginx düzenli ifadesindeki işaretlerin) yanlışlıkla genişletilmemesi için değişken listesini açıkça envsubst'a geçirin.
  • Oluşturulan dosyayı /tmp gibi yazılabilir bir yola veya özel bir yapılandırma birimine yazın.
#!/usr/bin/env bash
# Template: /etc/nginx/conf.d/app.conf.tmpl contains:
# server { listen ${NGINX_PORT}; server_name ${SERVER_NAME}; ... }

export NGINX_PORT=${NGINX_PORT:-8080}
export SERVER_NAME=${SERVER_NAME:-localhost}

envsubst '${NGINX_PORT} ${SERVER_NAME}' \
  < /etc/nginx/conf.d/app.conf.tmpl \
  > /etc/nginx/conf.d/app.conf

echo "[entrypoint] nginx config rendered:"
grep -E 'listen|server_name' /etc/nginx/conf.d/app.conf

exec "$@"

Sinyal İşleme ve Düzgün Kapatma

Kapsayıcılar Kubernetes, ECS veya docker stop tarafından durdurulduğunda SIGTERM alır. Başlatma noktası aracı komut dosyanız PID 1 konumundaysa ve sinyalleri iletmiyorsa, ana süreç bekleme süresinden sonra SIGKILL ile sonlandırılır; bu da isteklerin kaybolmasına veya verilerin bozulmasına yol açabilir.

  • Aracı komut dosyasında SIGTERM ve SIGINT sinyallerini yakalamak için trap kullanın.
  • Sinyali kill -TERM "$child" ile alt sürecin PID'sine iletin.
  • Alt süreç çıkana kadar beklemek ve ardından çıkış kodunu aktarmak için wait "$child" kullanın.
  • Alternatif olarak, kabuğu tamamen değiştirmek için exec kullanabilirsiniz; bu durumda işletim sistemi sinyalleri doğrudan alt sürece iletir ve trap gerekmez. Basit durumlarda tercih edilen kalıp budur.
#!/usr/bin/env bash
set -euo pipefail

# Start main process in background
"$@" &
child=$!

# Forward SIGTERM and SIGINT to the child
trap 'echo "[entrypoint] caught SIGTERM, forwarding..."; kill -TERM "$child"' TERM
trap 'echo "[entrypoint] caught SIGINT, forwarding...";  kill -INT  "$child"' INT

# Wait for child to exit and capture its exit code
wait "$child"
exit $?

En Küçük Başlatma Süreci Olarak tini Kullanma

Kapsayıcınız alt süreçler oluşturduğunda (ör. çalışanları çatallayan bir kabuk), zombi süreçleri toplamak için gerçek bir başlatma sürecine ihtiyaç duyarsınız. tini, özellikle kapsayıcılar için tasarlanmış küçük bir başlatma ikilisidir.

  • İmajınıza tini ekleyin ve bunu başlatma noktası sarmalayıcısı olarak ayarlayın.
  • Zombi alt süreçleri toplar, sinyalleri doğru şekilde iletir ve alt sürecin durum koduyla çıkar.
  • Docker, docker run --init ile etkinleştirilen yerleşik bir tini sunar; ancak bunu imaja gömmek, davranışın farklı çalışma zamanlarında (Kubernetes, ECS vb.) tutarlı olmasını sağlar.
FROM node:20-alpine

# Install tini for proper signal handling and zombie reaping
RUN apk add --no-cache tini

WORKDIR /app
COPY --chown=node:node . .
RUN npm ci --omit=dev

USER node

# tini wraps CMD; forwards SIGTERM and reaps zombies
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "server.js"]

Kök Kullanıcı Olmadan Çalıştırma

root olarak (UID 0) çalışan kapsayıcılar büyük bir güvenlik riskidir: kapsayıcıdan kaçış, ana makineye tam erişim sağlar. Ana süreci çalıştırmadan önce her zaman ayrıcalıksız bir kullanıcıya geçin.

  • Dockerfile içinde addgroup / adduser (Alpine) veya groupadd / useradd (Debian) ile özel bir sistem kullanıcısı ve grubu oluşturun.
  • Uygulama dosyalarının sahipliğini COPY --chown=appuser:appgroup ile değiştirin; bu, ayrı bir RUN chown katmanı kullanmaktan daha verimlidir.
  • USER yönergesiyle bu kullanıcıya geçin. Başlatma noktası ve CMD bu kullanıcıyı devralır.
  • Kubernetes securityContext.runAsNonRoot: true, hâlâ root olarak çalışan bir imajı başlatmayı reddeder.
FROM python:3.12-slim

# Create non-root user
RUN groupadd --gid 1001 appgroup && \
    useradd --uid 1001 --gid appgroup --shell /bin/bash --create-home appuser

WORKDIR /app

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

# Copy app files with correct ownership in a single layer
COPY --chown=appuser:appgroup src/ ./src/
COPY --chown=appuser:appgroup entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

USER appuser

ENTRYPOINT ["/entrypoint.sh"]
CMD ["python", "-m", "src.main"]

İmajda Sağlık Denetimleri ve Hazır Olma Yoklamaları

Kubernetes canlılık ve hazır olma yoklamaları bildirimlerde tanımlanır; ancak bağımsız docker run ve Docker Compose ortamları için Dockerfile'a bir HEALTHCHECK de ekleyebilirsiniz.

  • HEALTHCHECK --interval=10s --timeout=3s --start-period=15s --retries=3 CMD ...
  • HTTP hizmetleri için curl --fail veya wget -qO- kullanın; HTTP kullanmayan arka plan hizmetlerinde /dev/tcp/localhost/PORT ile bir yuvayı yoklayın.
  • Yalnızca ihtiyacınız olanları kurun: distroless imajlarda yalnızca sağlık denetimleri için curl eklemekten kaçının; bunun yerine amaca özel bir yoklama ikilisi veya uygulamanın kendi sağlık ikilisini kullanın.
FROM nginx:1.27-alpine

COPY nginx.conf /etc/nginx/nginx.conf
COPY dist/ /usr/share/nginx/html/

# Lightweight health check using bash TCP pseudo-device
# (no curl needed — works on any image with bash)
HEALTHCHECK --interval=15s --timeout=5s --start-period=10s --retries=3 \
  CMD bash -c 'exec 3<>/dev/tcp/localhost/80 && echo -e "GET /health HTTP/1.0\r\n" >&3 && cat <&3 | grep -q "200 OK"' || exit 1

EXPOSE 80

Her Şeyi Birleştirme: Üretim Ortamına Uygun Bir Başlatma Noktası

Aşağıdaki örnek, bu dersteki tüm kalıpları birleştiren eksiksiz ve üretim kalitesinde bir başlatma noktası aracı komut dosyasıdır: ortam doğrulama, yapılandırmaya şablon uygulama, sinyal iletme ve exec ile devretme. Bu kalıp, Kubernetes üzerinde dağıtılan gerçek dünya Node.js, Python ve Go mikro hizmetlerinde kullanılır.

  • Her bölüm, kendini açıklayan bir şablon görevi görmesi için açıklama satırları içerir.
  • Aracı komut dosyası 50 satırın altında tutulur; başlatma noktaları basit ve denetlenebilir olmalıdır.
  • Son exec "$@" komutuna dikkat edin: tüm hazırlıklar tamamlandıktan sonra kabuk uygulama süreciyle değiştirilir; böylece uygulama PID 1 olur ve tüm işletim sistemi sinyallerini doğrudan alır.
#!/usr/bin/env bash
# entrypoint.sh — production-grade container entrypoint shim
set -euo pipefail

# ── 1. Validate required environment variables ──────────────────
REQUIRED=(DATABASE_URL APP_SECRET PORT LOG_LEVEL)
for var in "${REQUIRED[@]}"; do
  [[ -n "${!var:-}" ]] || { echo "[entrypoint] FATAL: $var is not set" >&2; exit 1; }
done

# ── 2. Set safe defaults for optional variables ─────────────────
export HOST=${HOST:-0.0.0.0}
export WORKERS=${WORKERS:-2}

# ── 3. Render config template ───────────────────────────────────
if [[ -f /etc/app/app.conf.tmpl ]]; then
  envsubst '${DATABASE_URL} ${PORT} ${LOG_LEVEL} ${HOST}' \
    < /etc/app/app.conf.tmpl \
    > /etc/app/app.conf
  echo "[entrypoint] config rendered at /etc/app/app.conf"
fi

# ── 4. Wait for dependent services (optional, fast) ─────────────
if [[ -n "${WAIT_FOR_HOST:-}" ]]; then
  echo "[entrypoint] waiting for ${WAIT_FOR_HOST}:${WAIT_FOR_PORT:-5432}..."
  until bash -c "exec 3<>/dev/tcp/${WAIT_FOR_HOST}/${WAIT_FOR_PORT:-5432}" 2>/dev/null; do
    sleep 1
  done
  echo "[entrypoint] dependency ready"
fi

# ── 5. Hand off to CMD (PID 1 becomes the application) ──────────
echo "[entrypoint] starting: $*"
exec "$@"

Bilgi Kontrolü: Başlatma Noktalarında Sinyal İşleme

Kapsayıcı başlatma noktası komut dosyalarında sinyal işleme konusundaki anlayışınızı sınayın.

Özet: Yalın Dockerfile'lar ve Kabuk Başlatma Noktaları

Üretim ortamına yönelik kapsayıcı yazımının tüm katmanlarını ele aldınız:

  • Çok aşamalı derlemeler, derleyicileri ve derleme araçlarını son imajdan uzak tutmak için birden fazla FROM yönergesi kullanır; böylece yalın ve en küçük çalışma zamanı katmanları üretilir.
  • Katman sıralaması — bağımlılık bildirimlerini kaynak kodundan önce kopyalamak — önbellek isabetlerini en üst düzeye çıkarır ve CI işlem hatlarını hızlandırır.
  • BuildKit gizli bilgileri ve SSH bağlamaları, kimlik doğrulamalı derlemeleri bozmadan kimlik bilgilerini imaj geçmişinden uzak tutar.
  • Başlatma noktası aracı komut dosyaları, ortam değişkenlerini doğrular, envsubst ile yapılandırma dosyalarına şablon uygular ve exec "$@" aracılığıyla uygulamaya devreder.
  • Sinyal işleme, ya exec kullanılmasını (böylece uygulamanın PID 1 olmasını) ya da arka plan işleri kullanıldığında açık bir trap + kill + wait kalıbını gerektirir.
  • tini, kapsayıcı birden fazla süreç oluşturduğunda zombi süreçlerin toplanmasını ve sinyallerin doğru şekilde iletilmesini sağlar.
  • Kök kullanıcı olmayan kullanıcılar ve HEALTHCHECK yönergeleri, Kubernetes üretim iş yüklerine hazır, güvenli ve gözlemlenebilir bir imajı tamamlar.

Bu kalıpları tutarlı biçimde birleştirdiğinizde imajlarınız daha küçük, dağıtımları daha hızlı ve üretim koşullarındaki davranışları çok daha sağlam olur.

Sıkça Sorulan Sorular

“Yalın Dockerfile'lar ve Kabuk Giriş Noktaları Yazma” dersi ücretsiz mi?

Evet — “Yalın Dockerfile'lar ve Kabuk Giriş Noktaları Yazma” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Linux Command Line & Bash Scripting Mastery kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Linux Command Line & Bash Scripting Mastery kursu toplamda 4 dersten oluşur.

“Yalın Dockerfile'lar ve Kabuk Giriş Noktaları Yazma” dersinde ne öğreneceğim?

Sinyal işleme ve yapılandırma şablonlaması içeren çok aşamalı derleme betikleri ile sağlam giriş noktası uyarlayıcıları yazın. Linux Command Line & Bash Scripting Mastery ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

Linux Command Line & Bash Scripting Mastery öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te Linux Command Line & Bash Scripting Mastery, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 1. dersidir.

“Yalın Dockerfile'lar ve Kabuk Giriş Noktaları Yazma” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu Linux Command Line & Bash Scripting Mastery dersinde kod yazıp çalıştırabilir miyim?

Evet. Her Linux Command Line & Bash Scripting Mastery dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. Yalın Dockerfile'lar ve Kabuk Giriş Noktaları Yazma
  2. envsubst ve heredoc'larla Yapılandırma Şablonlama
  3. CLI ve jq ile Bulut Kaynaklarını Betikleme
  4. Sağlık Yoklamaları, Hazırlık Kapıları ve Bekleme Döngüleri
← Linux Command Line & Bash Scripting Mastery Sayfasına Dön