#!/bin/bash ############################################################################## # 通用Linux Docker一键安装脚本 # 功能:支持多种Linux发行版,自动适配国内外网络环境,安装Docker和Docker Compose # 版本:2.8 # 版权声明:该脚本由 xblog.tech 维护 # 支持系统:Ubuntu, Debian, CentOS, RHEL, Fedora, Rocky Linux, AlmaLinux等 # 注意:国内网络环境下将使用第三方脚本,请谨慎选择 ############################################################################## set -e # 颜色输出定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # 无颜色 # 日志函数 log_info() { echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" } log_error() { echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" } log_notice() { echo -e "${BLUE}[NOTICE]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" } log_debug() { echo -e "${BLUE}[DEBUG]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" } # 检查命令是否存在 command_exists() { command -v "$1" >/dev/null 2>&1 } # 获取系统信息 get_os_info() { if [ -f /etc/os-release ]; then . /etc/os-release OS_NAME=$(echo $ID | tr '[:upper:]' '[:lower:]') OS_VERSION=$(echo $VERSION_ID | tr '[:upper:]' '[:lower:]') OS_CODENAME=$(echo $VERSION_CODENAME | tr '[:upper:]' '[:lower:]') if [ -z "$OS_CODENAME" ]; then OS_CODENAME=$(lsb_release -cs 2>/dev/null || echo "unknown") fi else log_error "无法检测操作系统信息" exit 1 fi } # 获取系统架构 get_architecture() { ARCH=$(uname -m) case $ARCH in x86_64) ARCH="x86_64" ;; aarch64) ARCH="aarch64" ;; armv7l) ARCH="armv7" ;; *) log_error "不支持的架构: $ARCH" exit 1 ;; esac echo $ARCH } # 检测网络环境(检查与Docker官方的连通性) detect_network_environment() { log_info "检测网络环境..." if curl -s --connect-timeout 10 https://get.docker.com/ > /dev/null; then log_info "国外网络环境检测正常,优先使用官方源安装" return 0 else log_warn "国外网络访问不畅,将使用国内镜像源安装" return 1 fi } # 使用官方脚本安装Docker install_docker_official() { log_info "开始使用Docker官方脚本安装..." # 下载并执行官方安装脚本 if curl -fsSL https://get.docker.com -o get-docker.sh; then sh get-docker.sh # 清理临时文件 rm -f get-docker.sh return 0 else log_error "下载Docker官方安装脚本失败" return 1 fi } # 显示第三方脚本安全提醒 show_third_party_warning() { echo "================================================================" log_notice " 安全提醒" echo "================================================================" log_warn "您即将使用第三方脚本安装Docker,请注意以下事项:" log_warn "1. 第三方脚本的安全性我们无法保证" log_warn "2. 请确保您信任所使用的第三方脚本" log_warn "3. 建议在安装前审查脚本内容" log_warn "4. 生产环境请谨慎使用" echo "" log_info "可选的第三方脚本:" log_info "A. 轩辕镜像脚本 (https://xuanyuan.cloud/docker.sh)" log_info "B. LinuxMirrors脚本 (https://linuxmirrors.cn/docker.sh)" echo "================================================================" } # 使用第三方脚本安装Docker install_docker_third_party() { show_third_party_warning # 让用户选择安装方式 echo "" log_info "请选择安装方式:" echo "1) 使用轩辕镜像脚本安装 (推荐)" echo "2) 使用LinuxMirrors脚本安装" echo "3) 退出安装" read -p "请输入选择 [1-3]: " choice case $choice in 1) log_info "您选择了轩辕镜像脚本" log_warn "请注意:该脚本由第三方维护,安全性请自行评估" read -p "确认继续?(y/N): " confirm if [[ $confirm =~ ^[Yy]$ ]]; then bash <(wget -qO- https://xuanyuan.cloud/docker.sh || curl -sSL https://xuanyuan.cloud/docker.sh) else log_info "安装已取消" exit 0 fi ;; 2) log_info "您选择了LinuxMirrors脚本" log_warn "请注意:该脚本由第三方维护,安全性请自行评估" read -p "确认继续?(y/N): " confirm if [[ $confirm =~ ^[Yy]$ ]]; then bash <(curl -sSL https://linuxmirrors.cn/docker.sh || wget -qO- https://linuxmirrors.cn/docker.sh) else log_info "安装已取消" exit 0 fi ;; 3) log_info "安装已取消" exit 0 ;; *) log_error "无效选择,安装已取消" exit 1 ;; esac } # 安装系统依赖 install_dependencies() { log_info "安装系统依赖包..." if command_exists apt-get; then apt-get update || log_warn "apt-get update 失败,但继续执行..." apt-get install -y curl gnupg lsb-release ca-certificates elif command_exists yum; then yum install -y curl gpg dbus-utils device-mapper-persistent-data lvm2 elif command_exists dnf; then dnf install -y curl gpg dbus-utils device-mapper-persistent-data lvm2 else log_error "不支持的包管理器" exit 1 fi } # 配置Docker国内镜像源 setup_docker_repo_cn() { log_info "配置Docker国内镜像源..." get_os_info log_info "检测到 ${OS_NAME} ${OS_VERSION} (${OS_CODENAME}) 系统" if command_exists apt-get; then # Debian/Ubuntu mkdir -p /etc/apt/keyrings # 根据系统类型选择正确的仓库路径 if [ "$OS_NAME" = "debian" ]; then log_info "配置Debian国内镜像源..." curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian $OS_CODENAME stable" > /etc/apt/sources.list.d/docker.list else log_info "配置Ubuntu国内镜像源..." curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $OS_CODENAME stable" > /etc/apt/sources.list.d/docker.list fi apt-get update elif command_exists yum || command_exists dnf; then # CentOS/RHEL/Fedora等 log_info "配置CentOS/RHEL国内镜像源..." if command_exists dnf; then dnf config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo else yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo fi else log_error "不支持的Linux发行版" exit 1 fi } # 安装Docker包 install_docker_packages() { log_info "安装Docker引擎..." if command_exists apt-get; then # 对于较新的Debian/Ubuntu版本,可能需要安装containerd.io的特定版本 if ! apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin; then log_warn "标准安装失败,尝试替代安装方案..." apt-get install -y docker.io fi elif command_exists yum; then yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin elif command_exists dnf; then dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin fi } # 配置国内镜像加速器 setup_docker_mirror_cn() { log_info "配置国内镜像加速器..." mkdir -p /etc/docker # 测试可用的镜像加速器 local mirrors=( "https://docker.xuanyuan.me" "https://docker.1ms.run" "https://mirror.ccs.tencentyun.com" "https://docker.mirrors.ustc.edu.cn" "https://hub-mirror.c.163.com" ) # 选择前3个可用的镜像 local available_mirrors=() for mirror in "${mirrors[@]}"; do if curl -s --connect-timeout 3 "$mirror" > /dev/null; then available_mirrors+=("$mirror") log_info "镜像加速器可用: $mirror" if [ ${#available_mirrors[@]} -ge 3 ]; then break fi fi done if [ ${#available_mirrors[@]} -eq 0 ]; then log_warn "未找到可用的镜像加速器,使用默认配置" available_mirrors=( "https://docker.xuanyuan.me" "https://docker.1ms.run" "https://mirror.ccs.tencentyun.com" ) fi # 构建daemon.json local daemon_config="{ \"registry-mirrors\": [" for i in "${!available_mirrors[@]}"; do daemon_config+="\n \"${available_mirrors[$i]}\"" if [ $i -lt $((${#available_mirrors[@]} - 1)) ]; then daemon_config+="," fi done daemon_config+="\n ]\n}" echo -e "$daemon_config" > /etc/docker/daemon.json log_info "已配置 ${#available_mirrors[@]} 个镜像加速器" } # 启动Docker服务 start_docker_service() { log_info "启动Docker服务..." systemctl enable docker if ! systemctl start docker; then log_error "Docker服务启动失败" systemctl status docker return 1 fi # 等待服务完全启动 sleep 5 # 验证Docker服务状态 if systemctl is-active --quiet docker; then log_info "Docker服务启动成功" return 0 else log_error "Docker服务启动失败" systemctl status docker return 1 fi } # 安装Docker Compose install_docker_compose() { log_info "开始安装Docker Compose..." # 检查是否已经安装了Docker Compose Plugin if docker compose version &>/dev/null; then log_info "Docker Compose Plugin 已安装" docker compose version return 0 fi # 检查是否已经安装了独立版本的Docker Compose if command_exists docker-compose; then log_info "Docker Compose 已安装" docker-compose --version return 0 fi # 获取系统架构 local ARCH=$(get_architecture) # 定义Docker Compose版本 local COMPOSE_VERSION="2.24.0" # 下载Docker Compose二进制文件 log_info "下载Docker Compose v${COMPOSE_VERSION}..." # 尝试使用国内镜像下载 local download_url="" if detect_network_environment; then # 国外网络 - 使用官方源 download_url="https://github.com/docker/compose/releases/download/v${COMPOSE_VERSION}/docker-compose-linux-${ARCH}" else # 国内网络 - 使用镜像源 download_url="https://ghproxy.com/https://github.com/docker/compose/releases/download/v${COMPOSE_VERSION}/docker-compose-linux-${ARCH}" fi # 下载Docker Compose if curl -L "$download_url" -o /usr/local/bin/docker-compose; then chmod +x /usr/local/bin/docker-compose # 创建符号链接以便使用 docker compose 命令 ln -sf /usr/local/bin/docker-compose /usr/local/bin/docker-compose # 验证安装 if docker-compose --version; then log_info "Docker Compose 安装成功" return 0 else log_error "Docker Compose 安装验证失败" return 1 fi else log_error "下载Docker Compose失败" # 尝试备用安装方法 - 使用pip安装 log_info "尝试使用pip安装Docker Compose..." if command_exists pip3; then if pip3 install docker-compose; then log_info "Docker Compose 通过pip安装成功" return 0 fi elif command_exists pip; then if pip install docker-compose; then log_info "Docker Compose 通过pip安装成功" return 0 fi fi log_error "所有Docker Compose安装方法都失败了" return 1 fi } # 验证安装 verify_installation() { log_info "验证Docker安装..." if command_exists docker; then docker --version log_info "Docker安装成功!" # 验证Docker Compose if docker compose version &>/dev/null; then log_info "Docker Compose Plugin 已安装:" docker compose version elif command_exists docker-compose; then log_info "Docker Compose 已安装:" docker-compose --version else log_warn "Docker Compose 未安装" fi return 0 else log_error "Docker安装失败" return 1 fi } # 显示安装完成信息 show_completion_info() { echo "" log_info "================================================================" log_info " Docker安装完成" log_info "================================================================" log_info "常用命令:" log_info " 检查Docker版本: docker --version" log_info " 检查Docker Compose版本: docker-compose --version 或 docker compose version" log_info " 检查状态: systemctl status docker" log_info " 启动服务: systemctl start docker" log_info " 停止服务: systemctl stop docker" log_info "" log_info "使用提示:" log_info " 1. 使用 'docker ps' 查看运行中的容器" log_info " 2. 使用 'docker-compose up' 运行docker-compose项目" log_info " 3. 查看日志: journalctl -u docker.service" log_info "================================================================" } # 直接使用国内镜像源安装(无需用户交互) install_docker_direct_cn() { log_info "使用国内镜像源直接安装Docker..." # 安装依赖 if ! install_dependencies; then log_error "安装依赖包失败" return 1 fi # 配置Docker仓库 if ! setup_docker_repo_cn; then log_error "配置Docker仓库失败" return 1 fi # 安装Docker if ! install_docker_packages; then log_error "安装Docker包失败" return 1 fi # 配置镜像加速器 setup_docker_mirror_cn # 启动服务 if ! start_docker_service; then log_error "启动Docker服务失败" return 1 fi return 0 } # 使用备用方案安装Docker(当主要方法失败时) install_docker_fallback() { log_info "尝试使用备用方案安装Docker..." get_os_info if command_exists apt-get; then # 对于Debian/Ubuntu,尝试使用系统自带的docker.io包 log_info "使用系统自带的docker.io包安装..." apt-get update if apt-get install -y docker.io; then log_info "docker.io安装成功" return 0 else log_error "备用安装方案也失败了" return 1 fi else log_error "没有可用的备用安装方案" return 1 fi } # 询问是否安装Docker Compose ask_install_compose() { echo "" log_info "是否安装Docker Compose?" echo "1) 是,安装Docker Compose" echo "2) 否,跳过安装" read -p "请输入选择 [1-2] (默认1): " compose_choice case ${compose_choice:-1} in 1) if install_docker_compose; then log_info "Docker Compose安装完成" else log_warn "Docker Compose安装失败,但Docker已成功安装" fi ;; 2) log_info "跳过Docker Compose安装" ;; *) log_error "无效选择,跳过Docker Compose安装" ;; esac } # 自动重试安装(国外失败时切换到国内) install_docker_with_retry() { local network_ok=$1 if [ $network_ok -eq 0 ]; then # 国外网络 - 先尝试官方脚本 log_info "优先使用国外官方脚本安装..." if install_docker_official; then return 0 else log_warn "国外官方脚本安装失败,自动切换到国内镜像源安装..." # 国外安装失败,切换到国内安装 if install_docker_direct_cn; then return 0 else log_warn "国内镜像源安装失败,尝试备用方案..." if install_docker_fallback; then return 0 else return 1 fi fi fi else # 国内网络 - 直接使用国内镜像源 log_info "使用国内镜像源安装..." if install_docker_direct_cn; then return 0 else log_warn "国内镜像源安装失败,尝试备用方案..." if install_docker_fallback; then return 0 else return 1 fi fi fi } # 国内网络环境下的自动安装(无需用户交互) install_docker_auto_cn() { log_info "检测到国内网络环境,开始自动安装..." # 直接使用国内镜像源安装 if install_docker_direct_cn; then return 0 else log_warn "国内镜像源安装失败,尝试备用方案..." if install_docker_fallback; then return 0 else return 1 fi fi } # 主函数 main() { log_info "开始安装Docker..." log_info "版权声明:该脚本由 xblog.tech 维护" # 检查root权限 if [ "$(id -u)" -ne 0 ]; then log_error "请使用root权限运行此脚本" log_error "示例: sudo $0" exit 1 fi # 获取系统信息 get_os_info log_info "操作系统: ${OS_NAME} ${OS_VERSION} (${OS_CODENAME})" # 检测网络环境 detect_network_environment local network_ok=$? if [ $network_ok -eq 0 ]; then # 国外网络 - 使用自动重试安装 log_info "使用国外网络安装模式(失败时自动切换到国内源)" if install_docker_with_retry $network_ok; then ask_install_compose verify_installation show_completion_info else log_error "所有安装方法都失败了" exit 1 fi else # 国内网络 - 自动安装,无需用户选择 log_info "使用国内网络安装模式(自动安装)" if install_docker_auto_cn; then ask_install_compose verify_installation show_completion_info else log_error "所有安装方法都失败了" exit 1 fi fi } # 执行主函数 main "$@"