Files
dock/Docker 加速
2026-01-02 13:33:14 +08:00

618 lines
18 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# Docker镜像源配置脚本
# 描述: 配置Docker使用不同的镜像源支持私有仓库可选认证和公共镜像源
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# 默认私有仓库配置(用户可自定义)
DEFAULT_PRIVATE_REGISTRY="github.vps7k7k.xyz"
DEFAULT_PRIVATE_MIRROR="https://github.vps7k7k.xyz"
# 备用镜像源
ALIYUN_MIRROR="https://registry.cn-hangzhou.aliyuncs.com"
DOCKER_HUB_MIRROR="https://hub-mirror.c.163.com"
USTC_MIRROR="https://docker.mirrors.ustc.edu.cn"
TENCENT_MIRROR="https://mirror.ccs.tencentyun.com"
# 打印彩色信息
print_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
print_step() {
echo -e "${BLUE}[STEP]${NC} $1"
}
print_choice() {
echo -e "${PURPLE}[CHOICE]${NC} $1"
}
print_config() {
echo -e "${CYAN}[CONFIG]${NC} $1"
}
# 检查Docker是否安装
check_docker() {
if ! command -v docker &> /dev/null; then
print_error "Docker 未安装请先安装Docker"
exit 1
fi
print_info "Docker 已安装,版本: $(docker --version | cut -d' ' -f3 | cut -d',' -f1)"
}
# 获取私有仓库配置
get_private_registry_config() {
echo
print_step "配置私有仓库"
# 询问是否使用私有仓库
read -p "是否使用私有仓库?(y/N): " use_private
if [[ ! $use_private =~ ^[Yy]$ ]]; then
PRIVATE_REGISTRY=""
PRIVATE_MIRROR=""
NEED_AUTH="no"
return 0
fi
# 输入私有仓库域名
read -p "请输入私有仓库域名/地址 [默认: $DEFAULT_PRIVATE_REGISTRY]: " registry_input
if [ -z "$registry_input" ]; then
PRIVATE_REGISTRY="$DEFAULT_PRIVATE_REGISTRY"
PRIVATE_MIRROR="$DEFAULT_PRIVATE_MIRROR"
else
PRIVATE_REGISTRY="$registry_input"
# 自动构建镜像URL添加https前缀如果不是完整URL
if [[ "$registry_input" =~ ^https?:// ]]; then
PRIVATE_MIRROR="$registry_input"
else
PRIVATE_MIRROR="https://$registry_input"
fi
fi
print_info "私有仓库地址: $PRIVATE_REGISTRY"
print_info "镜像地址: $PRIVATE_MIRROR"
# 询问是否需要认证
read -p "私有仓库是否需要认证登录?(y/N): " need_auth
if [[ $need_auth =~ ^[Yy]$ ]]; then
NEED_AUTH="yes"
get_private_credentials
else
NEED_AUTH="no"
print_info "私有仓库无需认证"
fi
}
# 交互式输入私有仓库账号密码
get_private_credentials() {
print_step "请输入私有仓库的认证信息"
while true; do
read -p "请输入用户名: " PRIVATE_USERNAME
if [ -n "$PRIVATE_USERNAME" ]; then
break
else
print_error "用户名不能为空,请重新输入"
fi
done
while true; do
read -s -p "请输入密码: " PRIVATE_PASSWORD
echo
if [ -n "$PRIVATE_PASSWORD" ]; then
break
else
print_error "密码不能为空,请重新输入"
fi
done
# 确认密码
while true; do
read -s -p "请再次输入密码确认: " password_confirm
echo
if [ "$PRIVATE_PASSWORD" = "$password_confirm" ]; then
break
else
print_error "两次输入的密码不一致,请重新输入"
fi
done
}
# 测试私有仓库登录
test_private_login() {
if [ "$NEED_AUTH" != "yes" ]; then
return 0
fi
print_step "测试登录私有仓库..."
if echo "$PRIVATE_PASSWORD" | docker login $PRIVATE_REGISTRY -u "$PRIVATE_USERNAME" --password-stdin; then
print_info "私有仓库登录测试成功!"
return 0
else
print_error "私有仓库登录测试失败"
return 1
fi
}
# 显示镜像源选择菜单
show_mirror_menu() {
echo
print_step "请选择要使用的Docker镜像源配置"
echo "=========================================="
if [ -n "$PRIVATE_REGISTRY" ]; then
print_choice "1. 私有仓库为主 + 多个备用源(推荐)"
echo " - 主源: ${PRIVATE_REGISTRY}"
echo " - 备源: 阿里云、网易、中科大、腾讯云"
echo " - Docker自动选择最快可用源"
print_choice "2. 仅私有仓库"
echo " - 只使用 ${PRIVATE_REGISTRY}"
echo " - 访问速度最快"
print_choice "3. 私有仓库 + 公共镜像源混合"
echo " - 使用私有仓库和部分公共镜像源"
print_choice "4. 仅公共镜像源"
echo " - 不使用私有仓库"
echo " - 使用阿里云、网易、中科大、腾讯云"
print_choice "5. 官方Docker Hub"
echo " - 官方源,镜像最全"
echo " - 国外源,访问可能较慢"
else
print_choice "1. 仅公共镜像源"
echo " - 使用阿里云、网易、中科大、腾讯云"
print_choice "2. 官方Docker Hub"
echo " - 官方源,镜像最全"
echo " - 国外源,访问可能较慢"
print_choice "3. 自定义公共镜像源"
echo " - 手动选择公共镜像源组合"
fi
echo "=========================================="
}
# 获取用户选择的镜像源
get_mirror_choice() {
if [ -n "$PRIVATE_REGISTRY" ]; then
# 有私有仓库的情况
while true; do
read -p "请输入选择 (1-5): " choice
case $choice in
1)
MIRROR_TYPE="private_primary"
MIRROR_NAME="私有仓库为主 + 多个备用源"
break
;;
2)
MIRROR_TYPE="private_only"
MIRROR_NAME="仅私有仓库"
break
;;
3)
MIRROR_TYPE="mixed"
MIRROR_NAME="私有仓库 + 公共镜像源混合"
break
;;
4)
MIRROR_TYPE="public_only"
MIRROR_NAME="仅公共镜像源"
break
;;
5)
MIRROR_TYPE="official"
MIRROR_NAME="官方Docker Hub"
break
;;
*)
print_error "无效选择,请输入 1-5 的数字"
;;
esac
done
else
# 无私有仓库的情况
while true; do
read -p "请输入选择 (1-3): " choice
case $choice in
1)
MIRROR_TYPE="public_only"
MIRROR_NAME="仅公共镜像源"
break
;;
2)
MIRROR_TYPE="official"
MIRROR_NAME="官方Docker Hub"
break
;;
3)
MIRROR_TYPE="custom_public"
MIRROR_NAME="自定义公共镜像源"
break
;;
*)
print_error "无效选择,请输入 1-3 的数字"
;;
esac
done
fi
}
# 混合配置选择(私有+部分公共)
get_mixed_config() {
echo
print_step "选择要添加的公共镜像源(可多选):"
MIRRORS=("$PRIVATE_MIRROR")
echo "1) 阿里云镜像"
echo "2) 网易云镜像"
echo "3) 中科大镜像"
echo "4) 腾讯云镜像"
echo "5) 官方Docker Hub"
read -p "请输入选择多个用空格分隔1 2 3: " public_choices
for choice in $public_choices; do
case $choice in
1)
MIRRORS+=("$ALIYUN_MIRROR")
print_info "已添加阿里云镜像"
;;
2)
MIRRORS+=("$DOCKER_HUB_MIRROR")
print_info "已添加网易云镜像"
;;
3)
MIRRORS+=("$USTC_MIRROR")
print_info "已添加中科大镜像"
;;
4)
MIRRORS+=("$TENCENT_MIRROR")
print_info "已添加腾讯云镜像"
;;
5)
MIRRORS+=("https://registry-1.docker.io")
print_info "已添加官方Docker Hub"
;;
esac
done
MIRROR_NAME="混合镜像源(${#MIRRORS[@]}个)"
}
# 自定义公共镜像源配置
get_custom_public_config() {
echo
print_step "选择要添加的公共镜像源(可多选):"
MIRRORS=()
echo "1) 阿里云镜像"
echo "2) 网易云镜像"
echo "3) 中科大镜像"
echo "4) 腾讯云镜像"
echo "5) 官方Docker Hub"
read -p "请输入选择多个用空格分隔1 2 3: " public_choices
for choice in $public_choices; do
case $choice in
1)
MIRRORS+=("$ALIYUN_MIRROR")
print_info "已添加阿里云镜像"
;;
2)
MIRRORS+=("$DOCKER_HUB_MIRROR")
print_info "已添加网易云镜像"
;;
3)
MIRRORS+=("$USTC_MIRROR")
print_info "已添加中科大镜像"
;;
4)
MIRRORS+=("$TENCENT_MIRROR")
print_info "已添加腾讯云镜像"
;;
5)
MIRRORS+=("https://registry-1.docker.io")
print_info "已添加官方Docker Hub"
;;
esac
done
if [ ${#MIRRORS[@]} -eq 0 ]; then
print_error "至少需要选择一个镜像源"
exit 1
fi
MIRROR_NAME="自定义公共镜像源(${#MIRRORS[@]}个)"
}
# 配置镜像源
configure_mirrors() {
print_step "配置Docker镜像源: $MIRROR_NAME"
# 创建Docker配置目录
sudo mkdir -p /etc/docker
# 备份原有配置
if [ -f /etc/docker/daemon.json ]; then
sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.backup.$(date +%Y%m%d%H%M%S)
print_info "已备份原有配置: /etc/docker/daemon.json.backup.$(date +%Y%m%d%H%M%S)"
fi
# 根据不同类型生成配置
case "$MIRROR_TYPE" in
"private_primary")
# 私有仓库为主 + 多个备用源
cat << EOF | sudo tee /etc/docker/daemon.json > /dev/null
{
"registry-mirrors": [
"$PRIVATE_MIRROR",
"$ALIYUN_MIRROR",
"$DOCKER_HUB_MIRROR",
"$USTC_MIRROR",
"$TENCENT_MIRROR"
],
"insecure-registries": ["$PRIVATE_REGISTRY"],
"debug": false,
"experimental": false
}
EOF
;;
"private_only")
# 仅私有仓库
cat << EOF | sudo tee /etc/docker/daemon.json > /dev/null
{
"registry-mirrors": ["$PRIVATE_MIRROR"],
"insecure-registries": ["$PRIVATE_REGISTRY"],
"debug": false,
"experimental": false
}
EOF
;;
"mixed")
# 混合配置
mirrors_json=$(printf '"%s",' "${MIRRORS[@]}")
mirrors_json="[${mirrors_json%,}]"
cat << EOF | sudo tee /etc/docker/daemon.json > /dev/null
{
"registry-mirrors": $mirrors_json,
"insecure-registries": ["$PRIVATE_REGISTRY"],
"debug": false,
"experimental": false
}
EOF
;;
"public_only")
# 仅公共镜像源
cat << EOF | sudo tee /etc/docker/daemon.json > /dev/null
{
"registry-mirrors": [
"$ALIYUN_MIRROR",
"$DOCKER_HUB_MIRROR",
"$USTC_MIRROR",
"$TENCENT_MIRROR"
],
"insecure-registries": [],
"debug": false,
"experimental": false
}
EOF
;;
"official")
# 官方Docker Hub
cat << EOF | sudo tee /etc/docker/daemon.json > /dev/null
{
"registry-mirrors": ["https://registry-1.docker.io"],
"insecure-registries": [],
"debug": false,
"experimental": false
}
EOF
;;
"custom_public")
# 自定义公共镜像源
mirrors_json=$(printf '"%s",' "${MIRRORS[@]}")
mirrors_json="[${mirrors_json%,}]"
cat << EOF | sudo tee /etc/docker/daemon.json > /dev/null
{
"registry-mirrors": $mirrors_json,
"insecure-registries": [],
"debug": false,
"experimental": false
}
EOF
;;
esac
print_info "Docker镜像源配置完成"
print_config "配置文件位置: /etc/docker/daemon.json"
}
# 重启Docker服务
restart_docker() {
print_step "重启Docker服务..."
if sudo systemctl restart docker; then
print_info "Docker服务重启成功"
else
print_error "Docker服务重启失败"
exit 1
fi
# 等待Docker服务完全启动
sleep 3
}
# 保存私有仓库认证信息
save_private_credentials() {
if [ "$NEED_AUTH" != "yes" ]; then
return 0
fi
print_step "是否保存私有仓库认证信息?"
echo "如果保存,以后拉取私有镜像时不需要重复输入密码"
read -p "是否保存认证信息?(y/N): " save_choice
if [[ $save_choice =~ ^[Yy]$ ]]; then
# 使用Docker login保存认证信息
if echo "$PRIVATE_PASSWORD" | docker login $PRIVATE_REGISTRY -u "$PRIVATE_USERNAME" --password-stdin; then
print_info "私有仓库认证信息已保存到 ~/.docker/config.json"
CREDENTIALS_SAVED="yes"
else
print_warning "私有仓库认证信息保存失败"
CREDENTIALS_SAVED="no"
fi
else
print_info "私有仓库认证信息未保存,拉取私有镜像时需要重新登录"
CREDENTIALS_SAVED="no"
fi
}
# 验证配置
verify_configuration() {
print_step "验证配置..."
# 检查Docker服务状态
if sudo systemctl is-active --quiet docker; then
print_info "Docker服务运行正常"
else
print_error "Docker服务未运行"
exit 1
fi
# 检查配置是否生效
if sudo docker info 2>/dev/null | grep -q "Registry Mirrors"; then
print_info "镜像源配置已生效"
echo
print_config "当前配置的镜像源:"
sudo docker info 2>/dev/null | grep -A 10 "Registry Mirrors"
else
print_warning "镜像源配置可能未生效,请手动检查"
fi
}
# 显示配置摘要
show_summary() {
echo
print_info "=== 配置完成摘要 ==="
echo -e "${GREEN}${NC} Docker镜像源配置完成"
echo -e "${GREEN}${NC} 镜像源类型: ${MIRROR_NAME}"
if [ -n "$PRIVATE_REGISTRY" ]; then
echo -e "${GREEN}${NC} 私有仓库地址: ${PRIVATE_REGISTRY}"
echo -e "${GREEN}${NC} 私有仓库镜像: ${PRIVATE_MIRROR}"
if [ "$NEED_AUTH" = "yes" ]; then
echo -e "${GREEN}${NC} 私有仓库认证: 需要"
echo -e "${GREEN}${NC} 用户名: ${PRIVATE_USERNAME}"
if [ "$CREDENTIALS_SAVED" = "yes" ]; then
echo -e "${GREEN}${NC} 认证信息: 已保存"
else
echo -e "${YELLOW}${NC} 认证信息: 未保存"
fi
else
echo -e "${GREEN}${NC} 私有仓库认证: 无需认证"
fi
else
echo -e "${GREEN}${NC} 私有仓库: 未配置"
fi
echo -e "${GREEN}${NC} Docker服务已重启生效"
echo
print_info "使用说明:"
if [ -n "$PRIVATE_REGISTRY" ]; then
echo " 私有镜像: docker pull ${PRIVATE_REGISTRY}/镜像名称"
fi
echo " 公共镜像: docker pull 镜像名称"
echo " 查看配置: docker info | grep -A 10 'Registry Mirrors'"
echo " 测试拉取: docker pull hello-world"
echo
print_info "配置文件: /etc/docker/daemon.json"
print_info "备份文件: /etc/docker/daemon.json.backup.*"
if [ -n "$PRIVATE_REGISTRY" ] && [ "$NEED_AUTH" = "yes" ] && [ "$CREDENTIALS_SAVED" = "yes" ]; then
print_info "认证信息: ~/.docker/config.json"
fi
}
# 主函数
main() {
clear
echo "=========================================="
echo " Docker镜像源配置脚本"
echo "=========================================="
echo
# 检查Docker
check_docker
# 获取私有仓库配置
get_private_registry_config
# 显示镜像源菜单
show_mirror_menu
# 获取用户选择
get_mirror_choice
# 如果是混合配置,获取详细选择
if [ "$MIRROR_TYPE" = "mixed" ]; then
get_mixed_config
elif [ "$MIRROR_TYPE" = "custom_public" ]; then
get_custom_public_config
fi
# 如果是私有仓库需要认证,测试登录
if [ "$NEED_AUTH" = "yes" ]; then
if ! test_private_login; then
print_error "私有仓库登录测试失败"
read -p "是否继续配置?(可能会影响私有镜像拉取)(y/N): " continue_anyway
if [[ ! $continue_anyway =~ ^[Yy]$ ]]; then
print_error "配置中止,请解决登录问题后重新运行脚本"
exit 1
fi
fi
fi
# 配置镜像源
configure_mirrors
# 重启Docker服务
restart_docker
# 保存私有仓库认证信息
if [ "$NEED_AUTH" = "yes" ]; then
save_private_credentials
fi
# 验证配置
verify_configuration
# 显示摘要
show_summary
}
# 运行主函数
main "$@"