Giriş
Docker imajları oluştururken uygulama kodlarını, yapılandırma dosyalarını veya dağıtım arşivlerini imaja eklemek için COPY ve ADD komutları kullanılabilir. Basit yerel dosyalar için her iki komut aynı sonucu üretirken, arşiv dosyaları, uzak kaynaklar veya çok aşamalı yapılar söz konusu olduğunda davranışları farklılık gösterir. Bu kılavuz, her iki komutun detaylarını karşılaştırarak hangi durumda hangisini kullanmanız gerektiğini açıklamaktadır.
COPY Komutu Nasıl Çalışır?
COPY komutu, yerel dosya sistemi veya başka bir imajdan (build stage) dosya ve dizinleri Docker imajının belirli bir konumuna kopyalar. Temel kullanım şekli aşağıdaki gibidir:
COPY kaynak_dosya hedef_konum
COPY kaynak_dizin hedef_dizin/
Örnekler:
# Tek bir dosyayı kopyala
COPY app.py /app/
# Bir dizini ve içindeki tüm dosyaları kopyala
COPY src/ /app/src/
# Çok aşamalı yapıdan dosya kopyala
COPY --from=builder /app/build/output /usr/local/bin/app
COPY Komutunun Avantajları
- Basit ve tahmin edilebilir: Sadece dosya/dizin kopyalama işlemi yapar, arşiv dosyalarını otomatik olarak çıkartmaz.
- Yüksek performans: Sadece gerekli dosyaları kopyalar, ekstra işlemler (çıkartma, indirme) yapmaz.
- Çok aşamalı yapılarla uyum:
--fromseçeneğiyle başka bir imajdan veya build aşamasından dosya kopyalama imkanı sunar. - İzin ve sahiplik kontrolü:
--chownve--chmodseçenekleriyle dosya izinlerini ve sahipliğini ayarlayabilirsiniz.
# Dosya sahipliğini ve izinlerini ayarla
COPY --chown=appuser:appgroup --chmod=644 config.yml /app/
# Build aşamasından dosya kopyala
COPY --from=builder /app/target/app /usr/local/bin/app
⚠️ Önemli Not:
COPYkomutu arşiv dosyalarını (örn. .tar.gz) olduğu gibi kopyalar. Eğer arşivin içeriğini çıkartmak istiyorsanız,ADDkomutunu kullanmalısınız.
ADD Komutu Nasıl Çalışır?
ADD komutu, yerel dosyaları kopyalarken aynı zamanda arşiv dosyalarını otomatik olarak çıkartabilir, uzak kaynaklardan (HTTP/HTTPS/Git) dosya indirebilir ve hatta bunları imaja ekleyebilir. Temel kullanım şekli COPY ile aynıdır:
ADD kaynak_dosya hedef_konum
ADD kaynak_dizin hedef_dizin/
ADD Komutunun Özel Davranışları
1. Arşiv Dosyalarını Otomatik Çıkartma
ADD, yerel arşiv dosyalarını (tar, gzip, bzip2, xz) otomatik olarak çıkartır. Örneğin:
# .tar.gz arşivini çıkart ve / dizinine yerleştir
ADD rootfs.tar.gz /
# .tar.xz arşivini çıkart ve /opt dizinine yerleştir
ADD app-1.4.2-dist.tar.xz /opt/app/
💡 İpucu: Dosyanın arşiv olup olmadığına isimden değil, içeriğinden karar verilir. Eğer arşiv olarak tanınmayan bir dosya
ADDile kullanılırsa, hata oluşmaz ve dosya olduğu gibi kopyalanır.
2. Uzak Kaynaklardan Dosya İndirme
ADD, HTTP/HTTPS URL'lerinden dosya indirebilir. BuildKit ile birlikte --checksum seçeneği kullanılarak indirilen dosyanın SHA-256 hash değeri doğrulanabilir. Örneğin:
# syntax=docker/dockerfile:1
ADD --checksum=sha256:24454f830cdb571e2c4ad15481119c43b3cafd48dd869a9b2945d1036d1dc68d \
https://example.com/app.tar.gz /tmp/app.tar.gz
⚠️ Uyarı: Uzak arşiv dosyaları varsayılan olarak indirilir fakat çıkartılmaz. Dockerfile syntax 1.17 ve üzeri için
--unpack=trueseçeneğiyle hem indirme hem de çıkartma işlemi tek adımda yapılabilir.
3. Git Depolarını Klonlama
ADD, Git depolarını klonlayabilir. Belirli bir dal, etiket, commit veya alt dizin seçilebilir. Örneğin:
# Belirli bir branch'i klonla
ADD --keep-git-dir=true https://github.com/user/repo.git#main /app/repo
# Belirli bir commit'i klonla ve checksum ile doğrula
ADD --checksum=sha1:abc123... https://github.com/user/repo.git#v1.0.0 /app/repo
COPY ve ADD Arasındaki Temel Farklar
| Kaynak veya Davranış | COPY | ADD |
|---|---|---|
| Yerel dosya ve dizinler | Kopyalar | Kopyalar |
| Yerel arşiv dosyaları | Arşivi olduğu gibi kopyalar | Varsayılan olarak arşivden çıkarır |
| Uzak HTTP/HTTPS URL | Desteklenmez | Dosyayı indirir |
| Uzak Git deposu | Desteklenmez | Depoyu klonlar |
| Uzak kaynak checksum doğrulaması | Uygulanamaz | --checksum seçeneği |
| Uzak arşivin otomatik çıkartılması | Desteklenmez | --unpack=true |
| Build aşaması, isimli kontekst veya imaj | --from seçeneği |
Desteklenmez |
Hangi Durumda Hangi Komutu Kullanmalısınız?
COPY Komutunu Kullanmanız Gereken Durumlar
- Uygulama kodları ve yapılandırma dosyaları: Uygulamanızın kaynak kodunu, Dockerfile'ınızın bulunduğu dizinden imaja kopyalarken
COPYkullanın.COPY src/ /app/src/ COPY config.yml /app/config/ - Çok aşamalı build işlemleri: Derlenmiş ikili dosyaları (binary) üretim imajına kopyalarken
COPY --fromkullanın.# Derleyici aşamasından çıktıyı üretim imajına kopyala COPY --from=builder /app/target/app /usr/local/bin/app - Statik dosyalar ve kaynaklar: Web uygulamalarındaki statik dosyaları (JS, CSS, HTML) kopyalarken
COPYtercih edilmelidir.COPY static/ /usr/share/nginx/html/ - Arşiv dosyalarını olduğu gibi saklamak: Eğer arşiv dosyasını imaja eklemek ve daha sonra elle çıkartmak istiyorsanız,
COPYkullanın.COPY app-1.4.2.tar.gz /opt/app/ # Daha sonra RUN komutunda elle çıkart RUN tar -xzf /opt/app/app-1.4.2.tar.gz -C /opt/app/
💡 En İyi Uygulama: Docker topluluğu,
COPYkomutunu arşiv dosyaları için tercih etmenizi önermektedir. Bu sayede arşivin bütünlüğü korunur ve gereksiz otomatik çıkartma işlemlerinden kaçınılmış olur.
ADD Komutunu Kullanmanız Gereken Durumlar
- Arşiv dosyalarının otomatik çıkarılması: Uygulama arşivini doğrudan imaja eklemek ve içeriklerini çıkartmak istiyorsanız
ADDkullanın.# Uygulama arşivini çıkar ve /opt/app dizinine yerleştir ADD app-1.4.2-dist.tar.gz /opt/app/ - Uzak kaynaklardan dosya indirme: Build sürecinde doğrudan bir URL'den dosya indirmek istiyorsanız
ADDkullanın. Özellikle BuildKit ile checksum doğrulaması yapabilirsiniz.# syntax=docker/dockerfile:1 ADD --checksum=sha256:abc123... https://example.com/app.tar.gz /tmp/app.tar.gz - Git depolarını klonlama: Uzak bir Git deposunu doğrudan Dockerfile'a eklemek ve klonlamak istiyorsanız
ADDkomutunu kullanın.ADD https://github.com/user/repo.git#main /app/repo - Root dosya sistemi oluşturma: Linux sistemlerinin root dosya sistemini oluşturmak için arşiv dosyalarını çıkartırken
ADDkullanışlıdır.ADD alpine-minirootfs-3.18.0-x86_64.tar.gz /
⚠️ Dikkat Edilmesi Gerekenler: Uzak kaynaklardan dosya indirirken, indirilen dosyanın geçerliliğini doğrulamak için
--checksumkullanın. Ayrıca, indirilen dosyaların imaj katmanlarında kalıcı olmasını istemiyorsanız,RUNkomutunda geçici dizinlere indirip işledikten sonra silin.
Pratik Örnekler
Örnek 1: Yerel Dosya Kopyalama (COPY)
Basit bir Node.js uygulaması için Dockerfile örneği:
# syntax=docker/dockerfile:1
FROM node:18-alpine
WORKDIR /app
# Uygulama kodunu kopyala
COPY package*.json ./
RUN npm install
# Kaynak kodunu kopyala
COPY src/ ./src
# Uygulamayı çalıştır
CMD ["node", "src/index.js"]
Örnek 2: Arşiv Dosyasını Çıkartma (ADD)
Bir Python uygulamasının arşiv halindeki bağımlılıklarını çıkartıp kullanma örneği:
# syntax=docker/dockerfile:1
FROM python:3.11-slim
WORKDIR /app
# Arşiv dosyasını çıkar ve bağımlılıkları yükle
ADD requirements.tar.gz /tmp/
RUN pip install -r /tmp/requirements.txt
# Uygulama kodunu kopyala
COPY app.py .
CMD ["python", "app.py"]
Örnek 3: Uzak Kaynaklardan Dosya İndirme (ADD)
Build sürecinde doğrudan bir URL'den dosya indirme ve doğrulama örneği:
# syntax=docker/dockerfile:1
FROM alpine:latest
# Doğrulanmış bir arşiv dosyasını indir ve çıkar
ADD --checksum=sha256:abc123... https://example.com/tool-v1.0.0.tar.gz /opt/tool/
# Aracı çalıştırılabilir yap
RUN chmod +x /opt/tool/tool && \
ln -s /opt/tool/tool /usr/local/bin/tool
Sonuç
COPY ve ADD komutları arasındaki seçim, kullanım amacınıza bağlıdır. Genel kural olarak:
- Yerel dosyalar ve çok aşamalı build işlemleri için
COPYkullanın. Bu komut daha basit, tahmin edilebilir ve performanslıdır. - Arşiv dosyalarının otomatik çıkarılması, uzak kaynaklardan dosya indirme veya Git depolarını klonlama için
ADDkullanın.
COPY komutu, Docker imajlarınızın katman sayısını ve karmaşıklığını azaltırken, ADD komutu özel durumlar için esneklik sağlar. Dockerfile yazarken her iki komutun da avantajlarını ve sınırlamalarını göz önünde bulundurarak en uygun olanı seçin.
Daha fazla bilgi için Docker belgelerine ve Dockerfile en iyi uygulamalarına göz atabilirsiniz:


