Cloud Native 8 min read

Automate Docker Image Mirroring to CNB with GitHub Actions and skopeo

This guide explains how to set up a fully automated pipeline that syncs Docker Hub images to the CNB registry using GitHub Actions, skopeo, and configurable YAML files, supporting selective or full mirroring, version overrides, and secure credential handling.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
Automate Docker Image Mirroring to CNB with GitHub Actions and skopeo

Mirroring frequently used open‑source Docker images to a China‑accessible registry improves download speed, stability, and avoids unreliable official sources.

Background

Docker Hub often suffers from network latency, rate limits, or connection failures, making image pulls unreliable. The previous workflow synced images to CODING, which has been discontinued, so the target registry was switched to CNB (cnb.cool), a Tencent‑backed cloud‑native registry.

Sync Overview

The list of images to mirror is stored in .github/images.yml.

The sync can be triggered manually or automatically via GitHub Actions.

The skopeo tool copies images from Docker Hub to CNB.

Both selective (single image) and full (all images) syncs are supported.

Specific tags can be overridden at runtime.

GitHub Actions Workflow

The workflow file docker-proxy.yml defines two inputs ( name and version), runs on ubuntu-latest, and performs the following steps:

name: Mirror Docker Images to CNB
on:
  workflow_dispatch:
    inputs:
      name:
        description: 'Select image to mirror (or leave blank to mirror all)'
        required: false
        type: choice
        options:
          - ""
          - vaultwarden
          - bark-server
          - elasticsearch
          - mysql
          - hyperf
          - clickhouse
      version:
        description: 'Override tag version'
        required: false
        type: string
push:
  paths:
    - '.github/images.yml'
  branches: ['main']
jobs:
  mirror:
    name: >-
      Mirror ${{ github.event.inputs.name || 'All Images' }}${{ github.event.inputs.version && format(' (version: {0})', github.event.inputs.version) || '' }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Mirror images
        env:
          INPUT_NAME: ${{ github.event.inputs.name }}
          INPUT_VERSION: ${{ github.event.inputs.version }}
        run: |
          images=$(yq -o json '.images' ${{ github.workspace }}/.github/images.yml)
          if [ -n "$INPUT_NAME" ]; then
            matrix=$(echo "$images" | jq -c --arg name "$INPUT_NAME" '.[] | select(.name == $name)')
          else
            matrix=$(echo "$images" | jq -c '.[]')
          fi
          if [ -z "$matrix" ]; then
            echo "No matching images found for name: $INPUT_NAME"
            exit 1
          fi
          echo "$matrix" | while read -r item; do
            image=$(echo "$item" | jq -r '.image')
            name=$(echo "$item" | jq -r '.name')
            default_tag=$(echo "$item" | jq -r '.tag')
            tag=${INPUT_VERSION:-$default_tag}
            echo "Mirroring $image:$tag to docker.cnb.cool/lufei/docker/$name:$tag"
            skopeo copy --all docker://docker.io/${image}:${tag} \
              docker://docker.cnb.cool/lufei/docker/${name}:${tag} \
              --src-creds "${{ secrets.DOCKERHUB_USERNAME }}:${{ secrets.DOCKERHUB_TOKEN }}" \
              --dest-creds "cnb:${{ secrets.CNB_DOCKER_TOKEN }}"
            echo "::notice title=Image Published::https://docker.cnb.cool/lufei/docker/${name}:${tag}"
          done

Trigger Mechanisms

Manual trigger : Run the workflow from the GitHub Actions UI, optionally specifying an image name and tag.

Automatic trigger : Any change to .github/images.yml on the main branch automatically starts a full sync.

Image List File

The .github/images.yml file defines each source image, its default tag, and a short name used for the target repository:

images:
  - image: "vaultwarden/server"
    tag: "latest"
    name: "vaultwarden"
  - image: "finab/bark-server"
    tag: "latest"
    name: "bark-server"
  # ... more entries ...

Core Sync Command

skopeo copy --all docker://docker.io/${image}:${tag} \
  docker://docker.cnb.cool/lufei/docker/${name}:${tag} \
  --src-creds "${{ secrets.DOCKERHUB_USERNAME }}:${{ secrets.DOCKERHUB_TOKEN }}" \
  --dest-creds "cnb:${{ secrets.CNB_DOCKER_TOKEN }}"
--all

ensures multi‑architecture images (e.g., amd64, arm64) are mirrored.

Credentials are supplied via GitHub Secrets for security.

After each successful copy, the workflow prints a direct pull URL.

How to Use

Manual Trigger

Navigate to GitHub → Actions → Mirror Docker Images to CNB → Run workflow . Leave the image name empty to sync all images, or specify a name and optional tag to sync a single image.

Automatic Trigger

Whenever .github/images.yml is updated and pushed to the main branch, the workflow runs automatically and mirrors all listed images.

Pulling Mirrored Images

After a successful sync, pull images directly from the CNB public endpoint:

docker pull docker.cnb.cool/lufei/docker/hyperf:8.3-alpine-v3.21-swoole

Appending https:// to the URL opens a web page with image details.

Secure Configuration (GitHub Secrets)

DOCKERHUB_USERNAME

: Username for pulling source images from Docker Hub. DOCKERHUB_TOKEN: Docker Hub authentication token. CNB_DOCKER_TOKEN: Credential for pushing to the CNB registry.

CNB stores Docker artifacts directly in the repository, so creating a repository is sufficient for Docker images.

Conclusion

Combining GitHub Actions, skopeo, and the CNB service provides a reusable, automated pipeline that reliably mirrors multiple Docker images, significantly improving image availability and deployment efficiency.

References

CNB registry: https://cnb.cool/ .github/images.yml file: https://github.com/sy-records/.github/blob/main/.github/images.yml

Workflow definition docker-proxy.yml: https://github.com/sy-records/.github/blob/main/.github/workflows/docker-proxy.yml

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Dockerci/cdCNBGitHub Actionsskopeoimage mirroring
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.