Files
script/docker.sh
2025-09-14 17:34:24 +08:00

274 lines
6.8 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/env bash
# Docker 安装脚本
# 支持中国大陆和海外环境
set -euo pipefail
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly LOG_FILE="${SCRIPT_DIR}/docker_install.log"
readonly DAEMON_JSON="/etc/docker/daemon.json"
readonly BACKUP_FILE="${DAEMON_JSON}.backup"
# 颜色定义
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly BLUE='\033[0;34m'
readonly NC='\033[0m' # No Color
# 日志函数
log() {
echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "$LOG_FILE"
}
log_info() {
echo -e "${BLUE}[INFO]${NC} $1" | tee -a "$LOG_FILE"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1" | tee -a "$LOG_FILE"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"
}
# 检测地区
detect_region() {
local country
country=$(curl -s --connect-timeout 5 --max-time 10 ipinfo.io/country 2>/dev/null || echo "")
[[ "$country" == "CN" ]]
}
# 检查Docker版本
check_docker_version() {
if ! command -v docker &>/dev/null; then
return 1
fi
local version
version=$(docker --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+' | head -n1)
local major="${version%%.*}"
if [[ ${major:-0} -lt 20 ]]; then
log_warn "Docker版本过低 (${version})建议升级到20.x或更高版本"
else
log_info "检测到Docker版本: ${version}"
fi
return 0
}
# 创建daemon.json配置
create_daemon_json() {
local accelerator_url="${1:-}"
if [[ -n "$accelerator_url" ]]; then
log_info "配置Docker镜像加速器: $accelerator_url"
cat > "$DAEMON_JSON" << EOF
{
"registry-mirrors": ["$accelerator_url"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"storage-driver": "overlay2"
}
EOF
else
cat > "$DAEMON_JSON" << EOF
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"storage-driver": "overlay2"
}
EOF
fi
}
# 配置加速器
configure_accelerator() {
if ! detect_region; then
log_info "非中国大陆地区,跳过镜像加速器配置"
return 0
fi
echo -n "是否配置Docker镜像加速器(y/N): "
read -r choice
case "$choice" in
[yY]|[yY][eE][sS])
local accelerator_url=""
# 测试腾讯云镜像可用性
if ping -c 1 -W 3 mirror.ccs.tencentyun.com &>/dev/null; then
accelerator_url="https://mirror.ccs.tencentyun.com"
else
# 备选阿里云镜像
accelerator_url="https://registry.cn-hangzhou.aliyuncs.com"
fi
# 备份现有配置
[[ -f "$DAEMON_JSON" ]] && cp "$DAEMON_JSON" "$BACKUP_FILE"
# 创建配置目录
mkdir -p "$(dirname "$DAEMON_JSON")"
# 创建新配置
create_daemon_json "$accelerator_url"
# 重启Docker服务
log_info "重启Docker服务..."
systemctl daemon-reload
systemctl restart docker
log "Docker镜像加速器配置完成"
;;
*)
log_info "跳过镜像加速器配置"
;;
esac
}
# 获取最快的Docker安装源
get_fastest_source() {
local sources=(
"https://mirrors.aliyun.com/docker-ce"
"https://mirrors.tencent.com/docker-ce"
"https://mirrors.163.com/docker-ce"
)
local fastest_source="${sources[0]}"
local min_time=99999
for source in "${sources[@]}"; do
local response_time
response_time=$(curl -o /dev/null -s -w '%{time_total}\n' -m 3 "$source" 2>/dev/null || echo "99999")
if (( $(echo "$response_time < $min_time" | bc -l 2>/dev/null || echo 0) )); then
min_time=$response_time
fastest_source=$source
fi
done
echo "$fastest_source"
}
# 下载Docker安装脚本
download_docker_script() {
local scripts=(
"https://get.docker.com"
"https://cdn.jsdelivr.net/gh/docker/docker-install@master/install.sh"
"https://fastly.jsdelivr.net/gh/docker/docker-install@master/install.sh"
)
for script_url in "${scripts[@]}"; do
log_info "尝试从 $script_url 下载安装脚本..."
if curl -fsSL --connect-timeout 10 --max-time 30 "$script_url" -o get-docker.sh; then
log "下载成功: $script_url"
return 0
else
log_warn "下载失败: $script_url"
fi
done
log_error "所有下载尝试均失败"
return 1
}
# 安装Docker
install_docker() {
log_info "开始安装Docker..."
if detect_region; then
log_info "检测到中国大陆地区,使用国内镜像源"
local fastest_source
fastest_source=$(get_fastest_source)
export DOWNLOAD_URL="$fastest_source"
log_info "选择最快源: $fastest_source"
else
log_info "使用官方源"
export DOWNLOAD_URL="https://download.docker.com"
fi
# 下载安装脚本
if ! download_docker_script; then
log_error "无法下载Docker安装脚本"
return 1
fi
# 执行安装
log_info "执行Docker安装..."
if sh get-docker.sh 2>&1 | tee -a "$LOG_FILE"; then
log "Docker安装成功"
else
log_error "Docker安装失败"
return 1
fi
# 清理安装脚本
rm -f get-docker.sh
# 启动并启用Docker服务
log_info "启动Docker服务..."
systemctl enable docker
systemctl start docker
# 验证安装
if docker --version &>/dev/null; then
log "Docker安装验证成功"
docker --version | tee -a "$LOG_FILE"
return 0
else
log_error "Docker安装验证失败"
return 1
fi
}
# 主函数
main() {
log "开始Docker安装检查..."
# 检查是否已安装Docker
if check_docker_version; then
log_info "Docker已安装"
configure_accelerator
return 0
fi
# 确认安装
echo -n "Docker未安装是否现在安装(y/N): "
read -r install_choice
case "$install_choice" in
[yY]|[yY][eE][sS])
if install_docker; then
configure_accelerator
log "Docker安装和配置完成"
else
log_error "Docker安装失败请检查日志: $LOG_FILE"
exit 1
fi
;;
*)
log_info "取消安装"
exit 0
;;
esac
}
# 检查root权限
if [[ $EUID -ne 0 ]]; then
log_error "此脚本需要root权限运行"
exit 1
fi
# 执行主函数
main "$@"