由于大家都知道的原因,我们在拉取一些镜像的时候,可以通过国内的代理镜像站拉取。在使用南京大学代理站拉取 gcr,ghcr 等源的时候,需要替换前缀,手动处理又比较麻烦。可以将镜像替换逻辑直接集成到
docker
命令中,通过覆盖docker pull
的行为实现无缝替换。以下是实现方案,将其添加到~/.bashrc
或~/.zshrc
中:
1. 将镜像替换逻辑写入 Shell 配置文件
打开 ~/.bashrc
(或 ~/.zshrc
),在文件末尾添加以下代码:
# Docker 镜像前缀替换规则
declare -A DOCKER_REPLACE_RULES=(
["k8s.gcr.io/"]="gcr.nju.edu.cn/google-containers/" # 优先处理带路径的规则
["gcr.io/"]="gcr.nju.edu.cn/"
["ghcr.io/"]="ghcr.nju.edu.cn/"
["nvcr.io/"]="ngc.nju.edu.cn/"
["quay.io/"]="quay.nju.edu.cn/"
)
# 覆盖 docker 命令,自动处理镜像名称替换
docker() {
# 仅拦截 docker pull 命令
if [ "$1" = "pull" ]; then
local original_image="${*:2}"
local target_image="$original_image"
local has_replaced=false
# 应用替换规则
for source in "${!DOCKER_REPLACE_RULES[@]}"; do
local target="${DOCKER_REPLACE_RULES[$source]}"
if [[ "$original_image" == "$source"* ]]; then
target_image="${target}${original_image#$source}"
has_replaced=true
break
fi
done
if $has_replaced; then
# 显示替换信息并拉取镜像
echo -e "\033[33m镜像替换: $original_image => $target_image\033[0m"
command docker pull "$target_image"
# 重命名镜像并清理中间标签
if [ $? -eq 0 ]; then
command docker tag "$target_image" "$original_image"
command docker rmi "$target_image" >/dev/null 2>&1
echo -e "\033[32m镜像重命名完成: $original_image\033[0m"
return 0
else
echo -e "\033[31m镜像拉取失败: $original_image\033[0m"
return 1
fi
else
# 无替换时直接拉取原镜像
command docker pull "$original_image"
fi
return $?
fi
# 其他命令直接调用原生 docker
command docker "$@"
}
2. 使配置生效
source ~/.bashrc # 或 source ~/.zshrc
3. 使用示例
# 直接使用原始镜像名拉取,自动替换并重命名
docker pull k8s.gcr.io/pause:3.2
docker pull ghcr.io/open-webui/open-webui:main
# 其他命令不受影响
docker ps -a
docker build -t myapp .
功能特性
-
无缝集成
- 直接使用
docker pull
命令,无需记忆脚本路径或镜像替换规则。 - 自动处理多镜像拉取(如
docker pull image1 image2
)。
- 直接使用
-
智能重命名
- 拉取后自动将镜像标签恢复为原始名称。
- 自动清理中间镜像标签,避免冗余。
-
安全兼容
- 仅拦截
docker pull
命令,其他命令(如docker run
、docker build
)不受影响。 - 保留原生 Docker 的所有功能。
- 仅拦截
-
彩色输出
- 黄色显示镜像替换信息。
- 绿色显示重命名完成提示,红色显示错误信息。
验证方法
# 查看镜像列表(应显示原始名称)
docker images
# 检查镜像标签对应关系
docker inspect k8s.gcr.io/pause:3.2 | grep -E 'RepoTags|RepoDigests'
扩展配置
(1) 临时禁用替换功能
若需临时使用原生 docker pull
,可通过转义命令实现:
# 方法一:使用完整路径
/usr/bin/docker pull ghcr.io/open-webui/open-webui:main
# 方法二:调用 command 原生命令
command docker pull ghcr.io/open-webui/open-webui:main
(2) 自定义日志输出
修改 .bashrc
中的 echo
语句,或添加日志文件记录:
# 记录到日志文件
echo "$(date '+%Y-%m-%d %H:%M:%S') Pull $original_image => $target_image" >> ~/.docker_pull.log
总结
将此配置集成到 Shell 环境后,用户无需改变原有操作习惯即可享受镜像加速功能,是比独立脚本更优雅的解决方案。
评论区