Dockerfile'larınız çalışıyor olabilir — bu aslında sorunun ta kendisi. Derleme ve çalıştırma işlemleri sırasında ortaya çıkan güvenlik açıkları, yavaşlamalar ve gereksiz depolama alanı kullanımı, çoğu zaman ancak bir denetim, güvenlik ihlali ya da artan cloud faturalarıyla fark ediliyor. Sık yapılan ve çoğu geliştiricinin farkında olmadığı yedi Dockerfile hatası ile bunların nasıl önüne geçileceğini inceleyeceğiz.
1. Konteynerlerinizi kök kullanıcı olarak çalıştırmak
Dockerfile'larınızın varsayılan davranışı, içindeki süreçlerin kök (root) kullanıcı olarak çalışmasıdır. Bu durum, konteynerden bir kaçış gerçekleşmesi halinde saldırganın sistemde kök yetkilerine sahip olması anlamına gelir. Basit bir kullanıcı değişikliğiyle bu riski ortadan kaldırabilirsiniz:
RUN useradd --system --uid 10001 appuser
USER appuserBu küçük değişiklik, "en azından kök değildi" mazeretini ortadan kaldırarak ciddi güvenlik açıklarının önüne geçer. Maliyeti neredeyse sıfır olan bu düzeltme, birçok güvenlik ihlalini engelleyebilir.
2. FROM some-image:latest kullanmak — versiyon kontrolü yapılmaması
latest etiketi, aslında "bu komut çalıştırıldığında en yeni olan görüntü" anlamına gelir. Arka arkaya yapılan iki derleme işlemi bile — yalnızca birkaç gün arayla — farklı taban görüntülerini kullanabilir. Bu durum, beklenmedik güncellemeler nedeniyle çalışan uygulamaların bozulmasına yol açabilir. En iyi uygulama, daima belirli bir versiyonu belirtmektir:
FROM node:20.11.1-slimDaha da güvenlisi, daima imza (digest) kullanmaktır. Böylece hangi versiyonun kullanıldığı kesin olarak belirlenebilir ve tekrarlanabilir derlemeler sağlanır.
3. Gizli bilgileri katmanlara gömmek
.env dosyalarını kopyalamak ya da ARG API_KEY kullanarak gizli bilgileri derleme sırasında görüntüye yerleştirmek, bu bilgilerin daha sonra bile kurtarılabilir olmasına neden olur. Docker katmanları değiştirilemez ve eklemelidir; bir katmandaki dosyayı silmek, o bilgiyi kurtarmayı engellemez. Güvenlik en iyi uygulaması, gizli bilgileri derleme sırasında değil, çalışma zamanında enjekte etmektir:
docker build --secret id=api_key,src=./api_key.env .Ya da Kubernetes gibi platformlarda gizli bilgileri çalışma zamanında enjekte ederek güvenlik riskini minimize edin.
4. .dockerignore dosyasından yoksun olmak
.dockerignore dosyası olmadan COPY . . komutu, .git, yerel ortam dosyaları, node_modules ve test verilerini derleme bağlamına dahil eder. Bu durum hem gereksiz büyüklükte görüntülere yol açar hem de hassas bilgilerin katmanlara gömülmesine neden olur. Basit beş satırlık bir .dockerignore dosyası, projenizin en etkin güvenlik araçlarından biri olabilir:
.git
.env
*.log
docker-compose.yml
node_modules/5. Katman sırasını yanlış düzenlemek — önbellek bozulmasına neden olmak
Aşağıdaki gibi bir Dockerfile örneği düşünün:
COPY . .
RUN npm ciBu yapı, yalnızca bir satır kod değişikliği olduğunda bile tüm bağımlılıkların yeniden kurulmasına neden olur. Docker, herhangi bir katmanda yapılan değişiklikten sonraki tüm katmanları geçersiz kılar. En iyi uygulama, öncelikle kilit dosyalarını kopyalamak ve bağımlılıkları kurmaktır:
COPY package.json package-lock.json ./
RUN npm ci
COPY . .Bu sayede, kaynak kodunda yapılan küçük değişiklikler bağımlılıkların yeniden kurulmasını tetiklemez ve derleme süreleri önemli ölçüde kısalır.
6. Paket yöneticisi kalıntılarını temizlememek
RUN apt-get update && apt-get install -y curlBu komut, apt paket listesinin görüntüde kalmasına neden olur. Ayrı bir RUN komutuyla temizlemek, kalıntıların zaten katmana gömülmüş olması nedeniyle işe yaramaz. Tüm işlemleri tek bir katmanda tamamlamak gerekir:
RUN apt-get update \
&& apt-get install -y --no-install-recommends curl \
&& rm -rf /var/lib/apt/lists/*Bu şekilde hem gereksiz dosyalar temizlenir hem de katman boyutu minimize edilir.
7. HEALTHCHECK tanımlamamak — uygulama sağlığını görmezden gelmek
Docker ve orkestratörler, yalnızca sürecin çalışıp çalışmadığını kontrol eder; uygulamanın gerçekten hizmet verebilir durumda olup olmadığını anlamaz. Örneğin, bir web sunucusu çalışıyor olabilir, ancak veritabanına bağlanamıyor olabilir. Bu durumda, konteyner "çalışıyor" olarak görünse de aslında hizmet veremez durumdadır. Sağlık kontrolü tanımlamak, bu durumu tespit etmeyi kolaylaştırır:
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f || exit 1Önemli olan, bu uç noktanın uygulamanın gerçek durumunu kontrol etmesini sağlamaktır — yalnızca web sunucusunun çalışıp çalışmadığını değil.
Sonuç: Küçük değişiklikler, büyük farklar
Bu hataların hiçbiri Dockerfile'ınızın derlemesini engellemez. Aksine, sorunlar genellikle derleme sonrasında — güvenlik denetimlerinde, yavaş derleme sürelerinde, gereksiz depolama alanı kullanımında ya da "sağlıklı" olduğu halde hizmet veremeyen konteynerlerde ortaya çıkar. Bu düzeltmelerin tamamı yalnızca birkaç satırlık değişiklik gerektirir; en zor kısım, yoğun çalışma saatlerinde bile bunları hatırlamaktır.
Bu hatalara karşı önlem almak için benim tercih ettiğim yöntemler arasında, Dockerfile ve Compose dosyalarını yerel olarak doğrulayan araçlar kullanmak ve Docker ile ilgili sorunlar yaşandığında başvurabileceğim bir hata ayıklama aracı seti bulundurmak yer alıyor. Bu basit adımlar, Docker projelerinizin hem daha güvenli hem de daha verimli olmasını sağlayabilir.
Siz hangi hatayı ilk elden yaşadınız? Benim için üçüncüsüydi ve hatırladıkça hâlâ tedirgin oluyorum.
Yapay zeka özeti
Dockerfile'larınızda gizlenen güvenlik, performans ve depolama maliyetlerini keşfedin. Kök kullanıcı çalıştırmaktan en son etiketi kullanmaya kadar 7 yaygın hatanın çözümlerini ve en iyi uygulamaları öğrenin.