#!/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 "$@"