İmaj Deposu: Docker Hub’a Gönderme ve Çekme

Konteyner teknolojisine adım attığınızda, yazdığınız Dockerfile’ların ve oluşturduğunuz imajların bir yerde saklanması gerektiğini kısa sürede anlarsınız. Geliştirme ortamındaki imajı production sunucusuna taşımak, ekip arkadaşlarıyla paylaşmak ya da CI/CD pipeline’ınızda kullanmak için merkezi bir imaj deposuna ihtiyaç duyarsınız. Docker Hub tam olarak bu noktada devreye girer. Dünyanın en büyük konteyner imaj deposu olan Docker Hub, milyonlarca hazır imajı barındırırken kendi imajlarınızı da güvenle saklayabileceğiniz bir platform sunar. Bu yazıda Docker Hub’ı gerçek dünya senaryolarıyla nasıl kullanacağınızı, imajlarınızı nasıl gönderip çekeceğinizi ve bu süreci nasıl verimli hale getireceğinizi anlatacağım.

Docker Hub Nedir ve Neden Kullanmalısınız

Docker Hub, Docker Inc. tarafından işletilen bulut tabanlı bir imaj deposudur. Ücretsiz hesapla sınırsız public repository ve bir adet private repository oluşturabilirsiniz. Ücretli planlarda bu limit yükselir. Peki neden Docker Hub’ı tercih etmelisiniz?

Öncelikle ekosistem desteği açısından değerlendirelim. Ubuntu, Nginx, PostgreSQL, Redis gibi resmi imajların hepsi Docker Hub üzerinde barındırılır. Yeni bir teknoloji öğrenirken ya da hızlıca prototip geliştirirken bu hazır imajlardan yararlanmak muazzam bir zaman tasarrufu sağlar. Kendi imajlarınız için de benzer bir merkezi yapı kurmak, özellikle birden fazla sunucuya deploy ettiğinizde hayat kurtarır.

CI/CD entegrasyonu da ayrı bir avantajdır. GitHub Actions, Jenkins, GitLab CI gibi araçlarla Docker Hub’ı kolayca entegre edebilir, kod push ettiğinizde otomatik build ve push işlemleri tetikleyebilirsiniz.

Hesap Oluşturma ve İlk Yapılandırma

Docker Hub kullanmak için önce [hub.docker.com](https://hub.docker.com) adresinden ücretsiz bir hesap oluşturmanız gerekir. Kullanıcı adınızı dikkatli seçin, çünkü imaj isimleriniz bu kullanıcı adıyla başlayacak. Örneğin kullanıcı adınız ahmetyilmaz ise imajlarınız ahmetyilmaz/imaj-adi şeklinde görünecektir.

Hesap oluşturduktan sonra terminal üzerinden giriş yapın:

docker login

Bu komutu çalıştırdığınızda kullanıcı adı ve şifrenizi girmeniz istenir. Başarılı girişin ardından kimlik bilgileriniz ~/.docker/config.json dosyasına kaydedilir.

# Belirli bir registry'e login olmak için
docker login -u kullanici_adiniz

# Şifreyi stdin üzerinden güvenli şekilde geçirmek için
echo "sifreniz" | docker login --username kullanici_adiniz --password-stdin

Güvenlik notu: Production ortamlarında ve CI/CD pipeline’larında şifreyi doğrudan komuta yazmak yerine --password-stdin yöntemini ya da Docker Hub access token’larını kullanın. Token oluşturmak için Docker Hub hesabınızda “Account Settings > Security > New Access Token” adımlarını takip edin.

İmaj Etiketleme: Temel Kavramlar

Docker Hub’a imaj göndermeden önce imajınızın doğru şekilde etiketlenmiş olması gerekir. Docker imaj isimlendirme formatı şu şekildedir:

[registry]/[kullanici_adi]/[imaj_adi]:[tag]

Docker Hub için registry kısmını belirtmeniz gerekmez, varsayılan olarak docker.io kullanılır. Yani bir imajın tam adı şu şekilde olabilir:

  • ahmetyilmaz/my-webapp:latest
  • ahmetyilmaz/my-webapp:1.0.0
  • ahmetyilmaz/my-webapp:production

Tag kısmı belirtilmezse Docker otomatik olarak latest etiketini kullanır. Ancak production ortamlarında latest yerine spesifik versiyon numaraları kullanmak çok daha sağlıklıdır.

# Mevcut bir imajı yeniden etiketleme
docker tag kaynak_imaj:tag kullanici_adi/yeni_imaj_adi:yeni_tag

# Örnek kullanım
docker tag my-webapp:local ahmetyilmaz/my-webapp:1.0.0

# Aynı imaja birden fazla tag eklemek
docker tag ahmetyilmaz/my-webapp:1.0.0 ahmetyilmaz/my-webapp:latest
docker tag ahmetyilmaz/my-webapp:1.0.0 ahmetyilmaz/my-webapp:stable

Gerçek Dünya Senaryosu: Bir Web Uygulamasını Docker Hub’a Göndermek

Diyelim ki Node.js ile yazılmış basit bir web uygulamanız var. Uygulamanızın Dockerfile’ı şu şekilde:

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

Bu Dockerfile’dan imaj oluşturup Docker Hub’a gönderme süreci adım adım şöyle işler:

# 1. Adım: İmajı build et
docker build -t ahmetyilmaz/node-webapp:1.0.0 .

# 2. Adım: İmajın doğru oluştuğunu kontrol et
docker images | grep node-webapp

# 3. Adım: Yerel ortamda test et
docker run -p 3000:3000 ahmetyilmaz/node-webapp:1.0.0

# 4. Adım: latest etiketini de ekle
docker tag ahmetyilmaz/node-webapp:1.0.0 ahmetyilmaz/node-webapp:latest

# 5. Adım: Her iki tag'i de Docker Hub'a gönder
docker push ahmetyilmaz/node-webapp:1.0.0
docker push ahmetyilmaz/node-webapp:latest

Push işlemi sırasında Docker, imajınızı katman katman (layer) yükler. Daha önce Docker Hub’da bulunan katmanlar tekrar yüklenmez, bu sayede hem bant genişliğinden tasarruf edilir hem de işlem hızlanır. Bu özelliğe layer caching denir ve Dockerfile’ınızı doğru yapılandırdığınızda büyük avantaj sağlar.

İmaj Çekme: docker pull Komutunun İncelikleri

Docker Hub’dan imaj çekmek docker pull komutuyla yapılır. Bu işlem hem kendi imajlarınız hem de başkalarının public imajları için geçerlidir.

# En güncel versiyonu çek (latest tag)
docker pull ahmetyilmaz/node-webapp

# Spesifik bir versiyonu çek
docker pull ahmetyilmaz/node-webapp:1.0.0

# Resmi bir imajı çek
docker pull nginx:1.25-alpine

# Tüm tag'leri çek (dikkatli kullanın, disk dolabilir)
docker pull --all-tags ahmetyilmaz/node-webapp

Docker Hub’a kayıtlı olmadan da public imajları çekebilirsiniz. Ancak Docker Hub, anonim pull işlemleri için rate limiting uygulamaktadır. Saatte 100 pull ile sınırlanan anonim kullanıcılar, özellikle CI/CD ortamlarında bu limiti aşabilir. Login olmuş ücretsiz hesaplar için bu limit saatte 200 pull’a çıkar.

Rate Limiting ile Başa Çıkma

CI/CD pipeline’larınızda rate limit sorunuyla karşılaşıyorsanız birkaç çözüm yolu vardır:

# Pull rate limit durumunu kontrol etmek için
TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq -r .token)
curl -s --head -H "Authorization: Bearer $TOKEN" https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest | grep -i ratelimit

Pratik çözüm olarak sık kullandığınız base imajları kendi Docker Hub hesabınıza ya da kurumsal bir registry’ye kopyalayabilirsiniz. Bu yönteme imaj mirroring denir.

Repository Yönetimi

Docker Hub üzerinde repository’lerinizi web arayüzünden yönetebileceğiniz gibi bazı işlemleri komut satırından da gerçekleştirebilirsiniz.

# Mevcut imajlarınızı listele
docker images

# Belirli bir imajın tüm tag'lerini görüntüle
docker images ahmetyilmaz/node-webapp

# Artık kullanmadığınız imajları temizle
docker rmi ahmetyilmaz/node-webapp:0.9.0

# Tüm kullanılmayan imajları temizle
docker image prune -a

Docker Hub API’sini kullanarak repository bilgilerine programatik erişim de mümkündür:

# Bir kullanıcının public repository'lerini listele
curl -s "https://hub.docker.com/v2/repositories/ahmetyilmaz/?page_size=100" | jq '.results[].name'

# Bir imajın mevcut tag'lerini listele
curl -s "https://hub.docker.com/v2/repositories/ahmetyilmaz/node-webapp/tags/" | jq '.results[].name'

Çok Platformlu İmaj Oluşturma

Modern altyapılarda hem AMD64 hem de ARM64 mimarisine sahip sunucular kullanılabiliyor. AWS Graviton, Apple M serisi çipler ve Raspberry Pi gibi ARM tabanlı platformlar giderek yaygınlaşıyor. Docker’ın buildx aracı sayesinde tek komutla her iki mimari için de imaj oluşturup Docker Hub’a gönderebilirsiniz.

# Buildx builder oluştur
docker buildx create --name multiplatform-builder --use

# Builder'ı başlat
docker buildx inspect --bootstrap

# Çok platformlu imaj oluştur ve direkt Docker Hub'a gönder
docker buildx build 
  --platform linux/amd64,linux/arm64 
  -t ahmetyilmaz/node-webapp:1.0.0 
  -t ahmetyilmaz/node-webapp:latest 
  --push 
  .

--push parametresi build edilen imajı direkt olarak registry’ye gönderir. Çok platformlu imajlar yerel docker images listesinde görünmez, doğrudan registry’de saklanır.

Automated Builds ve Docker Hub Entegrasyonu

Docker Hub’ın GitHub ve Bitbucket entegrasyonu sayesinde kod deposunuza push yaptığınızda otomatik build tetiklenebilir. Ancak bu özellik artık ücretli planlarda aktif. Ücretsiz alternatif olarak GitHub Actions kullanmak çok daha yaygın bir tercih haline geldi.

Tipik bir GitHub Actions workflow’u şu şekilde görünür:

name: Docker Hub Push

on:
  push:
    branches: [ main ]
    tags: [ 'v*.*.*' ]

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Docker Hub Login
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build ve Push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: |
            ahmetyilmaz/node-webapp:latest
            ahmetyilmaz/node-webapp:${{ github.sha }}

Bu yapılandırmada DOCKERHUB_TOKEN olarak Docker Hub’dan oluşturduğunuz access token’ı, DOCKERHUB_USERNAME olarak da kullanıcı adınızı GitHub repository’nin Secrets bölümüne eklemeniz yeterli.

İmaj Güvenliği: Vulnerability Scanning

Docker Hub, imajlarınızı güvenlik açıkları için otomatik olarak tarar. Bu özellik Docker Scout adıyla sunulmaktadır. Özellikle production imajlarınızda güvenlik açığı barındıran paketleri tespit etmek kritik önem taşır.

# Docker Scout ile imajı analiz et
docker scout cves ahmetyilmaz/node-webapp:1.0.0

# Sadece kritik açıkları göster
docker scout cves --only-severity critical ahmetyilmaz/node-webapp:1.0.0

# İmaj hakkında genel özet
docker scout quickview ahmetyilmaz/node-webapp:1.0.0

Güvenlik taramasının yanı sıra imajlarınızın boyutunu küçük tutmak hem güvenlik hem de performans açısından önemlidir. Alpine tabanlı base imajlar, gereksiz araçları barındırmadığından hem daha küçük hem de daha az saldırı yüzeyi sunar.

Digest ile İmaj Doğrulama

Tag’ler değiştirilebilir, yani latest tag’i dünkü imajı gösterirken bugün farklı bir imajı işaret edebilir. Production ortamlarında imajın tam olarak hangi versiyonu olduğundan emin olmak için digest kullanımı önerilir.

# İmajın digest'ini öğren
docker inspect --format='{{index .RepoDigests 0}}' ahmetyilmaz/node-webapp:1.0.0

# Digest ile imaj çek (değişmezlik garantisi)
docker pull ahmetyilmaz/node-webapp@sha256:a1b2c3d4e5f6...

# Push sonrası digest bilgisini görmek için
docker push ahmetyilmaz/node-webapp:1.0.0
# Çıktıda "digest: sha256:..." satırını göreceksiniz

Kubernetes manifest dosyalarında da tag yerine digest kullanmak, imajın beklenmedik şekilde değişmesini engeller:

image: ahmetyilmaz/node-webapp@sha256:a1b2c3d4e5f6789...

Pratik İpuçları ve Yaygın Hatalar

Yıllar içinde gözlemlediğim en yaygın hataları ve çözümlerini paylaşmak istiyorum:

Hata: “denied: requested access to the resource is denied”

Bu hata genellikle iki nedenden kaynaklanır. Birincisi, Docker Hub’a login olmadan push yapmaya çalışmak. İkincisi ise imaj adının kullanıcı adıyla başlamaması.

# Yanlış
docker push my-webapp:latest

# Doğru
docker push ahmetyilmaz/my-webapp:latest

Hata: “tag does not exist” ya da yanlış imajı çekme

latest tag’ine güvenmek bazen sorun yaratır. Spesifik tag’ler kullanın:

# Tehlikeli - hangi versiyon olduğu belirsiz
docker pull ahmetyilmaz/my-webapp

# Güvenli - tam olarak hangi versiyon olduğu belli
docker pull ahmetyilmaz/my-webapp:1.2.3

Hata: Push çok yavaş ya da zaman aşımına uğruyor

İmaj boyutunu optimize etmek bu sorunu çözer. .dockerignore dosyası oluşturmayı unutmayın:

# .dockerignore dosyası oluştur
cat > .dockerignore << 'EOF'
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
*.log
dist
coverage
EOF

Kimlik bilgilerini düzgün yönetme

# Oturum açma durumunu kontrol et
cat ~/.docker/config.json

# Güvenli çıkış
docker logout

# Sadece belirli bir registry'den çıkış
docker logout registry.example.com

Private Repository Kullanımı

Ücretsiz Docker Hub hesabında bir adet private repository hakkınız bulunur. Private repository oluşturmak için Docker Hub web arayüzünden “Create Repository” adımında “Private” seçeneğini işaretleyin. Komut satırındaki kullanım public ile aynıdır, tek fark başkalarının bu imajları çekemeyeceğidir.

# Private repository'ye push
docker push ahmetyilmaz/private-app:1.0.0

# Başka bir sunucuda private imajı çekmek için önce login
docker login -u ahmetyilmaz
docker pull ahmetyilmaz/private-app:1.0.0

Birden fazla private repository ihtiyacınız varsa Docker Hub Pro planına geçmek yerine GitHub Container Registry (ghcr.io) ya da GitLab Container Registry gibi ücretsiz alternatifleri değerlendirmenizi öneririm. Kendi altyapınızda çalıştırmak isteyenler için Harbor veya Nexus Repository Manager mükemmel açık kaynak çözümler sunar.

Sonuç

Docker Hub, konteyner ekosisteminin merkezinde yer alan kritik bir altyapı bileşenidir. İmajları doğru şekilde etiketlemek, güvenli kimlik doğrulama yöntemleri kullanmak, imaj boyutlarını optimize etmek ve versiyon yönetimine önem vermek, günlük operasyonlarınızı hem daha güvenli hem de daha verimli hale getirir.

Özellikle vurgulamak istediğim noktalar şunlar: Production ortamlarında latest tag yerine spesifik versiyon numaraları kullanın, şifreler yerine access token tercih edin, büyük ekiplerde Docker Hub Pro veya özel registry çözümlerine geçmeyi düşünün. CI/CD entegrasyonu kurduğunuzda ise güvenlik scanning adımını pipeline’ınıza dahil etmek, sorunları production’a taşımadan tespit etmenizi sağlar.

Docker Hub’ı sadece bir depolama aracı olarak değil, iş akışınızın ayrılmaz bir parçası olarak konumlandırdığınızda, konteyner yönetimindeki karmaşıklık önemli ölçüde azalır ve ekipler arası işbirliği çok daha akıcı bir hal alır.

Yorum yapın