with one click
sync-image-aliyun
// Use when syncing apecloud DockerHub images to Aliyun registry or ACR for restricted IDC/China network environments and verifying registry availability.
// Use when syncing apecloud DockerHub images to Aliyun registry or ACR for restricted IDC/China network environments and verifying registry availability.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | sync-image-aliyun |
| description | Use when syncing apecloud DockerHub images to Aliyun registry or ACR for restricted IDC/China network environments and verifying registry availability. |
Reference resolution: when this source-derived skill mentions docs/..., resolve it from the shared support package beside the installed user skills: ~/.codex/skills/kubeblocks-addon-source-docs/docs/... for Codex or ~/.claude/skills/kubeblocks-addon-source-docs/docs/... for Claude Code. In the shared kubeblocks-addon-docs checkout, the same files live under skills/kubeblocks-addon-source-docs/docs/.... When it mentions scripts/..., resolve it from the same support package under scripts/.... If you are working inside a checkout of the original apecloud/kubeblocks-addon-skills, repo-relative paths are also valid.
Sync a Docker image from the apecloud Docker Hub organization to the Aliyun container registry configured in .env.
Usage: /sync-image-aliyun <image-name>:<tag> [--arch amd64|arm64] [--namespace <ns>]
Examples:
/sync-image-aliyun elasticsearch:8.17.4/sync-image-aliyun redis:7.2.11 --arch amd64/sync-image-aliyun postgresql:16.3 --namespace mynsSource is always docker.io/apecloud/<image>:<tag>.
Target is $ALIYUN_IMAGE_REGISTRY/<namespace>/<image>:<tag> (default namespace: apecloud).
Arguments: $ARGUMENTS
SCRIPT_DIR="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
[ -f "$SCRIPT_DIR/.env" ] && source "$SCRIPT_DIR/.env"
: "${ALIYUN_DOCKER_USERNAME:?'.env is missing ALIYUN_DOCKER_USERNAME'}"
: "${ALIYUN_DOCKER_PASSWORD:?'.env is missing ALIYUN_DOCKER_PASSWORD'}"
: "${ALIYUN_IMAGE_REGISTRY:?'.env is missing ALIYUN_IMAGE_REGISTRY'}"
echo "Aliyun registry : $ALIYUN_IMAGE_REGISTRY"
echo "Aliyun user : $ALIYUN_DOCKER_USERNAME"
Parse <image>:<tag>, optional --arch, and optional --namespace from $ARGUMENTS.
<image> is just the image name without any registry or org prefix, e.g. elasticsearch<tag> is the version tag, e.g. 8.17.4--arch (optional): amd64 or arm64--namespace (optional): Aliyun namespace (default: apecloud)Derived variables:
SOURCE=docker.io/apecloud/<image>:<tag>
ALIYUN_NS=<namespace or "apecloud">
TARGET=$ALIYUN_IMAGE_REGISTRY/$ALIYUN_NS/<image>:<tag>
Use skopeo inspect if available, otherwise skip the check and proceed.
if command -v skopeo &>/dev/null; then
if skopeo inspect \
--creds "$ALIYUN_DOCKER_USERNAME:$ALIYUN_DOCKER_PASSWORD" \
"docker://$TARGET" &>/dev/null; then
echo "Image $TARGET already exists in Aliyun registry. Skipping sync."
exit 0
fi
echo "Target image not found in Aliyun. Proceeding with sync..."
else
echo "skopeo not found — skipping existence check, proceeding with sync..."
fi
TOKEN=$(curl -s \
"https://auth.docker.io/token?service=registry.docker.io&scope=repository:apecloud/<image>:pull" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['token'])")
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -I \
-H "Authorization: Bearer $TOKEN" \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
"https://registry.hub.docker.com/v2/apecloud/<image>/manifests/<tag>")
if [ "$STATUS" != "200" ]; then
echo "Source image $SOURCE not found on Docker Hub (HTTP $STATUS). Aborting."
exit 1
fi
echo "Source image confirmed on Docker Hub (HTTP $STATUS)."
if command -v skopeo &>/dev/null; then
# Default to amd64/linux so skopeo does not try to match the host arch
# (fails on macOS arm64 when the source manifest has only linux/amd64 layers).
# If --arch was explicitly passed, honour it instead.
ARCH_OVERRIDE="${ARCH:-amd64}"
ARCH_FLAG="--override-arch $ARCH_OVERRIDE --override-os linux"
skopeo copy $ARCH_FLAG \
--src-no-creds \
--dest-username "$ALIYUN_DOCKER_USERNAME" \
--dest-password "$ALIYUN_DOCKER_PASSWORD" \
"docker://$SOURCE" \
"docker://$TARGET"
SYNC_STATUS=$?
else
PULL_FLAG=""
[ -n "$ARCH" ] && PULL_FLAG="--platform linux/$ARCH"
# Login to Aliyun
echo "$ALIYUN_DOCKER_PASSWORD" | \
docker login "$ALIYUN_IMAGE_REGISTRY" \
-u "$ALIYUN_DOCKER_USERNAME" --password-stdin
docker pull $PULL_FLAG "$SOURCE"
docker tag "$SOURCE" "$TARGET"
docker push "$TARGET"
SYNC_STATUS=$?
# Cleanup local copies
docker rmi "$SOURCE" "$TARGET" 2>/dev/null || true
fi
if [ "$SYNC_STATUS" -eq 0 ]; then
# Confirm image is inspectable in Aliyun
if command -v skopeo &>/dev/null; then
skopeo inspect \
--creds "$ALIYUN_DOCKER_USERNAME:$ALIYUN_DOCKER_PASSWORD" \
"docker://$TARGET" \
--format "Digest: {{.Digest}}" 2>/dev/null \
&& echo "Verification passed." \
|| echo "Warning: push succeeded but post-verify inspect failed."
fi
echo ""
echo "Sync complete:"
echo " Source : $SOURCE"
echo " Target : $TARGET"
else
echo "Sync FAILED (exit $SYNC_STATUS). Check errors above."
exit 1
fi