```bash #!/usr/bin/env bash # # Docker 安装脚本(Ubuntu) # # 功能: # - 安装 docker-ce / docker-ce-cli / containerd.io # - 安装 docker-buildx-plugin / docker-compose-plugin # - 可选按官方方式卸载旧 Docker 相关包 # - 可选使用国内 APT 源安装 Docker # - 可选配置 Docker registry 国内镜像加速 # - 可选配置容器日志轮转限制 # - 可选自动检测网络环境 # # 支持: # - Ubuntu 20.04 / 22.04 / 24.04 # # 用法示例: # sudo bash install_docker.sh # sudo bash install_docker.sh -u # sudo bash install_docker.sh -m -r -c # sudo bash install_docker.sh -a -c if [ -z "${BASH_VERSION:-}" ]; then echo "Please run this script with bash" exit 1 fi set -Eeuo pipefail #============================== # 默认参数 #============================== UNINSTALL=0 USE_CN_SOURCE=0 ENABLE_LOG_LIMIT=0 ENABLE_REGISTRY_MIRROR=0 AUTO_DETECT=0 NEED_RELOGIN=0 #============================== # 日志函数 #============================== log() { echo -e "[INFO] $*"; } warn() { echo -e "[WARN] $*"; } error() { echo -e "[ERROR] $*" >&2; } ok() { echo -e "[ OK ] $*"; } #============================== # 帮助信息 #============================== show_help() { cat <<'EOF' Docker 安装脚本(Ubuntu) 用法: install_docker.sh [options] 选项: -u 按官方方式卸载旧 Docker 相关包后再安装 -m 使用国内 Docker APT 源安装(清华源) -r 配置 Docker registry 国内镜像加速 -c 配置容器日志限制 -a 自动检测网络环境(国内则自动启用 -m 和 -r) -h 显示帮助信息 说明: - 不加 -m 时,默认使用 Docker 官方 APT 源 - 不加 -r 时,不配置 registry mirror - -c 会配置 json-file 日志轮转: max-size=20m max-file=3 - 若 /etc/docker/daemon.json 已存在,会先自动备份再覆盖 - 本脚本不会自动删除 /var/lib/docker 和 /var/lib/containerd 示例: sudo bash install_docker.sh sudo bash install_docker.sh -u sudo bash install_docker.sh -m -r sudo bash install_docker.sh -a -c sudo bash install_docker.sh -u -a -c EOF } #============================== # 错误处理 #============================== on_error() { local exit_code=$? error "脚本执行失败,退出码:${exit_code}" exit "${exit_code}" } trap on_error ERR #============================== # 权限检查 #============================== check_root() { if [ "$(id -u)" -ne 0 ]; then error "请使用 root 或 sudo 运行本脚本。" exit 1 fi } #============================== # 系统检查 #============================== detect_os() { if [ ! -f /etc/os-release ]; then error "无法检测系统版本:缺少 /etc/os-release" exit 1 fi # shellcheck disable=SC1091 . /etc/os-release if [ "${ID:-}" != "ubuntu" ]; then error "当前系统不是 Ubuntu(检测到 ID=${ID:-unknown}),本脚本仅支持 Ubuntu。" exit 1 fi CODENAME="${VERSION_CODENAME:-}" if [ -z "$CODENAME" ]; then case "${VERSION_ID:-}" in "24.04") CODENAME="noble" ;; "22.04") CODENAME="jammy" ;; "20.04") CODENAME="focal" ;; *) error "无法自动识别当前 Ubuntu 代号(VERSION_ID=${VERSION_ID:-unknown})" exit 1 ;; esac fi ARCH="$(dpkg --print-architecture)" ok "检测到系统:Ubuntu ${VERSION_ID:-unknown} (${CODENAME}), arch=${ARCH}" } #============================== # 参数解析 #============================== parse_args() { while getopts ":umrcah" opt; do case "${opt}" in u) UNINSTALL=1 ;; m) USE_CN_SOURCE=1 ;; r) ENABLE_REGISTRY_MIRROR=1 ;; c) ENABLE_LOG_LIMIT=1 ;; a) AUTO_DETECT=1 ;; h) show_help exit 0 ;; :) error "选项 -${OPTARG} 缺少参数" exit 1 ;; \?) error "未知选项: -${OPTARG}" show_help exit 1 ;; esac done } #============================== # 自动检测国内网络 #============================== detect_china_network() { local country="" country="$(curl -fsSL --connect-timeout 3 --max-time 5 https://ipinfo.io/country 2>/dev/null | tr -d '[:space:]' || true)" if [ "$country" = "CN" ]; then return 0 elif [ -n "$country" ]; then return 1 fi country="$(curl -fsSL --connect-timeout 3 --max-time 5 https://ifconfig.co/country-iso 2>/dev/null | tr -d '[:space:]' || true)" if [ "$country" = "CN" ]; then return 0 elif [ -n "$country" ]; then return 1 fi if ! curl -fsSL --connect-timeout 3 --max-time 5 https://registry-1.docker.io/v2/ >/dev/null 2>&1; then warn "地区判断失败,且 Docker Hub 连通性较差,按中国网络环境处理" return 0 fi return 1 } apply_auto_detect() { if [ "$AUTO_DETECT" -ne 1 ]; then return fi log "开始自动检测网络环境..." if detect_china_network; then ok "检测结果:更像中国网络环境,自动启用国内 APT 源和 registry 镜像加速" USE_CN_SOURCE=1 ENABLE_REGISTRY_MIRROR=1 else ok "检测结果:更像海外网络环境,默认使用官方 APT 源,不启用 registry 镜像加速" fi } #============================== # 安装基础依赖 #============================== install_dependencies() { log "安装必要依赖..." apt update apt install -y ca-certificates curl gnupg install -m 0755 -d /etc/apt/keyrings ok "基础依赖安装完成" } #============================== # 卸载旧 Docker(官方方式) #============================== uninstall_old_docker() { log "按官方方式卸载旧 Docker 相关包..." systemctl stop docker 2>/dev/null || true systemctl stop docker.socket 2>/dev/null || true systemctl stop containerd 2>/dev/null || true for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do apt remove -y "$pkg" || true done apt autoremove -y || true rm -f /etc/apt/sources.list.d/docker.list rm -f /etc/apt/keyrings/docker.gpg rm -f /etc/apt/keyrings/docker.asc warn "未自动删除 /var/lib/docker 和 /var/lib/containerd,避免误删现有镜像/容器数据" warn "如需彻底清理,可手动执行:rm -rf /var/lib/docker /var/lib/containerd" ok "旧 Docker 相关包清理完成" } #============================== # 配置 Docker APT 源 #============================== configure_docker_repo() { log "配置 Docker APT 源..." rm -f /etc/apt/sources.list.d/docker.list rm -f /etc/apt/keyrings/docker.gpg if [ "$USE_CN_SOURCE" -eq 1 ]; then log "使用清华 Docker CE APT 源" curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg \ | gpg --dearmor -o /etc/apt/keyrings/docker.gpg cat >/etc/apt/sources.list.d/docker.list </etc/apt/sources.list.d/docker.list </etc/docker/daemon.json ok "已写入 /etc/docker/daemon.json" } #============================== # 启动 Docker #============================== enable_and_start_docker() { log "启动 Docker 服务并设置开机自启..." systemctl enable --now docker ok "Docker 服务已启动" } #============================== # 应用 Docker 配置 #============================== apply_docker_config_if_needed() { if [ "$ENABLE_LOG_LIMIT" -eq 0 ] && [ "$ENABLE_REGISTRY_MIRROR" -eq 0 ]; then return fi log "写入 Docker 配置..." write_daemon_json log "重载并重启 Docker..." systemctl daemon-reload systemctl restart docker ok "Docker 配置已生效" } #============================== # 用户加入 docker 组 #============================== add_user_to_docker_group() { local orig_user="${SUDO_USER:-}" if [ -n "$orig_user" ] && [ "$orig_user" != "root" ]; then log "将用户 ${orig_user} 加入 docker 组..." usermod -aG docker "$orig_user" NEED_RELOGIN=1 ok "用户 ${orig_user} 已加入 docker 组" fi } #============================== # 验证安装 #============================== verify_installation() { echo log "验证安装结果..." docker --version docker compose version systemctl is-active docker >/dev/null ok "Docker 当前状态:active" echo echo "========== 安装结果 ==========" if [ "$USE_CN_SOURCE" -eq 1 ]; then echo "APT 源:国内清华 Docker 源" else echo "APT 源:Docker 官方源" fi if [ "$ENABLE_REGISTRY_MIRROR" -eq 1 ]; then echo "Registry 镜像加速:已开启" else echo "Registry 镜像加速:未开启" fi if [ "$ENABLE_LOG_LIMIT" -eq 1 ]; then echo "容器日志限制:已开启(20m x 3)" else echo "容器日志限制:未开启" fi if [ "$NEED_RELOGIN" -eq 1 ]; then echo "提示:请退出当前终端并重新登录后,再以普通用户执行 docker 命令。" fi echo "测试命令:docker run hello-world" echo "==============================" } #============================== # 主流程 #============================== main() { parse_args "$@" check_root detect_os apply_auto_detect echo echo "==== Docker 安装脚本启动 ====" echo "UNINSTALL=${UNINSTALL}" echo "USE_CN_SOURCE=${USE_CN_SOURCE}" echo "ENABLE_REGISTRY_MIRROR=${ENABLE_REGISTRY_MIRROR}" echo "ENABLE_LOG_LIMIT=${ENABLE_LOG_LIMIT}" echo "AUTO_DETECT=${AUTO_DETECT}" echo if [ "$UNINSTALL" -eq 1 ]; then uninstall_old_docker fi install_dependencies configure_docker_repo install_docker enable_and_start_docker apply_docker_config_if_needed add_user_to_docker_group verify_installation } main "$@" ``` # 将用户假如Docker用户组 ```bash sudo usermod -aG docker ${USER} ``` Loading... ```bash #!/usr/bin/env bash # # Docker 安装脚本(Ubuntu) # # 功能: # - 安装 docker-ce / docker-ce-cli / containerd.io # - 安装 docker-buildx-plugin / docker-compose-plugin # - 可选按官方方式卸载旧 Docker 相关包 # - 可选使用国内 APT 源安装 Docker # - 可选配置 Docker registry 国内镜像加速 # - 可选配置容器日志轮转限制 # - 可选自动检测网络环境 # # 支持: # - Ubuntu 20.04 / 22.04 / 24.04 # # 用法示例: # sudo bash install_docker.sh # sudo bash install_docker.sh -u # sudo bash install_docker.sh -m -r -c # sudo bash install_docker.sh -a -c if [ -z "${BASH_VERSION:-}" ]; then echo "Please run this script with bash" exit 1 fi set -Eeuo pipefail #============================== # 默认参数 #============================== UNINSTALL=0 USE_CN_SOURCE=0 ENABLE_LOG_LIMIT=0 ENABLE_REGISTRY_MIRROR=0 AUTO_DETECT=0 NEED_RELOGIN=0 #============================== # 日志函数 #============================== log() { echo -e "[INFO] $*"; } warn() { echo -e "[WARN] $*"; } error() { echo -e "[ERROR] $*" >&2; } ok() { echo -e "[ OK ] $*"; } #============================== # 帮助信息 #============================== show_help() { cat <<'EOF' Docker 安装脚本(Ubuntu) 用法: install_docker.sh [options] 选项: -u 按官方方式卸载旧 Docker 相关包后再安装 -m 使用国内 Docker APT 源安装(清华源) -r 配置 Docker registry 国内镜像加速 -c 配置容器日志限制 -a 自动检测网络环境(国内则自动启用 -m 和 -r) -h 显示帮助信息 说明: - 不加 -m 时,默认使用 Docker 官方 APT 源 - 不加 -r 时,不配置 registry mirror - -c 会配置 json-file 日志轮转: max-size=20m max-file=3 - 若 /etc/docker/daemon.json 已存在,会先自动备份再覆盖 - 本脚本不会自动删除 /var/lib/docker 和 /var/lib/containerd 示例: sudo bash install_docker.sh sudo bash install_docker.sh -u sudo bash install_docker.sh -m -r sudo bash install_docker.sh -a -c sudo bash install_docker.sh -u -a -c EOF } #============================== # 错误处理 #============================== on_error() { local exit_code=$? error "脚本执行失败,退出码:${exit_code}" exit "${exit_code}" } trap on_error ERR #============================== # 权限检查 #============================== check_root() { if [ "$(id -u)" -ne 0 ]; then error "请使用 root 或 sudo 运行本脚本。" exit 1 fi } #============================== # 系统检查 #============================== detect_os() { if [ ! -f /etc/os-release ]; then error "无法检测系统版本:缺少 /etc/os-release" exit 1 fi # shellcheck disable=SC1091 . /etc/os-release if [ "${ID:-}" != "ubuntu" ]; then error "当前系统不是 Ubuntu(检测到 ID=${ID:-unknown}),本脚本仅支持 Ubuntu。" exit 1 fi CODENAME="${VERSION_CODENAME:-}" if [ -z "$CODENAME" ]; then case "${VERSION_ID:-}" in "24.04") CODENAME="noble" ;; "22.04") CODENAME="jammy" ;; "20.04") CODENAME="focal" ;; *) error "无法自动识别当前 Ubuntu 代号(VERSION_ID=${VERSION_ID:-unknown})" exit 1 ;; esac fi ARCH="$(dpkg --print-architecture)" ok "检测到系统:Ubuntu ${VERSION_ID:-unknown} (${CODENAME}), arch=${ARCH}" } #============================== # 参数解析 #============================== parse_args() { while getopts ":umrcah" opt; do case "${opt}" in u) UNINSTALL=1 ;; m) USE_CN_SOURCE=1 ;; r) ENABLE_REGISTRY_MIRROR=1 ;; c) ENABLE_LOG_LIMIT=1 ;; a) AUTO_DETECT=1 ;; h) show_help exit 0 ;; :) error "选项 -${OPTARG} 缺少参数" exit 1 ;; \?) error "未知选项: -${OPTARG}" show_help exit 1 ;; esac done } #============================== # 自动检测国内网络 #============================== detect_china_network() { local country="" country="$(curl -fsSL --connect-timeout 3 --max-time 5 https://ipinfo.io/country 2>/dev/null | tr -d '[:space:]' || true)" if [ "$country" = "CN" ]; then return 0 elif [ -n "$country" ]; then return 1 fi country="$(curl -fsSL --connect-timeout 3 --max-time 5 https://ifconfig.co/country-iso 2>/dev/null | tr -d '[:space:]' || true)" if [ "$country" = "CN" ]; then return 0 elif [ -n "$country" ]; then return 1 fi if ! curl -fsSL --connect-timeout 3 --max-time 5 https://registry-1.docker.io/v2/ >/dev/null 2>&1; then warn "地区判断失败,且 Docker Hub 连通性较差,按中国网络环境处理" return 0 fi return 1 } apply_auto_detect() { if [ "$AUTO_DETECT" -ne 1 ]; then return fi log "开始自动检测网络环境..." if detect_china_network; then ok "检测结果:更像中国网络环境,自动启用国内 APT 源和 registry 镜像加速" USE_CN_SOURCE=1 ENABLE_REGISTRY_MIRROR=1 else ok "检测结果:更像海外网络环境,默认使用官方 APT 源,不启用 registry 镜像加速" fi } #============================== # 安装基础依赖 #============================== install_dependencies() { log "安装必要依赖..." apt update apt install -y ca-certificates curl gnupg install -m 0755 -d /etc/apt/keyrings ok "基础依赖安装完成" } #============================== # 卸载旧 Docker(官方方式) #============================== uninstall_old_docker() { log "按官方方式卸载旧 Docker 相关包..." systemctl stop docker 2>/dev/null || true systemctl stop docker.socket 2>/dev/null || true systemctl stop containerd 2>/dev/null || true for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do apt remove -y "$pkg" || true done apt autoremove -y || true rm -f /etc/apt/sources.list.d/docker.list rm -f /etc/apt/keyrings/docker.gpg rm -f /etc/apt/keyrings/docker.asc warn "未自动删除 /var/lib/docker 和 /var/lib/containerd,避免误删现有镜像/容器数据" warn "如需彻底清理,可手动执行:rm -rf /var/lib/docker /var/lib/containerd" ok "旧 Docker 相关包清理完成" } #============================== # 配置 Docker APT 源 #============================== configure_docker_repo() { log "配置 Docker APT 源..." rm -f /etc/apt/sources.list.d/docker.list rm -f /etc/apt/keyrings/docker.gpg if [ "$USE_CN_SOURCE" -eq 1 ]; then log "使用清华 Docker CE APT 源" curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg \ | gpg --dearmor -o /etc/apt/keyrings/docker.gpg cat >/etc/apt/sources.list.d/docker.list <<EOF deb [arch=${ARCH} signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu ${CODENAME} stable EOF else log "使用 Docker 官方 APT 源" curl -fsSL https://download.docker.com/linux/ubuntu/gpg \ | gpg --dearmor -o /etc/apt/keyrings/docker.gpg cat >/etc/apt/sources.list.d/docker.list <<EOF deb [arch=${ARCH} signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu ${CODENAME} stable EOF fi chmod a+r /etc/apt/keyrings/docker.gpg apt update ok "Docker APT 源配置完成" } #============================== # 安装 Docker #============================== install_docker() { log "安装 Docker Engine / CLI / containerd / Buildx / Compose..." apt install -y \ docker-ce \ docker-ce-cli \ containerd.io \ docker-buildx-plugin \ docker-compose-plugin ok "Docker 安装完成" } #============================== # 备份 daemon.json #============================== backup_daemon_json_if_exists() { if [ -f /etc/docker/daemon.json ]; then local backup_file="/etc/docker/daemon.json.bak.$(date +%Y%m%d%H%M%S)" cp -f /etc/docker/daemon.json "$backup_file" warn "检测到已有 /etc/docker/daemon.json,已备份到:$backup_file" fi } #============================== # 写入 daemon.json #============================== write_daemon_json() { mkdir -p /etc/docker backup_daemon_json_if_exists local need_comma=0 { echo "{" if [ "$ENABLE_LOG_LIMIT" -eq 1 ]; then echo ' "log-driver": "json-file",' echo ' "log-opts": {' echo ' "max-size": "20m",' echo ' "max-file": "3"' echo -n ' }' need_comma=1 fi if [ "$ENABLE_REGISTRY_MIRROR" -eq 1 ]; then if [ "$need_comma" -eq 1 ]; then echo "," else echo fi echo ' "registry-mirrors": [' echo ' "https://docker.m.daocloud.io",' echo ' "https://hub-mirror.c.163.com",' echo ' "https://mirror.baidubce.com"' echo -n ' ]' fi echo echo "}" } >/etc/docker/daemon.json ok "已写入 /etc/docker/daemon.json" } #============================== # 启动 Docker #============================== enable_and_start_docker() { log "启动 Docker 服务并设置开机自启..." systemctl enable --now docker ok "Docker 服务已启动" } #============================== # 应用 Docker 配置 #============================== apply_docker_config_if_needed() { if [ "$ENABLE_LOG_LIMIT" -eq 0 ] && [ "$ENABLE_REGISTRY_MIRROR" -eq 0 ]; then return fi log "写入 Docker 配置..." write_daemon_json log "重载并重启 Docker..." systemctl daemon-reload systemctl restart docker ok "Docker 配置已生效" } #============================== # 用户加入 docker 组 #============================== add_user_to_docker_group() { local orig_user="${SUDO_USER:-}" if [ -n "$orig_user" ] && [ "$orig_user" != "root" ]; then log "将用户 ${orig_user} 加入 docker 组..." usermod -aG docker "$orig_user" NEED_RELOGIN=1 ok "用户 ${orig_user} 已加入 docker 组" fi } #============================== # 验证安装 #============================== verify_installation() { echo log "验证安装结果..." docker --version docker compose version systemctl is-active docker >/dev/null ok "Docker 当前状态:active" echo echo "========== 安装结果 ==========" if [ "$USE_CN_SOURCE" -eq 1 ]; then echo "APT 源:国内清华 Docker 源" else echo "APT 源:Docker 官方源" fi if [ "$ENABLE_REGISTRY_MIRROR" -eq 1 ]; then echo "Registry 镜像加速:已开启" else echo "Registry 镜像加速:未开启" fi if [ "$ENABLE_LOG_LIMIT" -eq 1 ]; then echo "容器日志限制:已开启(20m x 3)" else echo "容器日志限制:未开启" fi if [ "$NEED_RELOGIN" -eq 1 ]; then echo "提示:请退出当前终端并重新登录后,再以普通用户执行 docker 命令。" fi echo "测试命令:docker run hello-world" echo "==============================" } #============================== # 主流程 #============================== main() { parse_args "$@" check_root detect_os apply_auto_detect echo echo "==== Docker 安装脚本启动 ====" echo "UNINSTALL=${UNINSTALL}" echo "USE_CN_SOURCE=${USE_CN_SOURCE}" echo "ENABLE_REGISTRY_MIRROR=${ENABLE_REGISTRY_MIRROR}" echo "ENABLE_LOG_LIMIT=${ENABLE_LOG_LIMIT}" echo "AUTO_DETECT=${AUTO_DETECT}" echo if [ "$UNINSTALL" -eq 1 ]; then uninstall_old_docker fi install_dependencies configure_docker_repo install_docker enable_and_start_docker apply_docker_config_if_needed add_user_to_docker_group verify_installation } main "$@" ``` # 将用户假如Docker用户组 ```bash sudo usermod -aG docker ${USER} ``` 最后修改:2026 年 03 月 17 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏