目錄表

建立與設定 DockerHub Proxy

registry:2 方案(適合小型服務情境)

  1. 檔案配置結構

    .
    ├── cleanup.sh
    ├── config
    │   └─── config.yml
    ├── data
    ├── .env
    └─── docker-compose.yml

  2. 產生 REGISTRY_HTTP_SECRET

    dockerhub-184:~# openssl rand -hex 16
    005311c1d394ec958d6e1966bf43b4d3

  3. 建立 .env 環境變數設定

    vi .env

    https://raw.githubusercontent.com/tryweb/docker-compose/refs/heads/main/docker-registry/env.example
    # openssl rand -hex 16
    REGISTRY_HTTP_SECRET=005311c1d394ec958d6e1966bf43b4d3
    # 清理超過 7 天未訪問的資料
    CLEANUP_DAYS_OLD=7

    https://raw.githubusercontent.com/tryweb/docker-compose/refs/heads/main/docker-registry/env.example

  4. 建立 cleanup.sh

    vi cleanup.sh

    https://raw.githubusercontent.com/tryweb/docker-compose/refs/heads/main/docker-registry/cleanup.sh
    #!/bin/sh
     
    # Registry 清理腳本
    # 此腳本會清理超過 7 天未訪問的資料
     
    REGISTRY_DATA_DIR="/var/lib/registry"
    LOG_FILE="/tmp/registry-cleanup.log"
     
    # 從環境變數讀取清理天數,如果未設定,則預設為 7 天
    DAYS_OLD=${CLEANUP_DAYS_OLD:-7}
     
    # 創建日志函數
    log() {
        echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
    }
     
    log "開始執行 Registry 清理作業..."
    log "清理天數設定為: $DAYS_OLD 天"
     
    # 檢查 registry 資料目錄是否存在
    if [ ! -d "$REGISTRY_DATA_DIR" ]; then
        log "錯誤: Registry 資料目錄不存在: $REGISTRY_DATA_DIR"
        exit 1
    fi
     
    # 計算清理前的磁碟使用量
    BEFORE_SIZE=$(du -sh "$REGISTRY_DATA_DIR" | cut -f1)
    log "清理前磁碟使用量: $BEFORE_SIZE"
     
    # 清理超過指定天數未訪問的 blob 檔案
    log "正在清理超過 $DAYS_OLD 天未訪問的檔案..."
    DELETED_COUNT=$(find "$REGISTRY_DATA_DIR" -name "data" -type f -atime +$DAYS_OLD -print | wc -l)
     
    if [ "$DELETED_COUNT" -gt 0 ]; then
        find "$REGISTRY_DATA_DIR" -name "data" -type f -atime +$DAYS_OLD -delete
        log "已刪除 $DELETED_COUNT 個過期的 blob 檔案"
    else
        log "沒有找到需要清理的過期檔案"
    fi
     
    # 執行 registry 垃圾回收
    log "執行 Registry 垃圾回收..."
    if registry garbage-collect /etc/docker/registry/config.yml; then
        log "垃圾回收執行成功"
    else
        log "警告: 垃圾回收執行失敗"
    fi
     
    # 計算清理後的磁碟使用量
    AFTER_SIZE=$(du -sh "$REGISTRY_DATA_DIR" | cut -f1)
    log "清理後磁碟使用量: $AFTER_SIZE"
     
    # 清理空的目錄
    log "清理空目錄..."
    find "$REGISTRY_DATA_DIR" -type d -empty -delete 2>/dev/null || true
     
    log "Registry 清理作業完成"
    log "----------------------------------------"
     

    https://raw.githubusercontent.com/tryweb/docker-compose/refs/heads/main/docker-registry/cleanup.sh

  5. 建立 config.yml

    mkdir -p config
    vi config/config.yml

    https://raw.githubusercontent.com/tryweb/docker-compose/refs/heads/main/docker-registry/config/config.yml
    version: 0.1
    log:
      accesslog:
        disabled: false
      level: info
      formatter: text
      fields:
        service: registry_proxy
     
    storage:
      delete:
        enabled: true
      maintenance:
        uploadpurging:
          enabled: true
          age: 168h        # 7天後清理未完成的上傳
          interval: 24h    # 每24小時檢查一次
          dryrun: false
      cache:
        blobdescriptor: inmemory
      filesystem:
        rootdirectory: /var/lib/registry
        maxthreads: 100
     
    http:
      addr: :5000
      headers:
        X-Content-Type-Options: [nosniff]
     
    proxy:
      remoteurl: https://registry-1.docker.io
      # 如果需要認證到 Docker Hub,取消註解下面兩行
      # username: your-dockerhub-username
      # password: your-dockerhub-password
     
    # 健康檢查配置
    health:
      storagedriver:
        enabled: true
        interval: 10s
        threshold: 3
     

    https://raw.githubusercontent.com/tryweb/docker-compose/refs/heads/main/docker-registry/config/config.yml

  6. 建立 image 存放路徑

    mkdir -p data

  7. 建立 docker-compose.yml

    vi docker-compose.yml

    https://raw.githubusercontent.com/tryweb/docker-compose/refs/heads/main/docker-registry/docker-compose.yml
    services:
      registry_proxy:
        image: registry:2
        container_name: registry_proxy
        ports:
          - "5000:5000"
        volumes:
          - ./config:/etc/docker/registry
          - ./data:/var/lib/registry
        environment:
          # 設定固定的 HTTP secret
          - REGISTRY_HTTP_SECRET=${REGISTRY_HTTP_SECRET}
        restart: unless-stopped
        healthcheck:
          test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:5000/v2/"]
          interval: 30s
          timeout: 10s
          retries: 3
          start_period: 40s
     
      # 清理服務 - 定期執行垃圾回收
      registry_cleaner:
        image: registry:2
        container_name: registry_cleaner
        volumes:
          - ./config:/etc/docker/registry
          - ./data:/var/lib/registry
          - ./cleanup.sh:/cleanup.sh:ro
        environment:
          - CLEANUP_DAYS_OLD=${CLEANUP_DAYS_OLD}
        command: /bin/sh -c "while true; do sleep 86400; /cleanup.sh; done"
        depends_on:
          - registry_proxy
        restart: unless-stopped
     

    https://raw.githubusercontent.com/tryweb/docker-compose/refs/heads/main/docker-registry/docker-compose.yml

  8. 啟動服務與查看 log

    docker compose up -d
    docker compose logs -f

  9. 測試服務

    curl -I http://localhost:5000/v2/

    • 應該可以看到類似以下的訊息

      dockerhub-184:~# curl -I http://localhost:5000/v2/
      HTTP/1.1 200 OK
      Content-Length: 2
      Content-Type: application/json; charset=utf-8
      Docker-Distribution-Api-Version: registry/2.0
      X-Content-Type-Options: nosniff
      Date: Mon, 09 Jun 2025 09:43:05 GMT

  10. 其他測試服務命令

    # 查看目前緩存的 repositories
    curl -X GET http://localhost:5000/v2/_catalog
    
    # 手動執行清理腳本
    docker exec registry_cleaner /cleanup.sh

其他主機設定 /etc/docker/daemon.json

  1. 編輯 /etc/docker/daemon.json
    {
      "registry-mirrors": [
        "http://192.168.11.184:5000"
      ],
      "insecure-registries": [
        "192.168.11.184:5000"
      ]
    }
  2. 重啟 docker

    service docker restart

  3. 確認設定是否生效

    docker info

    • 看執行內容是否出現 http://192.168.11.184:5000
  4. 執行 docker pull 驗證

    docker pull alpine

  5. 如果成功 pull image, 可以回到 registry:2 服務主機 Exp. 192.168.11.184 查看 data/docker/registry/v2/repositories/ 內是否出現 alpine
    • 看 tree data/docker/registry/v2/repositories/ 的目錄結構

Harbor 方案(適合大型服務情境)

參考網址