偶尔要在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运维技术,转载本站内容,请注明内容出处”来源刘国华教育“。如若本站内容侵犯了原著者的合法权益,请联系我们进行处理。
