Skip to content
Dokumentatsiya
Docker Registry

Docker Registry

Kirish

Zamonaviy dasturiy ta'minot ishlab chiqishda Docker image'larini ishonchli, xavfsiz va tezkor tarzda saqlash va tarqatish — muhim infratuzilma masalalardan biri. Docker Registry — aynan shu vazifani bajaruvchi servis bo'lib, u Docker image'larini saqlash, versiyalash va tarqatish imkonini beradi.

Ko'pchilik dasturchilar Docker Hub bilan ishlaydi — bu eng mashhur public registry. Lekin production muhitda kompaniyalar ko'pincha xususiy (private) registry o'rnatadi, chunki:

  • Maxfiy kodlar va konfiguratsiyalar ommaviy bo'lmasligi kerak
  • Image pull/push tezligi muhim (mahalliy tarmoqdagi registry ancha tez)
  • Xavfsizlik va kirish nazorati to'liq qo'lda bo'lishi kerak
  • Regulyativ talablar (HIPAA, GDPR, PCI DSS) bunga majburlaydi

Docker Registry — bu Apache 2.0 litsenziyasi (opens in a new tab) ostidagi open-source loyiha. Manba kodi GitHub (opens in a new tab)'da mavjud. Rasmiy hujjatlar: docs.docker.com/registry (opens in a new tab)


Registry nima va qanday ishlaydi?

Docker Registry — bu stateless, server-side dastur bo'lib, Docker image'larini saqlaydi va OCI (Open Container Initiative) Distribution Specification bo'yicha ishlaydi. Sodda qilib aytganda — bu image'lar uchun fayl serveri.

Registry arxitekturasi

┌──────────────────────────────────────────────────────────────────┐
│                     Docker Registry Arxitekturasi                │
│                                                                  │
│  ┌──────────────┐         ┌──────────────────────────────────┐   │
│  │   Docker     │  HTTPS  │         Docker Registry          │   │
│  │   Client     │  API    │         (distribution)           │   │
│  │              ┼────────►│                                  │   │
│  │  docker push │         │  ┌────────────────────────────┐  │   │
│  │  docker pull │         │  │     HTTP API (v2)          │  │   │
│  │  docker tag  │         │  │     /v2/_catalog           │  │   │
│  │              │         │  │     /v2/<name>/manifests/  │  │   │
│  └──────────────┘         │  │     /v2/<name>/blobs/      │  │   │
│                           │  └────────────────────────────┘  │   │
│  ┌──────────────┐         │              │                   │   │
│  │   CI/CD      │  HTTPS  │              ▼                   │   │
│  │  (Jenkins,   ┼────────►│  ┌────────────────────────────┐  │   │
│  │   GitLab CI) │         │  │     Storage Backend        │  │   │
│  └──────────────┘         │  │  ┌──────┐ ┌──────┐         │  │   │
│                           │  │  │ Local│ │  S3  │ ...     │  │   │
│                           │  │  │ Disk │ │      │         │  │   │
│                           │  │  └──────┘ └──────┘         │  │   │
│                           │  └────────────────────────────┘  │   │
│                           └──────────────────────────────────┘   │
│                                                                  │
│  ┌──────────────────────────────────────────────────────────┐    │
│  │              Authentication Layer                        │    │
│  │          (htpasswd, LDAP, OAuth2, token)                 │    │
│  └──────────────────────────────────────────────────────────┘    │
└──────────────────────────────────────────────────────────────────┘

Image saqlash tuzilmasi

Docker image qanday saqlanadi? Registry ichida image manifest va layer (blob) lardan tashkil topadi:

┌──────────────────────────────────────────────┐
│              Docker Image                    │
│                                              │
│  ┌────────────────────────────────────────┐  │
│  │           Image Manifest               │  │
│  │  ┌──────────────────────────────────┐  │  │
│  │  │ mediaType: application/vnd...    │  │  │
│  │  │ config:   sha256:abc123...       │  │  │
│  │  │ layers:                          │  │  │
│  │  │   - sha256:layer1...             │  │  │
│  │  │   - sha256:layer2...             │  │  │
│  │  │   - sha256:layer3...             │  │  │
│  │  └──────────────────────────────────┘  │  │
│  └────────────────────────────────────────┘  │
│                                              │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐      │
│  │  Layer 1 │ │  Layer 2 │ │  Layer 3 │      │
│  │  (blob)  │ │  (blob)  │ │  (blob)  │      │
│  │ base OS  │ │ paketlar │ │ app kodi │      │
│  └──────────┘ └──────────┘ └──────────┘      │
│                                              │
│  Har bir layer SHA256 hash bilan             │
│  identifikatsiya qilinadi                    │
└──────────────────────────────────────────────┘

Push jarayonida Docker client avval har bir layer'ni blob sifatida yuklaydi, keyin manifest'ni yuboradi. Pull jarayonida esa avval manifest olinadi, keyin har bir layer yuklab olinadi. Agar layer allaqachon mavjud bo'lsa (boshqa image'dan), qayta yuklanmaydi — bu content-addressable storage deyiladi.


Registry turlari

Docker image'larini saqlash uchun turli xil registry'lar mavjud. Har birining o'z afzalliklari va kamchiliklari bor.

Public Registry'lar

RegistryTavsifBepul rejasi
Docker HubEng mashhur, default registry. docker pull nginx aslida docker.io/library/nginxPublic image'lar cheksiz, 1 private repo
GitHub Container Registry (ghcr.io)GitHub bilan integratsiya, GitHub Actions'da tezPublic image'lar bepul
Quay.ioRed Hat tomonidan boshqariladi, xavfsizlik skanerlashPublic image'lar bepul

Cloud Provider Registry'lari

RegistryProviderAfzalligi
Amazon ECRAWSECS/EKS bilan chuqur integratsiya, IAM autentifikatsiya
Google Artifact RegistryGCPGKE bilan integratsiya, multi-format (Docker, npm, Maven)
Azure Container RegistryAzureAKS bilan integratsiya, geo-replikatsiya
Yandex Container RegistryYandex CloudCIS mintaqasida past latency

Self-hosted (o'z serveringizda) Registry'lar

RegistryTavsifMurakkabligi
Docker RegistryRasmiy open-source registry, minimal funksionalOddiy
HarborCNCF graduated loyiha, vulnerability scanning, RBAC, replikatsiyaO'rta
GitLab Container RegistryGitLab bilan birga keladi, CI/CD integratsiyaO'rta
Nexus RepositoryMulti-format (Docker, Maven, npm, PyPI), korporativMurakkab
JFrog ArtifactoryEnterprise darajada, universal paket menejeriMurakkab

Qaysi birini tanlash kerak?

Loyihangiz qanday? ──► Shaxsiy/kichik loyiha
                        └──► Docker Hub yoki ghcr.io (bepul)

                   ──► Startup/O'rta kompaniya
                        └──► Cloud provider registry (ECR, GCR, ACR)
                        └──► Harbor (self-hosted kerak bo'lsa)

                   ──► Enterprise/Katta kompaniya
                        └──► Harbor + Trivy (xavfsizlik skanerlash)
                        └──► Nexus/Artifactory (multi-format kerak bo'lsa)

                   ──► Air-gapped muhit (internetsiz)
                        └──► Docker Registry yoki Harbor (self-hosted)

Docker Registry o'rnatish

1. Minimal o'rnatish (test uchun)

Eng oddiy usul — bitta buyruq bilan registry'ni ishga tushirish:

docker run -d \
  -p 5000:5000 \
  --name registry \
  --restart=always \
  registry:2

Bu buyruq:

  • registry:2 — rasmiy Docker Registry image'ining 2-versiyasini ishga tushiradi
  • -p 5000:5000 — 5000 portni host'ga map qiladi
  • --restart=always — server qayta ishga tushganda registry avtomatik ko'tariladi
  • -d — background rejimda ishlaydi

Tekshirish:

# Registry ishlayaptimi?
curl http://localhost:5000/v2/
 
# Javob: {} — demak ishlayapti

Bu usul faqat test uchun yaroqli! Production'da TLS, autentifikatsiya va doimiy saqlash (volume) shart. Quyida production-ready o'rnatishni ko'ramiz.

2. Production-ready o'rnatish (Docker Compose bilan)

Production muhit uchun to'liq konfiguratsiya quyidagicha bo'ladi. Biz 4 ta komponentni sozlaymiz:

  1. Docker Registry — image'larni saqlash
  2. Nginx — reverse proxy, TLS terminatsiya
  3. htpasswd — autentifikatsiya
  4. Volume — doimiy saqlash

Loyiha tuzilmasi

mkdir -p docker-registry/{auth,certs,data,nginx}
cd docker-registry
docker-registry/
├── docker-compose.yml      # Asosiy konfiguratsiya
├── auth/
│   └── htpasswd            # Foydalanuvchi parollari
├── certs/
│   ├── domain.crt          # TLS sertifikat
│   └── domain.key          # TLS kalit
├── data/                   # Image'lar saqlanadigan joy
└── nginx/
    └── nginx.conf          # Nginx konfiguratsiya

TLS sertifikat yaratish

Production'da Let's Encrypt yoki boshqa CA sertifikatidan foydalaning. Test uchun self-signed sertifikat yaratish mumkin:

# Self-signed sertifikat (test uchun)
openssl req -newkey rsa:4096 -nodes -sha256 \
  -keyout certs/domain.key \
  -x509 -days 365 \
  -out certs/domain.crt \
  -subj "/CN=registry.example.com" \
  -addext "subjectAltName=DNS:registry.example.com,IP:192.168.1.100"

Let's Encrypt bilan bepul SSL sertifikat olish uchun Certbot yoki Traefik ishlatishingiz mumkin. Production muhitda self-signed sertifikat ishlatmang!

Foydalanuvchilar yaratish (htpasswd)

# htpasswd fayl yaratish (birinchi foydalanuvchi)
docker run --entrypoint htpasswd registry:2 \
  -Bbn admin S3cur3P@ssw0rd > auth/htpasswd
 
# Qo'shimcha foydalanuvchi qo'shish
docker run --entrypoint htpasswd registry:2 \
  -Bbn developer DevP@ss123 >> auth/htpasswd
 
# CI/CD uchun alohida foydalanuvchi
docker run --entrypoint htpasswd registry:2 \
  -Bbn cicd-bot C1CdB0tP@ss >> auth/htpasswd

> belgisi faylni qaytadan yozadi, >> esa mavjud faylga qo'shadi. Birinchi foydalanuvchidan keyin >> ishlating, aks holda oldingi foydalanuvchilar o'chib ketadi!

Nginx konfiguratsiya

nginx/nginx.conf
upstream docker-registry {
    server registry:5000;
}
 
## HTTP -> HTTPS redirect
server {
    listen 80;
    server_name registry.example.com;
    return 301 https://$host$request_uri;
}
 
server {
    listen 443 ssl;
    server_name registry.example.com;
 
    # TLS sertifikatlar
    ssl_certificate     /etc/nginx/certs/domain.crt;
    ssl_certificate_key /etc/nginx/certs/domain.key;
 
    # TLS xavfsizlik sozlamalari
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
 
    # Katta image'lar uchun upload limitni oshirish
    client_max_body_size 2G;
 
    # Chunked transfer encoding
    chunked_transfer_encoding on;
 
    location /v2/ {
        # Docker V2 API faqat registry'ga proxy
        if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-hierarchical))|Go ).*$" ) {
            return 404;
        }
 
        proxy_pass                          http://docker-registry;
        proxy_set_header  Host              $http_host;
        proxy_set_header  X-Real-IP         $remote_addr;
        proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header  X-Forwarded-Proto $scheme;
        proxy_read_timeout                  900;
    }
}

Docker Compose fayl

docker-compose.yml
version: "3.8"
 
services:
  registry:
    image: registry:2
    restart: always
    environment:
      # Autentifikatsiya sozlamalari
      REGISTRY_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: "Docker Registry"
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
      # Saqlash sozlamalari
      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /var/lib/registry
      # Garbage collection uchun
      REGISTRY_STORAGE_DELETE_ENABLED: "true"
    volumes:
      - ./auth:/auth:ro
      - ./data:/var/lib/registry
    networks:
      - registry-net
 
  nginx:
    image: nginx:alpine
    restart: always
    ports:
      - "443:443"
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
      - ./certs:/etc/nginx/certs:ro
    depends_on:
      - registry
    networks:
      - registry-net
 
volumes:
  registry-data:
 
networks:
  registry-net:
    driver: bridge

Ishga tushirish

# Registry'ni ishga tushirish
docker compose up -d
 
# Loglarni tekshirish
docker compose logs -f
 
# Tekshirish
curl -u admin:S3cur3P@ssw0rd https://registry.example.com/v2/_catalog

Docker Daemon konfiguratsiyasi

Docker client'ni xususiy registry bilan ishlashi uchun sozlash kerak.

Self-signed sertifikat bilan ishlash

Agar self-signed sertifikat ishlatsangiz, Docker daemon'ga sertifikatni ishonchli deb belgilash kerak:

1-usul: Sertifikatni Docker sertifikatlar papkasiga nusxalash (tavsiya etiladi):

# Sertifikat papkasini yarating
sudo mkdir -p /etc/docker/certs.d/registry.example.com:443
 
# Sertifikatni nusxalang
sudo cp certs/domain.crt /etc/docker/certs.d/registry.example.com:443/ca.crt

2-usul: Insecure registry sifatida qo'shish (faqat test uchun!):

sudo nano /etc/docker/daemon.json
/etc/docker/daemon.json
{
  "insecure-registries": ["registry.example.com:5000"]
}
# Docker daemon'ni qayta ishga tushiring
sudo systemctl restart docker

insecure-registries faqat test muhitda ishlating! Bu TLS tekshiruvini o'chiradi va man-in-the-middle hujumlariga zaif qiladi. Production'da har doim to'g'ri TLS sertifikat ishlating.


Registry bilan ishlash

Login/Logout

# Registryga kirish
docker login registry.example.com
# Username: admin
# Password: S3cur3P@ssw0rd
 
# Kirish holatini tekshirish
cat ~/.docker/config.json
 
# Registrydan chiqish
docker logout registry.example.com

Image push qilish

Image'ni registryga push qilish uchun avval uni registry manzili bilan tag qilish kerak:

# 1. Image yaratish yoki mavjudini olish
docker pull nginx:alpine
 
# 2. Image'ni registry manzili bilan tag qilish
docker tag nginx:alpine registry.example.com/web/nginx:alpine
docker tag nginx:alpine registry.example.com/web/nginx:1.25
docker tag nginx:alpine registry.example.com/web/nginx:latest
 
# 3. Push qilish
docker push registry.example.com/web/nginx:alpine
docker push registry.example.com/web/nginx:1.25
docker push registry.example.com/web/nginx:latest
Push jarayoni:

┌──────────┐     tag      ┌──────────────────────────┐     push     ┌─────────────┐
│  nginx   │────────────► │ registry.example.com/    │────────────► │  Registry   │
│  :alpine │              │ web/nginx:alpine         │              │  Server     │
└──────────┘              └──────────────────────────┘              │             │
                                                                    │ Layer 1 ✓   │
                                                                    │ Layer 2 ✓   │
                                                                    │ Manifest ✓  │
                                                                    └─────────────┘

Image pull qilish

# Registrydan image pull qilish
docker pull registry.example.com/web/nginx:alpine
 
# Boshqa serverdan pull qilish (registry manzilini to'liq yozing)
docker pull registry.example.com/web/nginx:1.25

Tag nomlash strategiyasi (naming convention)

Image tag'larini tartibli nomlash juda muhim. Yaxshi nomlash strategiyasi:

registry.example.com/<loyiha>/<service>:<versiya>

Misollar:
  registry.example.com/backend/api:v1.2.3
  registry.example.com/backend/api:latest
  registry.example.com/backend/api:main-abc1234
  registry.example.com/frontend/web:v2.0.0-rc1
  registry.example.com/infra/nginx:1.25-custom
  registry.example.com/ml/model-server:2024.01
Tag formatiIshlatilishiMisol
v1.2.3 (SemVer)Release versiyalariapi:v1.2.3
latestEng so'nggi stabil versiyaapi:latest
<branch>-<sha>CI/CD build'lariapi:main-abc1234
<date>Kunlik build'larmodel:2024.01.15
<env>Muhitga qarabapi:staging, api:production

Production'da hech qachon faqat latest tag'ga tayanmang! Har doim aniq versiya raqamini (v1.2.3) ishlating. latest tag o'zgarishi mumkin va bu kutilmagan deploy'larga olib keladi.


Registry HTTP API (v2)

Docker Registry bilan to'g'ridan-to'g'ri HTTP API orqali ishlash mumkin. Bu monitoring, avtomatlashtirilgan skriptlar va CI/CD integratsiya uchun foydali.

Asosiy API endpoint'lari

# Registry versiyasini tekshirish
curl -u admin:pass https://registry.example.com/v2/
 
# Barcha repository'lar ro'yxati
curl -u admin:pass https://registry.example.com/v2/_catalog
# Javob: {"repositories":["web/nginx","backend/api","frontend/web"]}
 
# Muayyan repository tag'lari
curl -u admin:pass https://registry.example.com/v2/web/nginx/tags/list
# Javob: {"name":"web/nginx","tags":["alpine","1.25","latest"]}
 
# Image manifest'ini olish
curl -u admin:pass \
  -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
  https://registry.example.com/v2/web/nginx/manifests/alpine

Image o'chirish (API orqali)

# 1. Image digest'ini olish
DIGEST=$(curl -s -u admin:pass \
  -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
  -I https://registry.example.com/v2/web/nginx/manifests/alpine \
  | grep -i docker-content-digest | awk '{print $2}' | tr -d '\r')
 
# 2. Manifest'ni o'chirish
curl -u admin:pass -X DELETE \
  https://registry.example.com/v2/web/nginx/manifests/$DIGEST
 
# 3. Diskdagi o'chirilgan layer'larni tozalash (garbage collection)
docker exec registry bin/registry garbage-collect \
  /etc/docker/registry/config.yml

Foydali skript: barcha image'lar ro'yxatini olish

#!/bin/bash
# list-images.sh — registrydagi barcha image va taglarni ko'rsatish
 
REGISTRY="https://registry.example.com"
USER="admin"
PASS="S3cur3P@ssw0rd"
 
echo "=== Registry: $REGISTRY ==="
echo ""
 
# Repository'lar ro'yxatini olish
REPOS=$(curl -s -u $USER:$PASS $REGISTRY/v2/_catalog | \
  python3 -c "import sys,json; print('\n'.join(json.load(sys.stdin)['repositories']))")
 
for repo in $REPOS; do
  # Har bir repo uchun taglarni olish
  TAGS=$(curl -s -u $USER:$PASS $REGISTRY/v2/$repo/tags/list | \
    python3 -c "import sys,json; tags=json.load(sys.stdin).get('tags',[]); print(' '.join(tags or ['<no tags>']))")
  echo "  $repo"
  echo "   Tags: $TAGS"
  echo ""
done

Garbage Collection (axlat yig'ish)

Vaqt o'tishi bilan eski image'lar va foydalanilmagan layer'lar disk joyini egallaydi. Garbage collection (GC) — bu endi hech qanday manifest tomonidan referans qilinmagan blob'larni o'chirib, disk joyini bo'shatish jarayoni.

GC qanday ishlaydi?

GC dan oldin:                          GC dan keyin:

┌──────────────┐  ┌────────────┐         ┌────────────┐
│ Image v1.0   │  │ Image v2.0 │         │ Image v2.0 │
│ (o'chirilgan)│  │ (aktiv)    │         │ (aktiv)    │
├──────────────┤  ├────────────┤         ├────────────┤
│ Layer A      │  │ Layer A ───┼────┐    │ Layer A    │  Saqlanadi (v2.0 ishlatadi)
│ Layer B      │  │ Layer C    │    │    │ Layer C    │  Saqlanadi
│ Layer C      │  └────────────┘    │    └────────────┘
└──────────────┘                    │
        │                           │    O'chiriladi:
        └─── Layer B ───────────────┘    └─ Layer B  (hech kim ishlatmaydi)

GC'ni ishga tushirish

# Dry-run (nimalar o'chirilishini ko'rish, hali o'chirmaydi)
docker exec registry bin/registry garbage-collect \
  --dry-run /etc/docker/registry/config.yml
 
# Haqiqiy garbage collection
docker exec registry bin/registry garbage-collect \
  /etc/docker/registry/config.yml
 
# GC dan keyin registry'ni qayta ishga tushirish (tavsiya)
docker restart registry

Avtomatik GC (cron bilan)

# Crontab'ga qo'shish: har kuni soat 3:00 da GC ishga tushadi
crontab -e
# Har kuni soat 03:00 da garbage collection
0 3 * * * docker exec registry bin/registry garbage-collect /etc/docker/registry/config.yml >> /var/log/registry-gc.log 2>&1

GC ishga tushirishdan oldin registry'ga yozish operatsiyalarini to'xtatish tavsiya etiladi. Aks holda, hozir yuklayotgan layer'lar noto'g'ri o'chirilishi mumkin. Production'da GC'ni kam trafik vaqtida (tunda) rejalashtiring.


Storage Backend'lari

Docker Registry turli xil saqlash tizimlarini qo'llab-quvvatlaydi. Default — mahalliy fayl tizimi, lekin production'da object storage tavsiya etiladi.

Mavjud backend'lar

BackendTavsifIshlatilishi
filesystemMahalliy diskDefault, kichik muhitlar uchun
s3Amazon S3 (yoki S3-compatible)AWS muhiti, MinIO bilan ham ishlaydi
gcsGoogle Cloud StorageGCP muhiti
azureAzure Blob StorageAzure muhiti

S3 backend konfiguratsiya

config.yml
version: 0.1
storage:
  s3:
    accesskey: AKIAIOSFODNN7EXAMPLE
    secretkey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
    region: us-east-1
    bucket: my-docker-registry
    rootdirectory: /registry
  delete:
    enabled: true
  cache:
    blobdescriptor: inmemory

MinIO bilan (self-hosted S3)

MinIO — bu self-hosted S3-compatible object storage. Katta hajmdagi image'lar uchun juda mos:

docker-compose.yml
version: "3.8"
 
services:
  minio:
    image: minio/minio:latest
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: minioadmin
      MINIO_ROOT_PASSWORD: minioadmin123
    volumes:
      - minio-data:/data
    ports:
      - "9000:9000"
      - "9001:9001"
 
  registry:
    image: registry:2
    restart: always
    environment:
      REGISTRY_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: "Docker Registry"
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
      REGISTRY_STORAGE: s3
      REGISTRY_STORAGE_S3_ACCESSKEY: minioadmin
      REGISTRY_STORAGE_S3_SECRETKEY: minioadmin123
      REGISTRY_STORAGE_S3_REGION: us-east-1
      REGISTRY_STORAGE_S3_BUCKET: docker-registry
      REGISTRY_STORAGE_S3_REGIONENDPOINT: http://minio:9000
      REGISTRY_STORAGE_S3_FORCEPATHSTYLE: "true"
      REGISTRY_STORAGE_DELETE_ENABLED: "true"
    volumes:
      - ./auth:/auth:ro
    ports:
      - "5000:5000"
    depends_on:
      - minio
 
volumes:
  minio-data:

Amaliy Use Case'lar

Use Case 1: CI/CD Pipeline integratsiya

Eng keng tarqalgan holat — CI/CD pipeline'da image'larni build qilib, registryga push qilish va production'ga deploy qilish.

┌──────────┐     ┌──────────┐     ┌──────────────┐     ┌──────────────┐
│   Git    │────►│  CI/CD   │────►│   Private    │────►│  Production  │
│  Push    │     │  Build   │     │   Registry   │     │   Server     │
└──────────┘     └──────────┘     └──────────────┘     └──────────────┘
                  docker build     docker push           docker pull
                  docker tag                              docker run

GitLab CI misol

.gitlab-ci.yml
variables:
  REGISTRY: registry.example.com
  IMAGE_NAME: $REGISTRY/backend/api
 
stages:
  - build
  - deploy
 
build:
  stage: build
  image: docker:24
  services:
    - docker:24-dind
  before_script:
    - echo "$REGISTRY_PASSWORD" | docker login $REGISTRY -u $REGISTRY_USER --password-stdin
  script:
    - docker build -t $IMAGE_NAME:$CI_COMMIT_SHORT_SHA .
    - docker tag $IMAGE_NAME:$CI_COMMIT_SHORT_SHA $IMAGE_NAME:latest
    - docker push $IMAGE_NAME:$CI_COMMIT_SHORT_SHA
    - docker push $IMAGE_NAME:latest
  after_script:
    - docker logout $REGISTRY
 
deploy:
  stage: deploy
  script:
    - ssh deploy@production "docker pull $IMAGE_NAME:$CI_COMMIT_SHORT_SHA"
    - ssh deploy@production "docker compose up -d"
  only:
    - main

GitHub Actions misol

.github/workflows/build.yml
name: Build and Push
 
on:
  push:
    branches: [main]
 
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
 
      - name: Login to private registry
        run: |
          echo "${{ secrets.REGISTRY_PASSWORD }}" | \
          docker login registry.example.com -u ${{ secrets.REGISTRY_USER }} --password-stdin
 
      - name: Build and push
        run: |
          IMAGE=registry.example.com/backend/api
          docker build -t $IMAGE:${{ github.sha }} .
          docker tag $IMAGE:${{ github.sha }} $IMAGE:latest
          docker push $IMAGE:${{ github.sha }}
          docker push $IMAGE:latest

Jenkins Pipeline misol

Jenkinsfile
pipeline {
    agent any
 
    environment {
        REGISTRY = 'registry.example.com'
        IMAGE = "${REGISTRY}/backend/api"
        REGISTRY_CREDS = credentials('docker-registry-creds')
    }
 
    stages {
        stage('Build') {
            steps {
                sh "docker build -t ${IMAGE}:${BUILD_NUMBER} ."
                sh "docker tag ${IMAGE}:${BUILD_NUMBER} ${IMAGE}:latest"
            }
        }
 
        stage('Push') {
            steps {
                sh "echo ${REGISTRY_CREDS_PSW} | docker login ${REGISTRY} -u ${REGISTRY_CREDS_USR} --password-stdin"
                sh "docker push ${IMAGE}:${BUILD_NUMBER}"
                sh "docker push ${IMAGE}:latest"
            }
        }
 
        stage('Deploy') {
            steps {
                sh "ssh deploy@production 'docker pull ${IMAGE}:${BUILD_NUMBER}'"
                sh "ssh deploy@production 'cd /opt/app && docker compose up -d'"
            }
        }
    }
 
    post {
        always {
            sh "docker logout ${REGISTRY}"
        }
    }
}

Use Case 2: Air-gapped (internetsiz) muhit

Ba'zi muhitlarda (harbiy, moliyaviy, davlat tizimlar) internet bilan aloqa bo'lmaydi. Bunday holatlarda xususiy registry yagona image manbayi bo'ladi.

Internet bor muhit:                Air-gapped muhit:

┌──────────┐   pull    ┌────────┐  USB/DVD    ┌──────────────┐   pull    ┌─────────┐
│ Docker   │─────────► │ Image  │──────────►  │   Private    │─────────► │ Server  │
│ Hub      │           │ Export │  transfer   │   Registry   │           │ Deploy  │
└──────────┘           └────────┘             └──────────────┘           └─────────┘
# === Internet bor muhitda ===
 
# 1. Kerakli image'larni pull qilish
docker pull nginx:alpine
docker pull postgres:16
docker pull redis:7
 
# 2. Image'larni tar faylga eksport qilish
docker save nginx:alpine postgres:16 redis:7 | gzip > images.tar.gz
 
# 3. Registry image'ini ham eksport qilish
docker save registry:2 | gzip > registry-image.tar.gz
 
# === USB/DVD orqali air-gapped muhitga ko'chirish ===
 
# === Air-gapped muhitda ===
 
# 4. Registry image'ini yuklash
docker load < registry-image.tar.gz
 
# 5. Registryni ishga tushirish
docker run -d -p 5000:5000 --restart=always --name registry registry:2
 
# 6. Image'larni yuklash
docker load < images.tar.gz
 
# 7. Image'larni tag'lab registryga push qilish
docker tag nginx:alpine localhost:5000/nginx:alpine
docker push localhost:5000/nginx:alpine
 
docker tag postgres:16 localhost:5000/postgres:16
docker push localhost:5000/postgres:16
 
docker tag redis:7 localhost:5000/redis:7
docker push localhost:5000/redis:7

Use Case 3: Multi-environment (ko'p muhit) boshqarish

Bitta registry orqali turli muhitlarga deploy qilish:

┌──────────────────────────────────────────────────────────────┐
│                    Private Registry                          │
│                                                              │
│  ┌───────────────────────────────────────────────────────┐   │
│  │  backend/api:v1.2.3          (release)                │   │
│  │  backend/api:v1.2.4-rc1      (release candidate)      │   │
│  │  backend/api:main-abc1234    (CI build)               │   │
│  │  backend/api:staging         (staging deploy)         │   │
│  └───────────────────────────────────────────────────────┘   │
└──────────┬─────────────────┬───────────────────┬─────────────┘
           │                 │                   │
           ▼                 ▼                   ▼
    ┌──────────────┐  ┌──────────────┐  ┌──────────────┐
    │ Development  │  │   Staging    │  │  Production  │
    │              │  │              │  │              │
    │ api:main-*   │  │ api:staging  │  │ api:v1.2.3   │
    └──────────────┘  └──────────────┘  └──────────────┘

Use Case 4: Kubernetes bilan integratsiya

Kubernetes cluster xususiy registrydan image tortishi uchun imagePullSecrets sozlash kerak:

# Kubernetes'da registry credential yaratish
kubectl create secret docker-registry regcred \
  --docker-server=registry.example.com \
  --docker-username=admin \
  --docker-password=S3cur3P@ssw0rd \
  --docker-email=admin@example.com
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      imagePullSecrets:
        - name: regcred
      containers:
        - name: web-app
          image: registry.example.com/backend/api:v1.2.3
          ports:
            - containerPort: 8080

Registry Mirror (Docker Hub mirror)

Agar jamoangiz tez-tez Docker Hub'dan image pull qilsa, registry'ni pull-through cache (mirror) sifatida sozlash mumkin. Bu:

  • Tezlikni oshiradi — bir marta yuklab olingan image keyingi safar mahalliy cache'dan olinadi
  • Docker Hub rate limit'dan himoyalaydi — bepul rejada soatiga 100 pull cheklovi bor
  • Internet trafigini kamaytiradi — ayniqsa ko'p serverli muhitlarda foydali

Mirror konfiguratsiya

config.yml
version: 0.1
proxy:
  remoteurl: https://registry-1.docker.io
  username: dockerhub_user
  password: dockerhub_token
storage:
  filesystem:
    rootdirectory: /var/lib/registry
  delete:
    enabled: true
http:
  addr: :5000
# Mirror registryni ishga tushirish
docker run -d \
  -p 5000:5000 \
  --restart=always \
  --name registry-mirror \
  -v ./config.yml:/etc/docker/registry/config.yml \
  -v mirror-data:/var/lib/registry \
  registry:2

Docker daemon'ni mirror'dan foydalanishga sozlash:

/etc/docker/daemon.json
{
  "registry-mirrors": ["http://mirror.example.com:5000"]
}
sudo systemctl restart docker
 
# Endi docker pull nginx aslida mirror orqali olinadi
docker pull nginx:alpine  # birinchi marta — Docker Hub'dan, keyingi safar — cache'dan

Xavfsizlik bo'yicha eng yaxshi amaliyotlar

1. Har doim TLS ishlating

Xato:   http://registry:5000   (shifrlanmagan, man-in-the-middle xavfi)
To'g'ri: https://registry:443   (TLS bilan shifrlangan)

2. Minimal imtiyozli foydalanuvchilar

# Turli rollar uchun alohida foydalanuvchilar
# CI/CD bot — faqat push/pull qila oladi
docker run --entrypoint htpasswd registry:2 -Bbn cicd-bot P@ssw0rd >> auth/htpasswd
 
# Developer — faqat pull qila oladi (Harbor yoki Nexus kerak)
# htpasswd oddiy autentifikatsiya — rol asosidagi nazorat uchun Harbor tavsiya etiladi

3. Image'larni xavfsizlik zaifliklariga tekshirish

# Trivy bilan image skanerlash (tavsiya etiladi)
# O'rnatish: https://aquasecurity.github.io/trivy/
trivy image registry.example.com/backend/api:v1.2.3
 
# Natija misoli:
# Total: 2 (HIGH: 1, CRITICAL: 1)
# ┌───────────────┬───────────────┬──────────┬─────────────────┐
# │   Library     │ Vulnerability │ Severity │ Fixed Version   │
# ├───────────────┼───────────────┼──────────┼─────────────────┤
# │ openssl       │ CVE-2024-XXX  │ CRITICAL │ 3.1.5           │
# │ curl          │ CVE-2024-YYY  │ HIGH     │ 8.5.0           │
# └───────────────┴───────────────┴──────────┴─────────────────┘

4. Image signing (imzolash)

# Cosign bilan image imzolash (Sigstore loyihasi)
# O'rnatish: https://docs.sigstore.dev/cosign/installation/
 
# Kalit juftini yaratish
cosign generate-key-pair
 
# Image'ni imzolash
cosign sign --key cosign.key registry.example.com/backend/api:v1.2.3
 
# Imzoni tekshirish
cosign verify --key cosign.pub registry.example.com/backend/api:v1.2.3

5. Xavfsizlik tekshiruv ro'yxati

TekshiruvTavsif
TLS/SSL sertifikatBarcha ulanishlar shifrlangan
AutentifikatsiyaLogin talab qilinadi
FirewallFaqat kerakli portlar ochiq (443)
Image scanningCI/CD'da avtomatik skanerlash
BackupRegistr ma'lumotlari muntazam backup'lanadi
MonitoringDisk, CPU, tarmoq monitoringi
GCEski image'lar muntazam tozalanadi
Access logKim qachon nima push/pull qilganini kuzatish

Monitoring va troubleshooting

Registry loglarini tekshirish

# Docker Compose loglar
docker compose logs registry
docker compose logs -f --tail=100 registry
 
# Muayyan xatolarni qidirish
docker compose logs registry 2>&1 | grep -i error

Disk ishlatilishini tekshirish

# Registry data hajmi
du -sh data/
 
# Eng katta repository'lar
du -sh data/docker/registry/v2/repositories/* | sort -rh | head -10

Ko'p uchraydigan muammolar va yechimlari

Muammo 1: Get https://registry:5000/v2/: http: server gave HTTP response to HTTPS client

# Yechim: insecure-registries qo'shish yoki TLS sozlash
sudo nano /etc/docker/daemon.json
# {"insecure-registries": ["registry:5000"]}
sudo systemctl restart docker

Muammo 2: unauthorized: authentication required

# Yechim: login qilish
docker login registry.example.com
 
# Yoki credential'lar to'g'riligini tekshirish
curl -u admin:password https://registry.example.com/v2/

Muammo 3: error parsing HTTP 413 response body: invalid character '<'

# Yechim: Nginx'da client_max_body_size ni oshirish
# nginx.conf: client_max_body_size 2G;

Muammo 4: blob upload unknown yoki manifest unknown

# Yechim: Garbage collection ishga tushirish va restart qilish
docker exec registry bin/registry garbage-collect /etc/docker/registry/config.yml
docker restart registry

Docker Registry vs Harbor — qiyoslash

Agar sizga oddiy registrydan ko'proq funksionallik kerak bo'lsa, Harbor ni ko'rib chiqing.

XususiyatDocker RegistryHarbor
Image saqlash
Autentifikatsiyahtpasswd (oddiy)LDAP, OIDC, Robot accounts
Kirish nazorati (RBAC)✅ (loyiha darajasida)
Vulnerability scanning✅ (Trivy integratsiya)
Image signing✅ (Cosign/Notary)
Replikatsiya✅ (ko'p registry o'rtasida)
Web UI
Garbage CollectionCLI orqaliWeb UI orqali
Helm chart saqlash
Audit logOddiyTo'liq
O'rnatish murakkabligiOddiyO'rta
Resurs talabiMinimal (~50MB RAM)O'rta (~1-2GB RAM)

Tavsiya: Agar faqat image push/pull kerak bo'lsa — Docker Registry yetarli. Agar xavfsizlik skanerlash, RBAC, Web UI va replikatsiya kerak bo'lsa — Harbor ni tanlang. Harbor haqida batafsil: goharbor.io (opens in a new tab)


Xulosa

Docker Registry — zamonaviy DevOps infratuzilmasining muhim tarkibiy qismi. Bu qo'llanmada siz quyidagilarni o'rgandingiz:

  • Registry arxitekturasi — image manifest va layer'lar qanday saqlanadi
  • Registry turlari — public, cloud, self-hosted variantlar
  • Production o'rnatish — TLS, autentifikatsiya, Nginx reverse proxy bilan
  • CI/CD integratsiya — GitLab CI, GitHub Actions, Jenkins bilan
  • Garbage Collection — disk joyini bo'shatish
  • Storage backend — S3, MinIO va boshqa variantlar
  • Xavfsizlik — TLS, image scanning, signing
  • Amaliy use case'lar — air-gapped muhit, multi-environment, Kubernetes

Keyingi qadamlar:

  1. Dockerga Kirish (opens in a new tab) — Docker asoslarini o'rganing
  2. Linux serverlarga Docker o'rnatish (opens in a new tab) — Docker o'rnating
  3. Dockerfile yozish (opens in a new tab) — o'z image'laringizni yarating
  4. Docker buyruqlari (opens in a new tab) — Docker CLI'ni o'rganing

Qo'shimcha