一键docker脚本

news2024/11/29 11:40:38

#!/bin/bash
## Author: SuperManito
## Modified: 2024-10-07
## License: MIT
## GitHub: https://github.com/SuperManito/LinuxMirrors
## Website: https://linuxmirrors.cn

## Docker CE 软件源列表
# 格式:"软件源名称@软件源地址"
mirror_list_docker_ce=(
    "阿里云@mirrors.aliyun.com/docker-ce"
    "腾讯云@mirrors.tencent.com/docker-ce"
    "华为云@repo.huaweicloud.com/docker-ce"
    "微软 Azure 中国@mirror.azure.cn/docker-ce"
    "网易@mirrors.163.com/docker-ce"
    "火山引擎@mirrors.volces.com/docker"
    "清华大学@mirrors.tuna.tsinghua.edu.cn/docker-ce"
    "北京大学@mirrors.pku.edu.cn/docker-ce"
    "南京大学@mirrors.nju.edu.cn/docker-ce"
    "上海交通大学@mirror.sjtu.edu.cn/docker-ce"
    "中国科学技术大学@mirrors.ustc.edu.cn/docker-ce"
    "中国科学院软件研究所@mirror.iscas.ac.cn/docker-ce"
    "官方@download.docker.com"
)

## Docker Registry 仓库列表
# 格式:"软件源名称@软件源地址"
mirror_list_registry=(
    "道客 DaoCloud@docker.m.daocloud.io"
    "AtomHub 可信镜像中心@hub.atomgit.com"
    "阿里云(杭州)@registry.cn-hangzhou.aliyuncs.com"
    "阿里云(上海)@registry.cn-shanghai.aliyuncs.com"
    "阿里云(青岛)@registry.cn-qingdao.aliyuncs.com"
    "阿里云(北京)@registry.cn-beijing.aliyuncs.com"
    "阿里云(张家口)@registry.cn-zhangjiakou.aliyuncs.com"
    "阿里云(呼和浩特)@registry.cn-huhehaote.aliyuncs.com"
    "阿里云(乌兰察布)@registry.cn-wulanchabu.aliyuncs.com"
    "阿里云(深圳)@registry.cn-shenzhen.aliyuncs.com"
    "阿里云(河源)@registry.cn-heyuan.aliyuncs.com"
    "阿里云(广州)@registry.cn-guangzhou.aliyuncs.com"
    "阿里云(成都)@registry.cn-chengdu.aliyuncs.com"
    "阿里云(香港)@registry.cn-hongkong.aliyuncs.com"
    "阿里云(日本-东京)@registry.ap-northeast-1.aliyuncs.com"
    "阿里云(新加坡)@registry.ap-southeast-1.aliyuncs.com"
    "阿里云(澳大利亚-悉尼)@registry.ap-southeast-2.aliyuncs.com"
    "阿里云(马来西亚-吉隆坡)@registry.ap-southeast-3.aliyuncs.com"
    "阿里云(印度尼西亚-雅加达)@registry.ap-southeast-5.aliyuncs.com"
    "阿里云(印度-孟买)@registry.ap-south-1.aliyuncs.com"
    "阿里云(德国-法兰克福)@registry.eu-central-1.aliyuncs.com"
    "阿里云(英国-伦敦)@registry.eu-west-1.aliyuncs.com"
    "阿里云(美国西部-硅谷)@registry.us-west-1.aliyuncs.com"
    "阿里云(美国东部-弗吉尼亚)@registry.us-east-1.aliyuncs.com"
    "阿里云(阿联酋-迪拜)@registry.me-east-1.aliyuncs.com"
    "腾讯云@mirror.ccs.tencentyun.com"
    "谷歌云@mirror.gcr.io"
    "官方 Docker Hub@registry.hub.docker.com"
)

## 定义系统判定变量
SYSTEM_DEBIAN="Debian"
SYSTEM_UBUNTU="Ubuntu"
SYSTEM_KALI="Kali"
SYSTEM_DEEPIN="Deepin"
SYSTEM_LINUX_MINT="Linuxmint"
SYSTEM_ZORIN="Zorin"
SYSTEM_REDHAT="RedHat"
SYSTEM_RHEL="Red Hat Enterprise Linux"
SYSTEM_CENTOS="CentOS"
SYSTEM_CENTOS_STREAM="CentOS Stream"
SYSTEM_ROCKY="Rocky"
SYSTEM_ALMALINUX="AlmaLinux"
SYSTEM_FEDORA="Fedora"
SYSTEM_OPENCLOUDOS="OpenCloudOS"
SYSTEM_OPENEULER="openEuler"
SYSTEM_OPENSUSE="openSUSE"
SYSTEM_ARCH="Arch"
SYSTEM_ALPINE="Alpine"

## 定义系统版本文件
File_LinuxRelease=/etc/os-release
File_RedHatRelease=/etc/redhat-release
File_DebianVersion=/etc/debian_version
File_ArmbianRelease=/etc/armbian-release
File_OpenCloudOSRelease=/etc/opencloudos-release
File_openEulerRelease=/etc/openEuler-release
File_ArchLinuxRelease=/etc/arch-release
File_AlpineRelease=/etc/alpine-release
File_ProxmoxVersion=/etc/pve/.version

## 定义软件源相关文件或目录
File_DebianSourceList=/etc/apt/sources.list
Dir_DebianExtendSource=/etc/apt/sources.list.d
Dir_YumRepos=/etc/yum.repos.d

## 定义 Docker 相关变量
DockerDir=/etc/docker
DockerConfig=$DockerDir/daemon.json
DockerConfigBackup=$DockerDir/daemon.json.bak
DockerVersionFile=docker-version.txt
DockerCEVersionFile=docker-ce-version.txt
DockerCECLIVersionFile=docker-ce-cli-version.txt

## 定义颜色变量
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033[34m'
PURPLE='\033[35m'
AZURE='\033[36m'
PLAIN='\033[0m'
BOLD='\033[1m'
SUCCESS="[\033[1;32m成功${PLAIN}]"
COMPLETE="[\033[1;32m完成${PLAIN}]"
WARN="[\033[1;5;33m注意${PLAIN}]"
ERROR="[\033[1;31m错误${PLAIN}]"
FAIL="[\033[1;31m失败${PLAIN}]"
TIP="[\033[1;32m提示${PLAIN}]"
WORKING="[\033[1;36m >_ ${PLAIN}]"

function main() {
    permission_judgment
    collect_system_info
    run_start
    choose_mirrors
    close_firewall_service
    install_dependency_packages
    configure_docker_ce_mirror
    install_docker_engine
    check_version
    run_end
}

## 处理命令选项
function handle_command_options() {
    ## 命令帮助
    function output_command_help() {
        echo -e "
命令选项(名称/含义/选项值):

  --source                 指定 Docker CE 源地址                     地址
  --source-registry        指定 Docker Registry 源地址               地址
  --codename               指定 Debian 系操作系统的版本代号          代号名称
  --install-latested       控制是否安装最新版本的 Docker Engine      true 或 false
  --ignore-backup-tips     忽略覆盖备份提示                          无

问题报告 https://github.com/SuperManito/LinuxMirrors/issues
  "
    }

    ## 判断参数
    while [ $# -gt 0 ]; do
        case "$1" in
        ## 指定 Docker CE 软件源地址
        --source)
            if [ "$2" ]; then
                echo "$2" | grep -Eq "\(|\)|\[|\]|\{|\}"
                if [ $? -eq 0 ]; then
                    output_error "命令选项 ${BLUE}$2${PLAIN} 无效,请在该选项后指定有效的地址!"
                else
                    SOURCE="$(echo "$2" | sed -e 's,^http[s]\?://,,g' -e 's,/$,,')"
                    shift
                fi
            else
                output_error "命令选项 ${BLUE}$1${PLAIN} 无效,请在该选项后指定软件源地址!"
            fi
            ;;
        ## 指定 Docker Registry 仓库地址
        --source-registry)
            if [ "$2" ]; then
                echo "$2" | grep -Eq "\(|\)|\[|\]|\{|\}"
                if [ $? -eq 0 ]; then
                    output_error "命令选项 ${BLUE}$2${PLAIN} 无效,请在该选项后指定有效的地址!"
                else
                    SOURCE_REGISTRY="$(echo "$2" | sed -e 's,^http[s]\?://,,g' -e 's,/$,,')"
                    shift
                fi
            else
                output_error "命令选项 ${BLUE}$1${PLAIN} 无效,请在该选项后指定镜像仓库地址!"
            fi
            ;;
        ## 指定 Debian 版本代号
        --codename)
            if [ "$2" ]; then
                DEBIAN_CODENAME="$2"
                shift
            else
                output_error "命令选项 ${BLUE}$1${PLAIN} 无效,请在该选项后指定版本代号!"
            fi
            ;;
        ## 安装最新版本
        --install-latested)
            if [ "$2" ]; then
                case "$2" in
                [Tt]rue | [Ff]alse)
                    INSTALL_LATESTED_DOCKER="${2,,}"
                    shift
                    ;;
                *)
                    output_error "命令选项 ${BLUE}$2${PLAIN} 无效,请在该选项后指定 true 或 false !"
                    ;;
                esac
            else
                output_error "命令选项 ${BLUE}$1${PLAIN} 无效,请在该选项后指定 true 或 false !"
            fi
            ;;
        ## 忽略覆盖备份提示
        --ignore-backup-tips)
            IGNORE_BACKUP_TIPS="true"
            ;;
        ## 命令帮助
        --help)
            output_command_help
            exit
            ;;
        *)
            output_error "命令选项 ${BLUE}$1${PLAIN} 无效,请确认后重新输入!"
            ;;
        esac
        shift
    done
    ## 给部分命令选项赋予默认值
    IGNORE_BACKUP_TIPS="${IGNORE_BACKUP_TIPS:-"false"}"
}

function run_start() {
    [[ -z "${SOURCE}" || -z "${SOURCE_REGISTRY}" ]] && clear
    echo -e ' +-----------------------------------+'
    echo -e " | \033[0;1;35;95m⡇\033[0m  \033[0;1;33;93m⠄\033[0m \033[0;1;32;92m⣀⡀\033[0m \033[0;1;36;96m⡀\033[0;1;34;94m⢀\033[0m \033[0;1;35;95m⡀⢀\033[0m \033[0;1;31;91m⡷\033[0;1;33;93m⢾\033[0m \033[0;1;32;92m⠄\033[0m \033[0;1;36;96m⡀⣀\033[0m \033[0;1;34;94m⡀\033[0;1;35;95m⣀\033[0m \033[0;1;31;91m⢀⡀\033[0m \033[0;1;33;93m⡀\033[0;1;32;92m⣀\033[0m \033[0;1;36;96m⢀⣀\033[0m |"
    echo -e " | \033[0;1;31;91m⠧\033[0;1;33;93m⠤\033[0m \033[0;1;32;92m⠇\033[0m \033[0;1;36;96m⠇⠸\033[0m \033[0;1;34;94m⠣\033[0;1;35;95m⠼\033[0m \033[0;1;31;91m⠜⠣\033[0m \033[0;1;33;93m⠇\033[0;1;32;92m⠸\033[0m \033[0;1;36;96m⠇\033[0m \033[0;1;34;94m⠏\033[0m  \033[0;1;35;95m⠏\033[0m  \033[0;1;33;93m⠣⠜\033[0m \033[0;1;32;92m⠏\033[0m  \033[0;1;34;94m⠭⠕\033[0m |"
    echo -e ' +-----------------------------------+'
    echo -e ' 欢迎使用 Docker Engine 安装与换源脚本'
}

## 运行结束
function run_end() {
    echo -e "\n     ------ 脚本执行结束 ------"
    echo -e ' \033[0;1;35;95m┌─\033[0;1;31;91m──\033[0;1;33;93m──\033[0;1;32;92m──\033[0;1;36;96m──\033[0;1;34;94m──\033[0;1;35;95m──\033[0;1;31;91m──\033[0;1;33;93m──\033[0;1;32;92m──\033[0;1;36;96m──\033[0;1;34;94m──\033[0;1;35;95m──\033[0;1;31;91m──\033[0;1;33;93m──\033[0;1;32;92m──\033[0;1;36;96m┐\033[0m'
    echo -e ' \033[0;1;31;91m│▞\033[0;1;33;93m▀▖\033[0m            \033[0;1;32;92m▙▗\033[0;1;36;96m▌\033[0m      \033[0;1;31;91m▗\033[0;1;33;93m▐\033[0m     \033[0;1;34;94m│\033[0m'
    echo -e ' \033[0;1;33;93m│▚\033[0;1;32;92m▄\033[0m \033[0;1;36;96m▌\033[0m \033[0;1;34;94m▌▛\033[0;1;35;95m▀▖\033[0;1;31;91m▞▀\033[0;1;33;93m▖▙\033[0;1;32;92m▀▖\033[0;1;36;96m▌▘\033[0;1;34;94m▌▝\033[0;1;35;95m▀▖\033[0;1;31;91m▛▀\033[0;1;33;93m▖▄\033[0;1;32;92m▜▀\033[0m \033[0;1;36;96m▞\033[0;1;34;94m▀▖\033[0;1;35;95m│\033[0m'
    echo -e ' \033[0;1;32;92m│▖\033[0m \033[0;1;36;96m▌\033[0;1;34;94m▌\033[0m \033[0;1;35;95m▌▙\033[0;1;31;91m▄▘\033[0;1;33;93m▛▀\033[0m \033[0;1;32;92m▌\033[0m  \033[0;1;34;94m▌\033[0m \033[0;1;35;95m▌▞\033[0;1;31;91m▀▌\033[0;1;33;93m▌\033[0m \033[0;1;32;92m▌▐\033[0;1;36;96m▐\033[0m \033[0;1;34;94m▖▌\033[0m \033[0;1;35;95m▌\033[0;1;31;91m│\033[0m'
    echo -e ' \033[0;1;36;96m│▝\033[0;1;34;94m▀\033[0m \033[0;1;35;95m▝▀\033[0;1;31;91m▘▌\033[0m  \033[0;1;32;92m▝▀\033[0;1;36;96m▘▘\033[0m  \033[0;1;35;95m▘\033[0m \033[0;1;31;91m▘▝\033[0;1;33;93m▀▘\033[0;1;32;92m▘\033[0m \033[0;1;36;96m▘▀\033[0;1;34;94m▘▀\033[0m \033[0;1;35;95m▝\033[0;1;31;91m▀\033[0m \033[0;1;33;93m│\033[0m'
    echo -e ' \033[0;1;34;94m└─\033[0;1;35;95m──\033[0;1;31;91m──\033[0;1;33;93m──\033[0;1;32;92m──\033[0;1;36;96m──\033[0;1;34;94m──\033[0;1;35;95m──\033[0;1;31;91m──\033[0;1;33;93m──\033[0;1;32;92m──\033[0;1;36;96m──\033[0;1;34;94m──\033[0;1;35;95m──\033[0;1;31;91m──\033[0;1;33;93m──\033[0;1;32;92m┘\033[0m'
    echo -e "     \033[1;34mPowered by linuxmirrors.cn\033[0m\n"
}

## 报错退出
function output_error() {
    [ "$1" ] && echo -e "\n$ERROR $1\n"
    exit 1
}

## 权限判定
function permission_judgment() {
    if [ $UID -ne 0 ]; then
        output_error "权限不足,请使用 Root 用户运行本脚本"
    fi
}

## 收集系统信息
function collect_system_info() {
    ## 定义系统名称
    SYSTEM_NAME="$(cat $File_LinuxRelease | grep -E "^NAME=" | awk -F '=' '{print$2}' | sed "s/[\'\"]//g")"
    grep -q "PRETTY_NAME=" $File_LinuxRelease && SYSTEM_PRETTY_NAME="$(cat $File_LinuxRelease | grep -E "^PRETTY_NAME=" | awk -F '=' '{print$2}' | sed "s/[\'\"]//g")"
    ## 定义系统版本号
    SYSTEM_VERSION_NUMBER="$(cat $File_LinuxRelease | grep -E "^VERSION_ID=" | awk -F '=' '{print$2}' | sed "s/[\'\"]//g")"
    ## 定义系统ID
    SYSTEM_ID="$(cat $File_LinuxRelease | grep -E "^ID=" | awk -F '=' '{print$2}' | sed "s/[\'\"]//g")"
    ## 判定当前系统派系
    if [ -s $File_DebianVersion ]; then
        SYSTEM_FACTIONS="${SYSTEM_DEBIAN}"
    elif [ -s $File_openEulerRelease ]; then
        SYSTEM_FACTIONS="${SYSTEM_OPENEULER}"
    elif [ -s $File_RedHatRelease ]; then
        SYSTEM_FACTIONS="${SYSTEM_REDHAT}"
    elif [ -s $File_OpenCloudOSRelease ]; then
        SYSTEM_FACTIONS="${SYSTEM_OPENCLOUDOS}" # 注:RedHat 判断优先级需要高于 OpenCloudOS,因为官方宣称8版本基于红帽而9版本不是
    else
        output_error "无法判断当前运行环境或不支持当前操作系统!"
    fi
    ## 判定系统类型、版本、版本号
    case "${SYSTEM_FACTIONS}" in
    "${SYSTEM_DEBIAN}")
        if [ ! -x /usr/bin/lsb_release ]; then
            apt-get install -y lsb-release
            if [ $? -ne 0 ]; then
                output_error "lsb-release 软件包安装失败\n\n本脚本依赖 lsb_release 指令判断系统具体类型和版本,当前系统可能为精简安装,请自行安装后重新执行脚本!"
            fi
        fi
        SYSTEM_JUDGMENT="$(lsb_release -is)"
        SYSTEM_VERSION_CODENAME="${DEBIAN_CODENAME:-"$(lsb_release -cs)"}"
        ;;
    "${SYSTEM_REDHAT}")
        SYSTEM_JUDGMENT="$(awk '{printf $1}' $File_RedHatRelease)"
        ## 特殊系统判断
        # Red Hat Enterprise Linux
        grep -q "${SYSTEM_RHEL}" $File_RedHatRelease && SYSTEM_JUDGMENT="${SYSTEM_RHEL}"
        # CentOS Stream
        grep -q "${SYSTEM_CENTOS_STREAM}" $File_RedHatRelease && SYSTEM_JUDGMENT="${SYSTEM_CENTOS_STREAM}"
        ;;
    *)
        SYSTEM_JUDGMENT="${SYSTEM_FACTIONS}"
        ;;
    esac
    ## 判定系统处理器架构
    case "$(uname -m)" in
    x86_64)
        DEVICE_ARCH="x86_64"
        SOURCE_ARCH="amd64"
        ;;
    aarch64)
        DEVICE_ARCH="ARM64"
        SOURCE_ARCH="arm64"
        ;;
    armv7l)
        DEVICE_ARCH="ARMv7"
        SOURCE_ARCH="armhf"
        ;;
    armv6l)
        DEVICE_ARCH="ARMv6"
        SOURCE_ARCH="armhf"
        ;;
    ppc64le)
        DEVICE_ARCH="ppc64le"
        SOURCE_ARCH="ppc64le"
        ;;
    s390x)
        DEVICE_ARCH="s390x"
        SOURCE_ARCH="s390x"
        ;;
    i386 | i686)
        output_error "Docker Engine 不支持安装在 x86_32 架构的环境上!"
        ;;
    *)
        output_error "未知的系统架构:$(uname -m)"
        ;;
    esac
    ## 定义软件源分支名称
    case "${SYSTEM_FACTIONS}" in
    "${SYSTEM_DEBIAN}")
        case "${SYSTEM_JUDGMENT}" in
        "${SYSTEM_DEBIAN}")
            SOURCE_BRANCH="debian"
            ;;
        "${SYSTEM_UBUNTU}" | "${SYSTEM_ZORIN}")
            SOURCE_BRANCH="ubuntu"
            ;;
        "${SYSTEM_RHEL}")
            SOURCE_BRANCH="rhel"
            ;;
        *)
            # 部分 Debian 系衍生操作系统使用 Debian 12 的 docker ce 源
            SOURCE_BRANCH="debian"
            SYSTEM_VERSION_CODENAME="bookworm"
            ;;
        esac
        ;;
    "${SYSTEM_REDHAT}")
        case "${SYSTEM_JUDGMENT}" in
        "${SYSTEM_FEDORA}")
            SOURCE_BRANCH="fedora"
            ;;
        "${SYSTEM_RHEL}")
            SOURCE_BRANCH="rhel"
            ;;
        *)
            SOURCE_BRANCH="centos"
            ;;
        esac
        ;;
    "${SYSTEM_OPENCLOUDOS}" | "${SYSTEM_OPENEULER}")
        SOURCE_BRANCH="centos"
        ;;
    esac
    ## 定义软件源更新文字
    case "${SYSTEM_FACTIONS}" in
    "${SYSTEM_DEBIAN}")
        SYNC_MIRROR_TEXT="更新软件源"
        ;;
    "${SYSTEM_REDHAT}" | "${SYSTEM_OPENCLOUDOS}" | "${SYSTEM_OPENEULER}")
        SYNC_MIRROR_TEXT="生成软件源缓存"
        ;;
    esac
}

function choose_mirrors() {
    ## 打印软件源列表
    function print_mirrors_list() {
        local tmp_mirror_name tmp_mirror_url arr_num default_mirror_name_length tmp_mirror_name_length tmp_spaces_nums a i j
        ## 计算字符串长度
        function StringLength() {
            local text=$1
            echo "${#text}"
        }
        echo -e ''

        local list_arr=()
        local list_arr_sum="$(eval echo \${#$1[@]})"
        for ((a = 0; a < $list_arr_sum; a++)); do
            list_arr[$a]="$(eval echo \${$1[a]})"
        done
        if [ -x /usr/bin/printf ]; then
            for ((i = 0; i < ${#list_arr[@]}; i++)); do
                tmp_mirror_name=$(echo "${list_arr[i]}" | awk -F '@' '{print$1}') # 软件源名称
                # tmp_mirror_url=$(echo "${list_arr[i]}" | awk -F '@' '{print$2}') # 软件源地址
                arr_num=$((i + 1))
                default_mirror_name_length=${2:-"30"} # 默认软件源名称打印长度
                ## 补齐长度差异(中文的引号在等宽字体中占1格而非2格)
                [[ $(echo "${tmp_mirror_name}" | grep -c "“") -gt 0 ]] && let default_mirror_name_length+=$(echo "${tmp_mirror_name}" | grep -c "“")
                [[ $(echo "${tmp_mirror_name}" | grep -c "”") -gt 0 ]] && let default_mirror_name_length+=$(echo "${tmp_mirror_name}" | grep -c "”")
                [[ $(echo "${tmp_mirror_name}" | grep -c "‘") -gt 0 ]] && let default_mirror_name_length+=$(echo "${tmp_mirror_name}" | grep -c "‘")
                [[ $(echo "${tmp_mirror_name}" | grep -c "’") -gt 0 ]] && let default_mirror_name_length+=$(echo "${tmp_mirror_name}" | grep -c "’")
                # 非一般字符长度
                tmp_mirror_name_length=$(StringLength $(echo "${tmp_mirror_name}" | sed "s| ||g" | sed "s|[0-9a-zA-Z\.\=\:\_\(\)\'\"-\/\!·]||g;"))
                ## 填充空格
                tmp_spaces_nums=$(($(($default_mirror_name_length - ${tmp_mirror_name_length} - $(StringLength "${tmp_mirror_name}"))) / 2))
                for ((j = 1; j <= ${tmp_spaces_nums}; j++)); do
                    tmp_mirror_name="${tmp_mirror_name} "
                done
                printf " ❖  %-$(($default_mirror_name_length + ${tmp_mirror_name_length}))s %4s\n" "${tmp_mirror_name}" "$arr_num)"
            done
        else
            for ((i = 0; i < ${#list_arr[@]}; i++)); do
                tmp_mirror_name=$(echo "${list_arr[i]}" | awk -F '@' '{print$1}') # 软件源名称
                tmp_mirror_url=$(echo "${list_arr[i]}" | awk -F '@' '{print$2}')  # 软件源地址
                arr_num=$((i + 1))
                echo -e " ❖  $arr_num. ${tmp_mirror_url} | ${tmp_mirror_name}"
            done
        fi
    }

    function print_title() {
        local system_name="${SYSTEM_PRETTY_NAME:-"${SYSTEM_NAME} ${SYSTEM_VERSION_NUMBER}"}"
        local arch=""${DEVICE_ARCH}""
        local date="$(date "+%Y-%m-%d %H:%M:%S")"
        local timezone="$(timedatectl status 2>/dev/null | grep "Time zone" | awk -F ':' '{print$2}' | awk -F ' ' '{print$1}')"

        echo -e ''
        echo -e " 运行环境 ${BLUE}${system_name} ${arch}${PLAIN}"
        echo -e " 系统时间 ${BLUE}${date} ${timezone}${PLAIN}"
    }

    print_title
    if [[ -z "${INSTALL_LATESTED_DOCKER}" ]]; then
        ## 是否手动选择安装版本
        local CHOICE_A=$(echo -e "\n${BOLD}└─ 是否安装最新版本的 Docker Engine? [Y/n] ${PLAIN}")
        read -p "${CHOICE_A}" INPUT
        [[ -z "${INPUT}" ]] && INPUT=Y
        case $INPUT in
        [Yy] | [Yy][Ee][Ss])
            INSTALL_LATESTED_DOCKER="true"
            ;;
        [Nn] | [Nn][Oo])
            ## 安装旧版本只有官方仓库有
            INSTALL_LATESTED_DOCKER="false"
            SOURCE="download.docker.com"
            ;;
        *)
            INSTALL_LATESTED_DOCKER="true"
            echo -e "\n$WARN 输入错误,默认安装最新版本!"
            ;;
        esac
    fi

    local mirror_list_name
    if [[ -z "${SOURCE}" ]]; then
        local mirror_list_name="mirror_list_docker_ce"
        print_mirrors_list "${mirror_list_name}" 38
        local CHOICE_B=$(echo -e "\n${BOLD}└─ 请选择并输入你想使用的 Docker CE 源 [ 1-$(eval echo \${#$mirror_list_name[@]}) ]:${PLAIN}")
        while true; do
            read -p "${CHOICE_B}" INPUT
            case "${INPUT}" in
            [1-9] | [1-9][0-9] | [1-9][0-9][0-9])
                local tmp_source="$(eval echo \${${mirror_list_name}[$(($INPUT - 1))]})"
                if [[ -z "${tmp_source}" ]]; then
                    echo -e "\n$WARN 请输入有效的数字序号!"
                else
                    SOURCE="$(eval echo \${${mirror_list_name}[$(($INPUT - 1))]} | awk -F '@' '{print$2}')"
                    # echo "${SOURCE}"
                    # exit
                    break
                fi
                ;;
            *)
                echo -e "\n$WARN 请输入数字序号以选择你想使用的软件源!"
                ;;
            esac
        done
    fi

    if [[ -z "${SOURCE_REGISTRY}" ]]; then
        mirror_list_name="mirror_list_registry"
        print_mirrors_list "${mirror_list_name}" 44
        local CHOICE_C=$(echo -e "\n${BOLD}└─ 请选择并输入你想使用的 Docker Registry 源 [ 1-$(eval echo \${#$mirror_list_name[@]}) ]:${PLAIN}")
        while true; do
            read -p "${CHOICE_C}" INPUT
            case "${INPUT}" in
            [1-9] | [1-9][0-9] | [1-9][0-9][0-9])
                local tmp_source="$(eval echo \${${mirror_list_name}[$(($INPUT - 1))]})"
                if [[ -z "${tmp_source}" ]]; then
                    echo -e "\n$WARN 请输入有效的数字序号!"
                else
                    SOURCE_REGISTRY="$(eval echo \${${mirror_list_name}[$(($INPUT - 1))]} | awk -F '@' '{print$2}')"
                    # echo "${SOURCE_REGISTRY}"
                    # exit
                    break
                fi
                ;;
            *)
                echo -e "\n$WARN 请输入数字序号以选择你想使用的软件源!"
                ;;
            esac
        done
    fi
}

## 关闭防火墙和SELinux
function close_firewall_service() {
    if [ ! -x /usr/bin/systemctl ]; then
        return
    fi
    if [[ "$(systemctl is-active firewalld)" == "active" ]]; then
        if [[ -z "${CLOSE_FIREWALL}" ]]; then
            local CHOICE
            CHOICE=$(echo -e "\n${BOLD}└─ 是否关闭防火墙和 SELinux ? [Y/n] ${PLAIN}")
            read -rp "${CHOICE}" INPUT
            [[ -z "${INPUT}" ]] && INPUT=Y
            case "${INPUT}" in
            [Yy] | [Yy][Ee][Ss])
                CLOSE_FIREWALL="true"
                ;;
            [Nn] | [Nn][Oo]) ;;
            *)
                echo -e "\n$WARN 输入错误,默认不关闭!"
                ;;
            esac
        fi
        if [[ "${CLOSE_FIREWALL}" == "true" ]]; then
            local SelinuxConfig=/etc/selinux/config
            systemctl disable --now firewalld >/dev/null 2>&1
            [ -s $SelinuxConfig ] && sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" $SelinuxConfig && setenforce 0 >/dev/null 2>&1
        fi
    fi
}

## 安装环境包
function install_dependency_packages() {
    ## 删除原有源
    case "${SYSTEM_FACTIONS}" in
    "${SYSTEM_DEBIAN}")
        sed -i '/docker-ce/d' $File_DebianSourceList
        rm -rf $Dir_DebianExtendSource/docker.list
        ;;
    "${SYSTEM_REDHAT}" | "${SYSTEM_OPENCLOUDOS}" | "${SYSTEM_OPENEULER}")
        rm -rf $Dir_YumRepos/*docker*.repo
        ;;
    esac
    echo -e "\n$WORKING 开始${SYNC_MIRROR_TEXT}...\n"
    case "${SYSTEM_FACTIONS}" in
    "${SYSTEM_DEBIAN}")
        apt-get update
        ;;
    "${SYSTEM_REDHAT}" | "${SYSTEM_OPENCLOUDOS}" | "${SYSTEM_OPENEULER}")
        yum makecache
        ;;
    esac
    VERIFICATION_SOURCESYNC=$?
    if [ ${VERIFICATION_SOURCESYNC} -ne 0 ]; then
        output_error "${SYNC_MIRROR_TEXT}出错,请先确保软件包管理工具可用!"
    fi
    echo -e "\n$COMPLETE ${SYNC_MIRROR_TEXT}结束\n"
    case "${SYSTEM_FACTIONS}" in
    "${SYSTEM_DEBIAN}")
        apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common
        ;;
    "${SYSTEM_REDHAT}" | "${SYSTEM_OPENEULER}" | "${SYSTEM_OPENCLOUDOS}")
        # 注:红帽 8 版本才发布了 dnf 包管理工具,为了兼容性而优先选择安装 dnf-utils
        case ${SYSTEM_VERSION_NUMBER:0:1} in
        7)
            yum install -y yum-utils device-mapper-persistent-data lvm2
            ;;
        *)
            yum install -y dnf-utils device-mapper-persistent-data lvm2
            ;;
        esac
        ;;
    esac
}

## 卸载 Docker Engine 原有版本软件包
function uninstall_original_version() {
    # 先停止并禁用 Docker 服务
    systemctl disable --now docker >/dev/null 2>&1
    sleep 2s
    # 确定需要卸载的软件包
    local package_list
    case "${SYSTEM_FACTIONS}" in
    "${SYSTEM_DEBIAN}")
        case "${SYSTEM_JUDGMENT}" in
        "${SYSTEM_UBUNTU}" | "${SYSTEM_ZORIN}")
            package_list="docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc"
            ;;
        *)
            package_list="docker.io docker-doc docker-compose podman-docker containerd runc"
            ;;
        esac
        ;;
    "${SYSTEM_REDHAT}")
        case "${SYSTEM_JUDGMENT}" in
        "${SYSTEM_FEDORA}")
            package_list="docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine podman runc"
            ;;
        "${SYSTEM_RHEL}")
            package_list="docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine"
            ;;
        *)
            package_list="docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine"
            ;;
        esac
        ;;
    "${SYSTEM_OPENCLOUDOS}" | "${SYSTEM_OPENEULER}")
        package_list="docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine"
        ;;
    esac
    # 卸载软件包并清理残留
    case "${SYSTEM_FACTIONS}" in
    "${SYSTEM_DEBIAN}")
        apt-get remove -y $package_list
        apt-get autoremove -y >/dev/null 2>&1
        ;;
    "${SYSTEM_REDHAT}" | "${SYSTEM_OPENCLOUDOS}" | "${SYSTEM_OPENEULER}")
        yum remove -y $package_list
        yum autoremove -y >/dev/null 2>&1
        ;;
    esac
}

## 配置 Docker CE 源
function configure_docker_ce_mirror() {
    case "${SYSTEM_FACTIONS}" in
    "${SYSTEM_DEBIAN}")
        ## 处理 GPG 密钥
        local file_keyring="/etc/apt/keyrings/docker.asc"
        apt-key del 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 >/dev/null 2>&1 # 删除旧的密钥
        [ -f $file_keyring ] && rm -rf $file_keyring
        install -m 0755 -d /etc/apt/keyrings
        curl -fsSL https://${SOURCE}/linux/${SOURCE_BRANCH}/gpg -o $file_keyring >/dev/null
        if [ $? -ne 0 ]; then
            output_error "GPG 密钥下载失败,请检查网络或更换 Docker CE 软件源后重试!"
        fi
        chmod a+r $file_keyring
        ## 添加源
        echo "deb [arch=${SOURCE_ARCH} signed-by=${file_keyring}] https://${SOURCE}/linux/${SOURCE_BRANCH} ${SYSTEM_VERSION_CODENAME} stable" | tee $Dir_DebianExtendSource/docker.list >/dev/null 2>&1
        apt-get update
        ;;
    "${SYSTEM_REDHAT}" | "${SYSTEM_OPENCLOUDOS}" | "${SYSTEM_OPENEULER}")
        yum-config-manager -y --add-repo https://${SOURCE}/linux/${SOURCE_BRANCH}/docker-ce.repo
        sed -i "s|download.docker.com|${SOURCE}|g" $Dir_YumRepos/docker-ce.repo
        ## 兼容处理版本号
        if [[ "${SYSTEM_JUDGMENT}" != "${SYSTEM_FEDORA}" ]]; then
            local target_version
            case ${SYSTEM_VERSION_NUMBER:0:1} in
            7 | 8 | 9)
                target_version="${SYSTEM_VERSION_NUMBER:0:1}"
                ;;
            *)
                target_version="9" # 使用较新的版本
                ;;
            esac
            sed -i "s|\$releasever|${target_version}|g" $Dir_YumRepos/docker-ce.repo
            yum makecache
        fi
        ;;
    esac
}

## 安装 Docker Engine
function install_docker_engine() {
    ## 导出可安装的版本列表
    function export_version_list() {
        case "${SYSTEM_FACTIONS}" in
        "${SYSTEM_DEBIAN}")
            apt-cache madison docker-ce | awk '{print $3}' | grep -Eo "[0-9][0-9].[0-9]{1,2}.[0-9]{1,2}" >$DockerCEVersionFile
            apt-cache madison docker-ce-cli | awk '{print $3}' | grep -Eo "[0-9][0-9].[0-9]{1,2}.[0-9]{1,2}" >$DockerCECLIVersionFile
            grep -wf $DockerCEVersionFile $DockerCECLIVersionFile >$DockerVersionFile
            ;;
        "${SYSTEM_REDHAT}" | "${SYSTEM_OPENCLOUDOS}" | "${SYSTEM_OPENEULER}")
            yum list docker-ce --showduplicates | sort -r | awk '{print $2}' | grep -Eo "[0-9][0-9].[0-9]{1,2}.[0-9]{1,2}" >$DockerCEVersionFile
            yum list docker-ce-cli --showduplicates | sort -r | awk '{print $2}' | grep -Eo "[0-9][0-9].[0-9]{1,2}.[0-9]{1,2}" >$DockerCECLIVersionFile
            grep -wf $DockerCEVersionFile $DockerCECLIVersionFile >$DockerVersionFile
            ;;
        esac
        rm -rf $DockerCEVersionFile $DockerCECLIVersionFile
    }

    ## 安装
    function install_main() {
        if [[ "${INSTALL_LATESTED_DOCKER}" == "true" ]]; then
            case "${SYSTEM_FACTIONS}" in
            "${SYSTEM_DEBIAN}")
                apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
                ;;
            "${SYSTEM_REDHAT}" | "${SYSTEM_OPENCLOUDOS}" | "${SYSTEM_OPENEULER}")
                yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
                ;;
            esac
        else
            export_version_list
            echo -e "\n${GREEN} --------- 请选择你要安装的版本,如:27.1.0 ---------- ${PLAIN}\n"
            cat $DockerVersionFile
            echo -e '\n注:以上可供选择的安装版本由官方源提供,此列表以外的版本则无法安装在当前操作系统上'
            while true; do
                local CHOICE=$(echo -e "\n${BOLD}└─ 请根据上面的列表,选择并输入你想要安装的具体版本号:${PLAIN}\n")
                read -p "${CHOICE}" DOCKER_VERSION
                echo ''
                cat $DockerVersionFile | grep -Eqw "${DOCKER_VERSION}"
                if [ $? -eq 0 ]; then
                    echo "${DOCKER_VERSION}" | grep -Eqw '[0-9][0-9].[0-9]{1,2}.[0-9]{1,2}'
                    if [ $? -eq 0 ]; then
                        rm -rf $DockerVersionFile
                        break
                    else
                        echo -e "$ERROR 请输入正确的版本号!"
                    fi
                else
                    echo -e "$ERROR 输入错误请重新输入!"
                fi
            done
            case "${SYSTEM_FACTIONS}" in
            "${SYSTEM_DEBIAN}")
                check_version="$(echo ${DOCKER_VERSION} | cut -c1-2)"
                CheckSubversion="$(echo ${DOCKER_VERSION} | cut -c4-5)"
                case ${check_version} in
                18)
                    if [ ${CheckSubversion} == "09" ]; then
                        INSTALL_JUDGMENT="5:"
                    else
                        INSTALL_JUDGMENT=""
                    fi
                    ;;
                *)
                    INSTALL_JUDGMENT="5:"
                    ;;
                esac
                apt-get install -y docker-ce=${INSTALL_JUDGMENT}${DOCKER_VERSION}* docker-ce-cli=5:${DOCKER_VERSION}* containerd.io docker-buildx-plugin docker-compose-plugin
                ;;
            "${SYSTEM_REDHAT}" | "${SYSTEM_OPENCLOUDOS}" | "${SYSTEM_OPENEULER}")
                yum install -y docker-ce-${DOCKER_VERSION} docker-ce-cli-${DOCKER_VERSION} containerd.io docker-buildx-plugin docker-compose-plugin
                ;;
            esac
        fi
    }

    ## 修改 Docker Registry 镜像仓库源
    function change_docker_registry_mirror() {
        if [[ "${REGISTRY_SOURCEL}" != "registry.hub.docker.com" ]]; then
            if [ -d $DockerDir ] && [ -e $DockerConfig ]; then
                if [ -e $DockerConfigBackup ]; then
                    if [[ "${IGNORE_BACKUP_TIPS}" == "false" ]]; then
                        local CHOICE_BACKUP=$(echo -e "\n${BOLD}└─ 检测到已备份的 Docker 配置文件,是否跳过覆盖备份? [Y/n] ${PLAIN}")
                        read -p "${CHOICE_BACKUP}" INPUT
                        [[ -z "${INPUT}" ]] && INPUT=Y
                        case $INPUT in
                        [Yy] | [Yy][Ee][Ss]) ;;
                        [Nn] | [Nn][Oo])
                            echo ''
                            cp -rvf $DockerConfig $DockerConfigBackup 2>&1
                            ;;
                        *)
                            echo -e "\n$WARN 输入错误,默认不覆盖!"
                            ;;
                        esac
                    fi
                else
                    echo ''
                    cp -rvf $DockerConfig $DockerConfigBackup 2>&1
                    echo -e "\n$COMPLETE 已备份原有 Docker 配置文件至 $DockerConfigBackup"
                fi
                sleep 2s
            else
                mkdir -p $DockerDir >/dev/null 2>&1
                touch $DockerConfig
            fi
            echo -e '{\n  "registry-mirrors": ["https://SOURCE"]\n}' >$DockerConfig
            sed -i "s|SOURCE|${SOURCE_REGISTRY}|g" $DockerConfig
            systemctl daemon-reload
        fi
    }

    ## 判定是否已安装
    case "${SYSTEM_FACTIONS}" in
    "${SYSTEM_DEBIAN}")
        dpkg -l | grep docker-ce-cli -q
        ;;
    "${SYSTEM_REDHAT}" | "${SYSTEM_OPENCLOUDOS}" | "${SYSTEM_OPENEULER}")
        rpm -qa | grep docker-ce-cli -q
        ;;
    esac
    if [ $? -eq 0 ]; then
        export_version_list
        DOCKER_INSTALLED_VERSION="$(docker -v | grep -Eo "[0-9][0-9]\.[0-9]{1,2}\.[0-9]{1,2}")"
        DOCKER_VERSION_LATEST="$(cat $DockerVersionFile | head -n 1)"
        if [[ "${DOCKER_INSTALLED_VERSION}" == "${DOCKER_VERSION_LATEST}" ]]; then
            if [[ "${INSTALL_LATESTED_DOCKER}" == "true" ]]; then
                echo -e "\n$COMPLETE 检测到已安装 Docker Engine 最新版本,跳过安装"
                rm -rf $DockerVersionFile
                change_docker_registry_mirror
                if [[ $(systemctl is-active docker) == "active" ]]; then
                    systemctl restart docker
                fi
                systemctl enable --now docker >/dev/null 2>&1
                check_version
                run_end
                exit
            else
                local CHOICE=$(echo -e "\n${BOLD}└─ 检测到已安装 Docker Engine 最新版本,是否继续安装其它版本? [Y/n] ${PLAIN}")
            fi
        else
            if [[ "${INSTALL_LATESTED_DOCKER}" == "true" ]]; then
                local CHOICE=$(echo -e "\n${BOLD}└─ 检测到已安装 Docker Engine 旧版本,是否覆盖安装为最新版本? [Y/n] ${PLAIN}")
            else
                local CHOICE=$(echo -e "\n${BOLD}└─ 检测到已安装 Docker Engine 旧版本,是否继续安装其它版本? [Y/n] ${PLAIN}")
            fi
        fi
        read -p "${CHOICE}" INPUT
        [[ -z "${INPUT}" ]] && INPUT=Y
        case $INPUT in
        [Yy] | [Yy][Ee][Ss])
            echo -en "\n$WORKING 正在卸载之前的版本...\n"
            uninstall_original_version
            echo -e "\n$COMPLETE 卸载完毕\n"
            install_main
            ;;
        [Nn] | [Nn][Oo]) ;;
        *)
            echo -e "\n$WARN 输入错误,默认不覆盖安装!\n"
            ;;
        esac
        rm -rf $DockerVersionFile
    else
        uninstall_original_version
        install_main
    fi
    change_docker_registry_mirror
    systemctl stop docker >/dev/null 2>&1
    systemctl enable --now docker >/dev/null 2>&1
}

## 查看版本并验证安装结果
function check_version() {
    if [ -x /usr/bin/docker ]; then
        echo -en "\n当前安装版本:"
        docker -v
        VERIFICATION_DOCKER=$?
        if [ ${VERIFICATION_DOCKER} -eq 0 ]; then
            echo -e "\n$COMPLETE 安装完成"
        else
            echo -e "\n$ERROR 安装失败"
            case "${SYSTEM_FACTIONS}" in
            "${SYSTEM_DEBIAN}")
                echo -e "\n检查源文件:cat $Dir_DebianExtendSource/docker.list"
                echo -e '请尝试手动执行安装命令: apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin\n'
                echo ''
                ;;
            "${SYSTEM_REDHAT}" | "${SYSTEM_OPENCLOUDOS}" | "${SYSTEM_OPENEULER}")
                echo -e "\n检查源文件:cat $Dir_YumRepos/docker.repo"
                echo -e '请尝试手动执行安装命令: yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin\n'
                ;;
            esac
            exit 1
        fi
        if [[ $(systemctl is-active docker) != "active" ]]; then
            sleep 2
            systemctl disable --now docker >/dev/null 2>&1
            sleep 2
            systemctl enable --now docker >/dev/null 2>&1
            sleep 2
            if [[ $(systemctl is-active docker) != "active" ]]; then
                echo -e "\n$ERROR 检测到 Docker 服务启动异常,可能由于重复安装导致"
                echo -e "\n${YELLOW} 请执行 "systemctl start docker" 或 "service docker start" 命令尝试启动,如若报错请尝试重新执行本脚本${PLAIN}"
            fi
        fi
    else
        echo -e "\n$ERROR 安装失败\n"
    fi
}

handle_command_options "$@"
main

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2215814.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WebGl 如何给页面绑定点击事件

在WebGL中给页面绑定点击事件&#xff0c;可以通过为WebGL的绘图上下文所在的<canvas>元素添加事件监听器来实现点击事件的处理。 1. 画布添加点击事件 const ctx document.getElementById(canvas) const gl ctx.getContext(webgl)ctx.onclick function (e) {// 给ca…

深入理解WPF中的命令机制

Windows Presentation Foundation&#xff08;WPF&#xff09;是微软推出的一种用于构建桌面客户端应用程序的技术。它被认为是现代Windows应用程序的基础&#xff0c;具有强大的图形和媒体处理能力。在WPF中&#xff0c;“命令”是一个重要的概念&#xff0c;它为应用程序开发…

Ubuntu下编译opencv4.5遇到的问题及解决方法

一、编译opencv4.5的步骤 1、安装依赖项 sudo apt update sudo apt install build-essential cmake git pkg-config \ libjpeg-dev libtiff-dev libpng-dev \ libavcodec-dev libavformat-dev libswscale-dev \ libv4l-dev libxvidcore-dev libx264-dev \ libgtk-3-dev libat…

使用Arcgis批量自动出图

操作方法如下&#xff1a; 1 2 3 4 5 6 7 设置好选项&#xff0c;开始打印。 8 生成pdf。 第一步&#xff1a;shp放到数据库中&#xff0c;标注转注记&#xff0c;然后编辑注记&#xff0c;符号样式设置好。准备出图&#xff1a;&#xff08;转注记时候尽量压盖监测等选最…

使用Windows创建一个MFC应用【带界面】

MFC使用教程【对初学者保姆型友好&#xff01;】 目录 前提条件 1&#xff1a;创建MFC应用程序 2. 项目结构解读 引用 外部依赖项 头文件 源文件 资源文件 文件功能详解 项目的主要流程 步骤2&#xff1a;配置OpenCV 安装OpenCV 包含目录与库文件 步骤3&#xff1…

啤酒酿造中的温度与时间魔法:精酿啤酒的匠心之旅

在精酿啤酒的世界里&#xff0c;温度与时间仿佛两位默契的舞者&#xff0c;在酿造过程中演绎着一段段美妙的舞蹈。而Fendi Club精酿啤酒&#xff0c;正是这段舞蹈的品牌&#xff0c;将温度与时间的魔法发挥到了致点。 一、温度的魔法&#xff1a;酿造中的温暖与冷静 在啤酒酿…

【原创教程】电气电工25:如何选择接近传感器

我们今天来看看经常遇到的接近传感器,在电气电工工作中,这种传感器随处可见,所以我们要对它有一个深度的认知。 一、接近传感器的工作原理 1、通过高频发震器Coil而发出高频磁场 2、被测对象(金属)接近时表面会产生涡电流(Eddy Current),涡电流又会引发磁场 3、…

OceanBase中扩容OCP节点step by step

许多用户在开始使用OceanBase时部署OCP&#xff0c;通常选择单节点部署。但随着后续业务规模的不断扩大&#xff0c;会开始担忧单节点OCP在面对故障时可能丧失对集群运维管控的连续性。鉴于此&#xff0c;会将现有的单节点OCP扩展至多节点部署&#xff0c;以此来确保OCP服务的高…

【HarmonyOS】HMRouter使用详解(四)路由拦截

路由拦截器 可以对指定或全局路由跳转时添加拦截器&#xff0c;作用是可以实现在页面切换前做判断是否有进入当前页面的权限。这篇文章将实现登录的全局路由拦截样式。 新建拦截器类 通过继承IHMInterceptor接口实现生命周期接口的方法重写。 通过添加HMInterceptor装饰器&…

使用Docker部署nextjs应用

最近使用nextjs网站开发&#xff0c;希望使用docker进行生产环境的部署&#xff0c;减少环境的依赖可重复部署操作。我采用的是Dockerfile编写应用镜像方式 docker-compose实现容器部署的功能。 Docker Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器…

大数据-172 Elasticsearch 索引操作 与 IK 分词器 自定义停用词 Nginx 服务

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

CMake学习笔记(四)cmake --build使用踩坑记录

根据 深入理解 CMake 的 cmake --build 命令_cmake build-CSDN博客等消息来源的说法&#xff0c; cmake --build <dir> 将在目录<dir>中产生结果文件。但是实测发现&#xff0c;这里有坑&#xff1a;如果目录<dir>中没有CMakeCache.txt等文件的话&#xff…

门店收银系统源码-php+flutter+uniapp

1. 系统开发语言 核心开发语言: PHP、HTML5、Dart 后台接口: PHP7.3 后台管理网站: HTML5vue2.0element-uicssjs 线下收银台&#xff08;安卓/PC收银、安卓自助收银&#xff09;: Dart3 框架&#xff1a;Flutter 3.19.6 移动店务助手: uniapp 线上商城: uniapp 2.线下收…

每天花2分钟学数字化转型,第二讲:数字化

每天花2分钟学习数字化转型&#xff0c;第二讲&#xff1a;什么是数字化转型&#xff1f; 数字化转型的定义 Gartner对数字化(digitalization)的定义&#xff1a;数字化就是利用数字技术来改变商业模式并提供新的收入和价值创造机会&#xff1b;是转向数字业务的过程。 从这个…

叉车安全防撞装置的作用

‌叉车安全防撞装置的核心作用在于提升叉车运行时的安全性&#xff0c;特别是在倒车或经过岔路口等驾驶员视线可能受阻的情境下&#xff0c;通过探测叉车周围的障碍物距离&#xff0c;实时为驾驶员提供必要的辅助信息&#xff0c;有效预防碰撞事故的发生。‌ 这些装置通过多种技…

【多模态】ViT模型技术学习

前言 最近多模态模型特别火&#xff0c;模型也越来越小&#xff0c;性能优异的MiniCPM-2.6只有8B大小&#xff0c;它采用的图片编码器是SigLipViT模型&#xff0c;一起从头学习ViT和Transformer&#xff01;本文记录一下学习过程&#xff0c;所以是自上而下的写&#xff0c;从…

windows上svn设置忽略

目的 就是在windows环境下设置svn的需要忽略的文件&#xff0c;这还是挺实用的一个功能&#xff0c;不然&#xff0c;很多编译的中间文件都上传到svn上了&#xff0c;这样就不好了&#xff1b;ignore设置&#xff0c;也需要注意一下。 过程 svn服务端式忽略&#xff0c;这是…

【前端】制作一个简单的网页(2)

单标签组成的元素 这类标签不需要内容产生效果&#xff0c;通常表示对网页的某种行为&#xff0c;它们不用标记任何内容&#xff0c;开始即是结束。 比如&#xff0c;<hr>标签的作用是在网页中添加一条分割线&#xff0c;它仅包含开始标签&#xff0c;是一个单标签元素。…

【Linux】解读信号的本质&相关函数及指令的介绍

前言 大家好吖&#xff0c;欢迎来到 YY 滴Linux系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《Lin…

k8s的部署和安装

k8s的部署和安装 一、Kubernets简介及部署方法 1.1 应用部署方式演变 在部署应用程序的方式上&#xff0c;主要经历了三个阶段&#xff1a; 传统部署&#xff1a;互联网早期&#xff0c;会直接将应用程序部署在物理机上 优点&#xff1a;简单&#xff0c;不需要其它技术的参…