偶尔要在ubuntu上安装docker,每次实验时都手工安装,工序繁琐,做了一个sh脚本,一键安装docker,docker-compose,并设置最新的镜像加速地址。

文章最后有该脚本的高速下载地址

#!/bin/bash

# Ubuntu Docker 安装脚本(支持 22.04 和 24.04)- 不更新内核
set -e

echo "=========================================="
echo "  Docker & Docker Compose 安装脚本"
echo "  适用于 Ubuntu 22.04 和 24.04 - 国内镜像源"
echo "  不更新内核版本"
echo "=========================================="

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

# 系统信息
OS_ID=""
OS_VERSION=""
OS_CODENAME=""
CURRENT_KERNEL=""

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查是否以 root 运行
check_root() {
    if [ "$(id -u)" -ne 0 ]; then
        log_error "请使用 root 权限运行此脚本"
        log_info "可以使用: sudo bash $0"
        exit 1
    fi
}

# 检测系统版本
detect_os() {
    if [ ! -f /etc/os-release ]; then
        log_error "无法检测操作系统版本"
        exit 1
    fi
    
    . /etc/os-release
    
    OS_ID="$ID"
    OS_VERSION="$VERSION_ID"
    OS_CODENAME="$VERSION_CODENAME"
    CURRENT_KERNEL=$(uname -r)
    
    log_info "检测到系统: $PRETTY_NAME"
    log_info "当前内核版本: $CURRENT_KERNEL"
    
    case "$OS_CODENAME" in
        "jammy")  # 22.04
            log_info "检测到 Ubuntu 22.04 (Jammy Jellyfish)"
            ;;
        "noble")  # 24.04
            log_info "检测到 Ubuntu 24.04 (Noble Numbat)"
            ;;
        *)
            log_warn "此脚本主要针对 Ubuntu 22.04 和 24.04 测试"
            log_warn "当前系统: $OS_ID $OS_VERSION ($OS_CODENAME)"
            printf "是否继续?(y/n): "
            read -r choice
            case "$choice" in
                y|Y|yes|YES) ;;
                *) exit 1 ;;
            esac
            ;;
    esac
}

# 锁定内核版本,防止更新
lock_kernel_packages() {
    log_info "锁定内核包,防止自动更新..."
    
    # 安装 apt-mark 如果不存在
    if ! command -v apt-mark > /dev/null 2>&1; then
        apt-get install -y apt-utils
    fi
    
    # 获取当前已安装的内核包
    KERNEL_PACKAGES=$(dpkg -l | grep -E "linux-image-|linux-headers-|linux-modules-" | awk '{print $2}' | grep -v "linux-headers-generic" | grep -v "linux-image-generic")
    
    # 锁定所有内核相关包
    for package in $KERNEL_PACKAGES; do
        if dpkg -l | grep -q "^ii  $package"; then
            apt-mark hold "$package" > /dev/null 2>&1 && \
            log_info "已锁定包: $package" || \
            log_warn "锁定包失败: $package"
        fi
    done
    
    # 锁定通用的内核元包
    for package in linux-generic linux-image-generic linux-headers-generic; do
        if dpkg -l | grep -q "^ii  $package"; then
            apt-mark hold "$package" > /dev/null 2>&1
        fi
    done
    
    # 配置 APT 不更新内核
    if [ ! -f /etc/apt/apt.conf.d/50hold-kernel ]; then
        cat > /etc/apt/apt.conf.d/50hold-kernel << 'EOF'
# 阻止内核自动更新
APT::Get::Hold "linux-image-*";
APT::Get::Hold "linux-headers-*";
APT::Get::Hold "linux-modules-*";
APT::Get::Hold "linux-generic";
APT::Get::Hold "linux-image-generic";
APT::Get::Hold "linux-headers-generic";
EOF
        log_info "已配置 APT 阻止内核更新"
    fi
}

# 配置国内镜像源
configure_mirrors() {
    log_info "配置国内镜像源..."
    
    # 备份原有源
    if [ ! -f /etc/apt/sources.list.bak ]; then
        cp /etc/apt/sources.list /etc/apt/sources.list.bak
        log_info "已备份原有源列表"
    fi
    
    case "$OS_CODENAME" in
        "jammy")  # Ubuntu 22.04
            cat > /etc/apt/sources.list << 'EOF'
# 阿里云镜像源 - Ubuntu 22.04 Jammy
deb http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
# 注释掉 proposed 和 backports 仓库,减少内核更新风险
# deb http://mirrors.aliyun.com/ubuntu/ jammy-proposed main restricted universe multiverse
# deb http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
EOF
            ;;
        "noble")  # Ubuntu 24.04
            cat > /etc/apt/sources.list << 'EOF'
# 阿里云镜像源 - Ubuntu 24.04 Noble
deb http://mirrors.aliyun.com/ubuntu/ noble main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ noble-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ noble-updates main restricted universe multiverse
# 注释掉 proposed 和 backports 仓库,减少内核更新风险
# deb http://mirrors.aliyun.com/ubuntu/ noble-proposed main restricted universe multiverse
# deb http://mirrors.aliyun.com/ubuntu/ noble-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ noble main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ noble-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ noble-updates main restricted universe multiverse
EOF
            ;;
        *)
            log_error "不支持的 Ubuntu 版本: $OS_CODENAME"
            exit 1
            ;;
    esac

    log_info "已配置阿里云镜像源 ($OS_CODENAME)"
    log_info "已禁用 proposed 和 backports 仓库以减少内核更新风险"
}

# 安装基础依赖(不更新内核)
install_dependencies() {
    log_info "更新软件包列表(不更新系统)..."
    
    # 使用 --allow-downgrades 和 --allow-remove-essential 避免因依赖问题触发内核更新
    apt-get update
    
    log_info "安装基础依赖..."
    
    # 单独安装每个包,避免大规模更新
    for package in apt-transport-https ca-certificates curl gnupg lsb-release software-properties-common git; do
        if ! dpkg -l | grep -q "^ii  $package"; then
            log_info "安装 $package..."
            apt-get install -y --allow-downgrades --allow-remove-essential "$package"
        else
            log_info "$package 已安装,跳过"
        fi
    done
}

# 获取 Docker Compose 架构名称
get_architecture() {
    local arch
    arch=$(uname -m)
    case "$arch" in
        "x86_64")
            echo "x86_64"
            ;;
        "aarch64"|"arm64")
            echo "aarch64"
            ;;
        "armv7l")
            echo "armv7"
            ;;
        *)
            log_error "不支持的架构: $arch"
            exit 1
            ;;
    esac
}

# 安装 Docker(不更新内核)
install_docker() {
    log_info "安装 Docker..."
    
    if command -v docker > /dev/null 2>&1; then
        log_warn "Docker 已安装,跳过安装步骤"
        return 0
    fi
    
    # 添加 Docker 官方 GPG 密钥
    mkdir -p /etc/apt/keyrings
    curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    
    # 添加 Docker 镜像源
    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \
      $OS_CODENAME stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
    
    log_info "更新 Docker 软件包列表..."
    apt-get update
    
    # 检查可用的 Docker 版本
    log_info "可用的 Docker 版本:"
    apt-cache madison docker-ce | head -5
    
    # 安装特定版本的 Docker 以避免依赖冲突
    DOCKER_VERSION=$(apt-cache madison docker-ce | awk '{print $3}' | head -1)
    log_info "将安装 Docker 版本: $DOCKER_VERSION"
    
    # Ubuntu 24.04 需要先安装 containerd.io
    if [ "$OS_CODENAME" = "noble" ]; then
        log_info "检测到 Ubuntu 24.04,安装兼容的 containerd 版本..."
        apt-get install -y --allow-downgrades --allow-remove-essential containerd.io
    fi
    
    # 安装 Docker(不推荐更新相关包)
    log_info "安装 Docker CE..."
    apt-get install -y --allow-downgrades --allow-remove-essential \
        docker-ce="$DOCKER_VERSION" \
        docker-ce-cli="$DOCKER_VERSION"
    
    # 配置 Docker 镜像加速器
    mkdir -p /etc/docker
    cat > /etc/docker/daemon.json << 'EOF'
{
  "registry-mirrors": [
    "https://docker.1ms.run",
    "https://hub-mirror.c.163.com",
    "https://hub.mirrorify.net",
    "https://hub.1panel.dev"
  ],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  },
  "storage-driver": "overlay2"
}
EOF
    
    # 启动 Docker
    systemctl enable docker
    systemctl start docker
    
    log_info "Docker 安装完成"
}

# 安装 Docker Compose
install_docker_compose() {
    log_info "安装 Docker Compose..."
    
    if command -v docker-compose > /dev/null 2>&1; then
        docker_compose_version=$(docker-compose --version | awk '{print $3}')
        log_warn "Docker Compose 已安装 (版本: $docker_compose_version)"
        printf "是否重新安装?(y/n): "
        read -r choice
        case "$choice" in
            y|Y|yes|YES) ;;
            *) return 0 ;;
        esac
    fi
    
    local arch
    arch=$(get_architecture)
    local compose_version="v2.24.0"
    
    log_info "下载 Docker Compose $compose_version (架构: $arch)"
    
    if curl -L "https://soft-1251416864.cos.ap-nanjing.myqcloud.com/docker/docker-compose-linux-x86_64" \
        -o /usr/local/bin/docker-compose; then
        chmod +x /usr/local/bin/docker-compose
        ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose 2>/dev/null || true
        log_info "Docker Compose 安装完成"
    else
        log_error "Docker Compose 下载失败"
        exit 1
    fi
}

# 配置用户权限
configure_user_permissions() {
    log_info "配置用户权限..."
    
    if [ -n "$SUDO_USER" ]; then
        if ! groups "$SUDO_USER" | grep -q docker; then
            usermod -aG docker "$SUDO_USER"
            log_info "已将用户 $SUDO_USER 添加到 docker 组"
        else
            log_info "用户 $SUDO_USER 已在 docker 组中"
        fi
    else
        log_warn "未检测到 SUDO_USER,请手动将用户添加到 docker 组:"
        log_info "sudo usermod -aG docker \$USER"
        log_info "然后重新登录或执行: newgrp docker"
    fi
}

# 验证安装和内核状态
verify_installation() {
    log_info "验证安装..."
    
    echo
    echo "=== 安装验证 ==="
    
    # 检查内核状态
    echo "当前内核版本: $CURRENT_KERNEL"
    echo "内核锁定状态:"
    dpkg -l | grep -E "^hi" | grep -E "linux-image-|linux-headers-" | head -3
    
    # 检查 Docker
    if command -v docker > /dev/null 2>&1; then
	    systemctl restart docker
        docker_version=$(docker --version | awk '{print $3}')
        echo "Docker 版本: $docker_version"
        
        if systemctl is-active docker > /dev/null; then
            echo "Docker 服务状态: 运行中"
            if docker run --rm hello-world 2>/dev/null | grep -q "Hello from Docker"; then
                log_info "Docker 测试: 成功"
            else
                log_warn "Docker 基础功能正常,但测试容器执行失败"
            fi
        else
            log_error "Docker 服务未运行"
        fi
    else
        log_error "Docker 安装失败"
    fi
    
    if command -v docker-compose > /dev/null 2>&1; then
        compose_version=$(docker-compose --version | awk '{print $3}')
        echo "Docker Compose 版本: $compose_version"
    else
        log_error "Docker Compose 安装失败"
    fi
    
    echo
    log_info "安装完成!"
    log_info "内核版本已锁定,不会自动更新"
    
    if [ -n "$SUDO_USER" ]; then
        echo
        log_info "后续步骤:"
        log_info "1. 重新登录或执行: newgrp docker"
        log_info "2. 测试: docker ps"
        log_info "3. 测试: docker-compose --version"
    fi
}

# 显示系统信息
show_system_info() {
    echo
    echo "=== 系统信息 ==="
    echo "操作系统: $OS_ID $OS_VERSION ($OS_CODENAME)"
    echo "架构: $(uname -m)"
    echo "内核: $CURRENT_KERNEL"
    
    if command -v free > /dev/null 2>&1; then
        echo "内存: $(free -h | awk '/^Mem:/ {print $2}')"
    fi
    
    if command -v df > /dev/null 2>&1; then
        echo "磁盘: $(df -h / | awk 'NR==2 {print $4}') 可用"
    fi
    echo
}

# 主函数
main() {
    check_root
    detect_os
    show_system_info
    
    log_info "开始安装 Docker 和 Docker Compose(不更新内核)..."
    
    # 首先锁定内核
    lock_kernel_packages
    
    # 询问是否配置国内镜像源
    printf "是否配置国内镜像源?(y/n, 推荐 y): "
    read -r choice
    case "$choice" in
        y|Y|yes|YES) configure_mirrors ;;
        *) log_warn "跳过镜像源配置,使用默认源" ;;
    esac
    
    install_dependencies
    install_docker
    install_docker_compose
    configure_user_permissions
    verify_installation
    
    log_info "=== 重要提示 ==="
    log_info "内核更新已被禁用,如需手动更新内核,请先执行:"
    log_info "sudo apt-mark unhold linux-image-* linux-headers-*"
    log_info "然后更新完成后重新锁定内核"
}

# 执行主函数
main "$@"

 

脚本蓝奏云高速下载

https://wwud.lanzouu.com/b00wn606la
密码:liuguohua

 

脚本远程执行

curl https://www.liuguohua.com/soft/install.docker.ubuntu.sh | bash

 

声明:欢迎大家光临本站,学习IT运维技术,转载本站内容,请注明内容出处”来源刘国华教育“。如若本站内容侵犯了原著者的合法权益,请联系我们进行处理。