Debian 系统初始化与环境配置指南
本笔记旨在记录 Debian 系统初始化配置的详细步骤,包括系统更新、网络设置、SSH 服务配置、Oh-My-Zsh 安装与插件配置,以及 Vim 编辑器基础配置。
0. 更换 APT 镜像源
为了提高软件包下载速度和稳定性,建议将 Debian 系统的 APT 镜像源更换为国内的常用镜像站。本节提供一个自动化脚本,帮助你轻松完成此操作。
0.1 更换源脚本
将以下内容保存为 change_debian_sources.sh
文件,并赋予执行权限后运行。
#!/bin/bash
# --- 字体颜色定义 ---
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# --- 函数定义 ---
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 [[ $EUID -ne 0 ]]; then
log_error "此脚本必须以 root 用户身份运行。"
log_error "请使用 'sudo ./change_debian_sources.sh' 运行,或直接切换到 root 用户再执行。"
exit 1
fi
}
# 获取 Debian 发行版代号
get_debian_codename() {
if [ -f "/etc/os-release" ]; then
. /etc/os-release
echo "$VERSION_CODENAME"
elif [ -f "/etc/debian_version" ]; then
# fallback for older systems or minimal installs
# Try to guess based on version if codename not found in os-release
DEB_VER=$(cat /etc/debian_version | cut -d'.' -f1)
case "$DEB_VER" in
12) echo "bookworm";;
13) echo "bullseye";;
14) echo "buster";;
15) echo "stretch";;
*) echo "";; # Unknown or no codename
esac
fi
}
# 镜像源内容模板函数
get_source_content() {
local mirror_base_url=$1
local codename=$2
local template=""
# 核心源
template+="deb $mirror_base_url/debian/ $codename main contrib non-free non-free-firmware\n"
template+="deb-src $mirror_base_url/debian/ $codename main contrib non-free non-free-firmware\n\n"
# 更新源
template+="deb $mirror_base_url/debian/ $codename-updates main contrib non-free non-free-firmware\n"
template+="deb-src $mirror_base_url/debian/ $codename-updates main contrib non-free non-free-firmware\n\n"
# 安全更新源
if [[ "$mirror_base_url" == "http://deb.debian.org" ]]; then
# 官方源的security地址不同
template+="deb $mirror_base_url/debian-security/ $codename-security main contrib non-free non-free-firmware\n"
template+="deb-src $mirror_base_url/debian-security/ $codename-security main contrib non-free non-free-firmware\n"
else
# 国内镜像站的security地址通常这样
template+="deb $mirror_base_url/debian-security/ $codename-security main contrib non-free non-free-firmware\n"
template+="deb-src $mirror_base_url/debian-security/ $codename-security main contrib non-free non-free-firmware\n"
fi
# backports 源(可选,默认注释)
template+="\n# backports源 (提供较新版本的软件,可能不稳定)\n"
template+="# deb $mirror_base_url/debian/ $codename-backports main contrib non-free non-free-firmware\n"
template+="# deb-src $mirror_base_url/debian/ $codename-backports main contrib non-free non-free-firmware\n"
echo -e "$template"
}
# --- 主脚本逻辑 ---
check_root # 确保脚本以 root 权限运行
SOURCES_LIST="/etc/apt/sources.list"
BACKUP_FILE="${SOURCES_LIST}.bak.$(date +%Y%m%d%H%M%S)"
log_info "正在检测 Debian 发行版代号..."
DEBIAN_CODENAME=$(get_debian_codename)
if [ -z "$DEBIAN_CODENAME" ]; then
log_error "未能检测到 Debian 发行版代号。请手动确认或更新您的系统。"
log_error "脚本可能无法为您生成正确的 sources.list 内容。"
log_error "请确保您运行的是 Debian 系统,或者手动修改脚本中的 DEBIAN_CODENAME 变量。"
exit 1
else
log_info "检测到 Debian 发行版代号为: ${DEBIAN_CODENAME}"
fi
log_info "正在备份原始的 ${SOURCES_LIST} 文件到 ${BACKUP_FILE}..."
if cp "$SOURCES_LIST" "$BACKUP_FILE"; then
log_info "备份成功。"
else
log_error "备份失败!请检查权限或磁盘空间。退出。"
exit 1
fi
echo ""
log_info "请选择您希望使用的 Debian APT 镜像源:"
echo "1) 阿里云镜像站 (https://mirrors.aliyun.com)"
echo "2) 清华大学镜像站 (https://mirrors.tuna.tsinghua.edu.cn)"
echo "3) 中国科学技术大学 (USTC) 镜像站 (https://mirrors.ustc.edu.cn)"
echo "4) 官方 Debian 镜像站 (deb.debian.org)"
echo "5) 退出脚本"
echo ""
read -p "请输入您的选择 (1-5): " CHOICE
MIRROR_URL=""
case "$CHOICE" in
1) MIRROR_URL="https://mirrors.aliyun.com";;
2) MIRROR_URL="https://mirrors.tuna.tsinghua.edu.cn";;
3) MIRROR_URL="https://mirrors.ustc.edu.cn";;
4) MIRROR_URL="http://deb.debian.org";; # 官方源使用 http 是惯例,因为 GPG 签名确保安全
5) log_info "脚本已退出。"; exit 0;;
*) log_error "无效的选择,请重新运行脚本并输入 1-5 之间的数字。"; exit 1;;
esac
log_info "您选择了 $MIRROR_URL 作为镜像源。"
log_info "正在生成新的 sources.list 内容..."
NEW_SOURCES_CONTENT=$(get_source_content "$MIRROR_URL" "$DEBIAN_CODENAME")
log_info "正在写入新内容到 ${SOURCES_LIST}..."
echo "$NEW_SOURCES_CONTENT" | tee "$SOURCES_LIST" > /dev/null
if [ $? -eq 0 ]; then
log_info "成功更新 ${SOURCES_LIST}。"
else
log_error "写入 ${SOURCES_LIST} 失败!退出。"
exit 1
fi
log_info "正在执行 'apt update' 更新软件包列表..."
if apt update; then
log_info "'apt update' 成功完成。"
log_warn "建议您现在运行 'apt upgrade -y' 来升级您的系统。"
else
log_error "'apt update' 失败!请检查您的网络连接或新的源配置。"
log_error "如果出现 GPG 错误,您可能需要手动导入缺失的密钥。"
fi
log_info "脚本执行完毕。感谢使用!"
0.2 如何使用脚本
- 保存脚本: 将上述代码复制并保存到一个文件,例如
change_debian_sources.sh
。 - 添加执行权限: 在终端中运行
chmod +x change_debian_sources.sh
。 - 运行脚本: 使用
sudo
权限运行脚本:sudo ./change_debian_sources.sh
。 - 选择镜像源: 脚本会提示你选择一个镜像源,输入对应的数字即可。
- 更新系统: 脚本会自动执行
apt update
。建议在脚本完成后手动运行sudo apt upgrade -y
来升级所有软件包。
1. 基础系统初始化自动化脚本
本节提供一个综合性脚本,用于自动化执行 Debian 系统的基础初始化步骤,包括:
- 更新系统软件包并安装常用工具(如 Vim, OpenSSH)。
- 配置静态 IP 地址、子网掩码、网关和 DNS 服务器。
- 修改 SSH 配置以允许 root 登录和密码认证(注意:此操作会降低安全性,仅建议在受控环境中或临时使用)。
1.1 基础初始化脚本
将以下内容保存为 debian_initial_setup.sh
文件,并赋予执行权限后运行。
#!/bin/bash
# --- 字体颜色定义 ---
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# --- 函数定义 ---
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 [[ $EUID -ne 0 ]]; then
log_error "此脚本必须以 root 用户身份运行。"
log_error "请使用 'sudo ./debian_initial_setup.sh' 运行,或直接切换到 root 用户再执行。"
exit 1
fi
}
# 备份文件函数
backup_file() {
local file_path=$1
local backup_path="${file_path}.bak.$(date +%Y%m%d%H%M%S)"
if [ -f "$file_path" ]; then
log_info "正在备份 ${file_path} 到 ${backup_path}..."
if cp "$file_path" "$backup_path"; then
log_info "备份成功。"
else
log_error "备份 ${file_path} 失败!请检查权限或磁盘空间。退出。"
exit 1
fi
else
log_warn "${file_path} 文件不存在,跳过备份。"
fi
}
# --- 主脚本逻辑 ---
check_root # 确保脚本以 root 权限运行
log_info "========================================="
log_info " Debian 服务器初始化及网络配置脚本 "
log_info "========================================="
log_warn "此脚本将修改网络配置和 SSH 配置,可能导致远程连接中断。"
log_warn "请确保有物理访问权限或虚拟机快照以防万一。"
read -p "您确定要继续吗?(y/N): " CONFIRM
if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then
log_info "用户取消,脚本退出。"
exit 0
fi
# --- 1. 前期准备 ---
log_info "--- 1. 前期准备:更新系统及安装必要工具 ---"
log_info "正在更新软件包列表..."
if ! apt update; then
log_error "apt update 失败!请检查网络连接。退出。"
exit 1
fi
log_info "正在升级所有已安装的软件包..."
# 使用 apt upgrade -y --allow-downgrades --allow-remove-essential --allow-change-held-packages 确保升级不被中断
if ! apt upgrade -y; then
log_warn "apt upgrade 过程中可能出现警告或错误,但通常不致命。请查看日志。"
fi
log_info "正在安装 Vim 编辑器..."
if ! apt install vim -y; then
log_error "安装 Vim 失败!退出。"
exit 1
fi
log_info "正在安装 OpenSSH 服务器..."
if ! apt install openssh-server -y; then
log_error "安装 OpenSSH 服务器失败!退出。"
exit 1
fi
log_info "检查 SSH 服务状态..."
systemctl status ssh | grep -q "active (running)"
if [ $? -eq 0 ]; then
log_info "SSH 服务正在运行。"
else
log_error "SSH 服务未运行。请手动检查并启动。"
log_info "尝试启动 SSH 服务..."
if systemctl start ssh; then
log_info "SSH 服务已启动。"
else
log_error "启动 SSH 服务失败!请检查系统日志。"
exit 1
fi
fi
log_info "前期准备完成。"
# --- 2. 修改 IP 地址及网关 ---
log_info "--- 2. 修改 IP 地址及网关 ---"
# 尝试自动检测网卡接口名称
AUTO_DETECTED_INTERFACE=$(ip -o link show | awk -F': ' '{print $2}' | grep -E "^e|^eth|^enp" | grep -v "lo" | head -n 1)
read -p "请输入您的网卡接口名称 (例如: ens32, eth0, enp0s3) [默认: ${AUTO_DETECTED_INTERFACE}]: " NETWORK_INTERFACE
NETWORK_INTERFACE=${NETWORK_INTERFACE:-${AUTO_DETECTED_INTERFACE}}
if [ -z "$NETWORK_INTERFACE" ]; then
log_error "未检测到或未输入网卡接口名称。退出。"
exit 1
fi
log_info "将为网卡接口 ${NETWORK_INTERFACE} 配置静态 IP。"
read -p "请输入静态 IP 地址 (例如: 192.168.50.13): " STATIC_IP
read -p "请输入子网掩码 (例如: 255.255.255.0): " NETMASK
read -p "请输入网关地址 (例如: 192.168.50.1): " GATEWAY
read -p "请输入首选 DNS 服务器地址 (例如: 192.168.50.4 或 8.8.8.8): " NAMESERVER1
read -p "请输入备用 DNS 服务器地址 (可选,留空则不设置): " NAMESERVER2
# 备份 /etc/network/interfaces
backup_file "/etc/network/interfaces"
log_info "正在配置 /etc/network/interfaces..."
# 清空并写入新的网络配置
cat << EOF > /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface - configured by script
allow-hotplug ${NETWORK_INTERFACE}
iface ${NETWORK_INTERFACE} inet static
address ${STATIC_IP}
netmask ${NETMASK}
gateway ${GATEWAY}
EOF
log_info "已更新 /etc/network/interfaces。"
# 备份 /etc/resolv.conf
backup_file "/etc/resolv.conf"
log_info "正在配置 /etc/resolv.conf (DNS 服务器)..."
# 清空并写入新的 DNS 配置
echo "nameserver ${NAMESERVER1}" > /etc/resolv.conf
if [ -n "$NAMESERVER2" ]; then
echo "nameserver ${NAMESERVER2}" >> /etc/resolv.conf
fi
log_info "已更新 /etc/resolv.conf。"
log_info "正在重启网络服务 (此操作可能导致连接中断)..."
if systemctl restart networking; then
log_info "网络服务重启成功。请检查您的网络连接是否正常。"
else
log_error "网络服务重启失败!请检查 /etc/network/interfaces 配置。"
log_error "您可能需要手动修复网络,否则可能无法连接到服务器。"
exit 1
fi
log_info "IP 地址及网关配置完成。"
# --- 3. 修改 SSH 配置以允许远程连接 ---
log_info "--- 3. 修改 SSH 配置以允许远程连接 ---"
log_warn "此操作将降低 SSH 安全性,允许 root 登录和密码认证!"
log_warn "在生产环境中,强烈建议使用密钥认证并禁用这些选项。"
SSH_CONFIG="/etc/ssh/sshd_config"
backup_file "$SSH_CONFIG"
log_info "正在修改 ${SSH_CONFIG}..."
# 使用 sed 确保这些行存在并被正确设置
sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin yes/' "$SSH_CONFIG"
# 如果 PermitRootLogin 不存在,则添加
grep -qxF 'PermitRootLogin yes' "$SSH_CONFIG" || echo 'PermitRootLogin yes' >> "$SSH_CONFIG"
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/' "$SSH_CONFIG"
# 如果 PasswordAuthentication 不存在,则添加
grep -qxF 'PasswordAuthentication yes' "$SSH_CONFIG" || echo 'PasswordAuthentication yes' >> "$SSH_CONFIG"
log_info "已更新 SSH 配置。"
log_info "正在重启 SSH 服务..."
if systemctl restart ssh; then
log_info "SSH 服务重启成功。root 用户和密码认证现已启用。"
else
log_error "SSH 服务重启失败!请检查 /etc/ssh/sshd_config 或系统日志。"
exit 1
fi
log_info "SSH 配置修改完成。"
log_info "========================================="
log_info " Debian 服务器初始化脚本执行完毕! "
log_info "========================================="
log_info "请立即测试您的网络连接和 SSH 登录。"
1.2 如何使用脚本
- 保存脚本: 将上述代码复制并保存到一个文件,例如
debian_initial_setup.sh
。 - 添加执行权限: 在终端中运行
chmod +x debian_initial_setup.sh
。 - 运行脚本: 使用
sudo
权限运行脚本:sudo ./debian_initial_setup.sh
。 - 交互式输入: 脚本会提示你输入网络配置信息,请根据实际情况填写。
- 验证: 脚本执行完毕后,请务必测试网络连接和 SSH 登录是否正常。
1.3 脚本功能详解
- 安全提示与确认: 脚本开始时会发出警告,提示用户此操作可能导致连接中断,并要求用户确认。
- 日志与权限检查: 沿用统一的
log_info
,log_warn
,log_error
函数和check_root
函数。 - 文件备份: 在修改
/etc/network/interfaces
和/etc/ssh/sshd_config
之前,脚本会自动创建备份文件。 - 前期准备:
- 执行
apt update
和apt upgrade -y
。 - 安装
vim
和openssh-server
。 - 检查 SSH 服务状态,如果未运行则尝试启动。
- 执行
- 网络配置:
- 尝试自动检测网卡接口名称,并允许用户手动输入或确认。
- 交互式地获取静态 IP、子网掩码、网关和 DNS 服务器地址。
- 生成并写入新的
/etc/network/interfaces
和/etc/resolv.conf
配置。 - 重启
networking
服务以应用更改。
- SSH 配置:
- 修改
/etc/ssh/sshd_config
,设置PermitRootLogin yes
和PasswordAuthentication yes
。 - 重启
ssh
服务以使配置生效。
- 修改
- 完成提示: 脚本结束时会给出完成提示,并建议用户测试连接。
2. 配置 Oh-My-Zsh
Oh-My-Zsh 是一个流行的 Zsh 配置框架,提供了丰富的插件和主题,可以极大地提升命令行体验。
2.1 安装 Oh-My-Zsh
-
**安装 Zsh、Git 和 Curl:**这些是安装 Oh-My-Zsh 所需的依赖。
sudo apt install zsh git curl -y
-
**设置 Zsh 为默认终端:**执行此命令后,下次登录时将自动使用 Zsh。
chsh -s /bin/zsh
-
**安装 Oh-My-Zsh:**选择以下任一方式进行安装。
-
使用 Curl 安装:
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
-
使用 Wget 安装:
sh -c "$(wget https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)"
-
2.2 安装常用插件
安装 zsh-autosuggestions
(命令自动补全)和 zsh-syntax-highlighting
(语法高亮)插件。
# 克隆 zsh-autosuggestions 插件
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
# 克隆 zsh-syntax-highlighting 插件
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
2.3 配置 .zshrc
编辑你的 Zsh 配置文件 ~/.zshrc
,启用插件和设置主题。
-
编辑
.zshrc
文件:vim ~/.zshrc
-
**修改或添加以下内容:**找到
ZSH_THEME
和plugins
行,进行修改。export ZSH="$HOME/.oh-my-zsh" # Oh-My-Zsh 的安装路径,通常无需修改 ZSH_THEME="bira" # 设置主题,你可以尝试其他主题,如 "agnoster" plugins=( git zsh-autosuggestions zsh-syntax-highlighting ) source $ZSH/oh-my-zsh.sh # 确保这一行在文件末尾,用于加载 Oh-My-Zsh
-
使
.zshrc
配置生效:
在终端中执行以下命令,或重新打开终端。source ~/.zshrc
3. 配置 Vim
为 Vim 编辑器添加一些基础配置,提升使用体验。
-
**创建或编辑 Vim 配置文件:**打开
~/.vimrc
文件。vim ~/.vimrc
-
添加以下内容:
这些配置将启用行号显示、设置颜色方案和打开语法高亮。set nu " 显示行号 (number) colorscheme desert " 设置颜色显示方案为 desert,你可以尝试其他方案 syntax on " 打开语法高亮
4. 安装docker
本节提供一个自动化脚本,用于在 Debian 系统上安装最新版本的 Docker Engine 和 Docker Compose 插件。该脚本处理了依赖安装、旧版本卸载、官方仓库配置以及用户权限设置等步骤,并提供了详细的日志输出。
4.1 Docker 安装脚本
将以下内容保存为 install_docker.sh
文件,并赋予执行权限后运行。
#!/bin/bash
# --- 配置选项 ---
# 是否安装旧版独立的 docker-compose 可执行文件?
# 设置为 true 会同时安装 docker-compose-plugin 和旧版独立文件
# 设置为 false 则只安装 docker-compose-plugin
# 注意:通常情况下,创建一个从 'docker compose' 到 'docker-compose' 的符号链接就足够,
# 无需再安装旧版独立的 docker-compose 二进制文件。
# 此处默认设置为 false,如果需要真正的旧版独立文件,请改为 true。
INSTALL_OLD_DOCKER_COMPOSE_BINARY=false # 保持为 false,使用符号链接兼容
# --- 字体颜色定义 ---
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# --- 函数定义 ---
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[0;33m[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查是否以root权限运行
check_root() {
if [[ $EUID -ne 0 ]]; then
log_error "此脚本必须以 root 用户身份运行。"
log_error "请使用 'sudo ./install_docker_latest.sh' 运行,或直接切换到 root 用户再执行。"
exit 1
fi
}
# 添加当前用户到docker组
add_user_to_docker_group() {
# 尝试获取原始非root用户,如果脚本是通过 sudo 运行,USER 可能是 root
# 对于直接以 root 登录运行脚本的情况,用户组操作有些特殊,
# 因为通常我们希望将非 root 用户添加到 docker 组。
# 这里我们假定 $SUDO_USER 变量能够提供原始的非 root 用户名。
# 如果是直接以 root 用户登录执行脚本,那么 $SUDO_USER 可能为空,
# 这种情况下,root 用户本身不需要添加到 docker 组。
TARGET_USER="${SUDO_USER:-$USER}" # 如果 SUDO_USER 不为空则用它,否则用当前用户
if [ "$TARGET_USER" == "root" ]; then
log_warn "当前用户是 root,root 用户通常不需要添加到 'docker' 组。"
log_warn "如果您希望其他非 root 用户可以执行 docker 命令,请手动将他们添加到 'docker' 组。"
else
log_info "将用户 '$TARGET_USER' 添加到 'docker' 组..."
usermod -aG docker "$TARGET_USER"
if [ $? -eq 0 ]; then
log_info "用户 '$TARGET_USER' 已添加到 'docker' 组。您需要注销并重新登录或运行 'newgrp docker' 以应用更改。"
log_info "运行 'newgrp docker' 以立即应用组更改(可能导致当前shell会话中断)。"
log_warn "建议在脚本运行完毕后,手动注销并重新登录以确保权限完全生效。"
else
log_error "添加用户到 'docker' 组失败。请检查是否已存在该用户或权限问题。"
fi
fi
}
# --- 主脚本逻辑 ---
check_root # 确保脚本以 root 权限运行
log_info "正在更新系统软件包列表并安装必要的依赖..."
if ! apt update; then
log_error "apt update 失败!请检查网络连接或源配置。退出。"
exit 1
fi
if ! apt install -y ca-certificates curl gnupg lsb-release; then
log_error "安装必要依赖失败!退出。"
exit 1
fi
log_info "正在卸载可能存在的旧版 Docker 相关软件包..."
# 尝试卸载可能存在的旧版本Docker
apt remove -y docker docker-engine docker.io containerd runc
apt autoremove -y
log_info "正在设置 Docker 官方 APT 仓库..."
# 创建密钥目录
if ! install -m 0755 -d /etc/apt/keyrings; then
log_error "创建 /etc/apt/keyrings 目录失败。退出。"
exit 1
fi
# 下载并添加 GPG 密钥
if ! curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg; then
log_error "下载或添加 Docker GPG 密钥失败。退出。"
exit 1
fi
chmod a+r /etc/apt/keyrings/docker.gpg # 确保权限正确
# 添加 Docker APT 仓库
if ! echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null; then
log_error "添加 Docker APT 仓库失败。退出。"
exit 1
fi
log_info "正在更新 apt 软件包索引以包含 Docker 仓库..."
if ! apt update; then
log_error "apt update (包含Docker仓库) 失败!退出。"
exit 1
fi
log_info "正在安装 Docker Engine (docker-ce, docker-ce-cli, containerd.io) 和 Docker Compose 插件..."
if ! apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin; then
log_error "安装 Docker Engine 和 docker-compose-plugin 失败!退出。"
exit 1
fi
log_info "Docker Engine 和 Docker Compose 插件安装成功。"
# 如果选择安装旧版独立的 docker-compose 可执行文件
if [ "$INSTALL_OLD_DOCKER_COMPOSE_BINARY" = true ]; then
log_info "正在下载并安装旧版独立的 docker-compose 可执行文件..."
# 查找适用于当前架构的最新 docker-compose 版本
DOCKER_COMPOSE_URL=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep browser_download_url | grep "docker-compose-$(uname -s)-$(uname -m)" | cut -d '"' -f 4)
if [ -z "$DOCKER_COMPOSE_URL" ]; then
log_error "未能找到最新的 docker-compose 下载链接。跳过旧版独立文件安装。"
else
log_info "下载链接: $DOCKER_COMPOSE_URL"
if ! curl -L "$DOCKER_COMPOSE_URL" -o /usr/local/bin/docker-compose; then
log_error "下载旧版 docker-compose 可执行文件失败。"
else
if ! chmod +x /usr/local/bin/docker-compose; then
log_error "为旧版 docker-compose 添加执行权限失败。"
else
log_info "旧版独立的 docker-compose 安装成功。"
log_info "验证旧版 docker-compose 版本:"
# 直接运行旧版 docker-compose
/usr/local/bin/docker-compose --version
fi
fi
fi
else
# 在 /usr/local/bin 中创建符号链接,将 docker-compose 指向 docker cli
log_info "创建 'docker-compose' 符号链接,以兼容旧版命令..."
if [ -f "/usr/local/bin/docker-compose" ]; then
log_warn "检测到 /usr/local/bin/docker-compose 已存在,正在删除旧链接/文件..."
rm /usr/local/bin/docker-compose
fi
# 尝试找到 docker 可执行文件的位置,通常在 /usr/bin/docker
DOCKER_CLI_PATH=$(command -v docker)
if [ -z "$DOCKER_CLI_PATH" ]; then
log_error "未找到 'docker' CLI 可执行文件。无法创建 docker-compose 兼容链接。"
else
# 创建符号链接,使 docker-compose 调用 'docker compose'
ln -s "$DOCKER_CLI_PATH" /usr/local/bin/docker-compose
if [ $? -eq 0 ]; then
log_info "已成功创建 /usr/local/bin/docker-compose -> $DOCKER_CLI_PATH 的符号链接。"
log_info "现在可以使用 'docker-compose' 命令来调用 'docker compose' 功能。"
else
log_error "创建 'docker-compose' 符号链接失败。"
fi
fi
fi
# 添加用户到docker组
add_user_to_docker_group
log_info "验证 Docker Engine 安装..."
if ! docker run hello-world; then
log_error "Docker Engine 验证失败!请检查 Docker 服务状态。退出。"
exit 1
fi
log_info "验证 Docker Compose 插件安装 (新方式:docker compose)..."
if ! docker compose version; then
log_error "Docker Compose 插件验证失败!退出。"
exit 1
fi
# 验证 docker-compose 兼容链接
if [ -L "/usr/local/bin/docker-compose" ]; then
log_info "验证 'docker-compose' 兼容性(通过符号链接)..."
if ! docker-compose version; then
log_error "'docker-compose' 兼容性验证失败,可能符号链接有问题。"
else
log_info "'docker-compose' 命令兼容性良好。"
fi
fi
log_info "所有操作完成。请在尝试运行 Docker 命令前,重新登录您的会话或运行 'newgrp docker'。"
log_info "感谢使用!"
4.2 如何使用脚本
- 保存脚本: 将上述代码复制并保存到一个文件,例如
install_docker.sh
。 - 添加执行权限: 在终端中运行
chmod +x install_docker.sh
。 - 运行脚本: 使用
sudo
权限运行脚本:sudo ./install_docker.sh
。
4.3 脚本功能详解
-
配置选项 (
INSTALL_OLD_DOCKER_COMPOSE_BINARY
):- 此变量控制是否安装旧版独立的
docker-compose
二进制文件。 - 默认设置为
false
,这意味着脚本将安装 Docker Compose 插件 (docker-compose-plugin
),并创建一个符号链接,使docker-compose
命令能够调用docker compose
(这是 Docker 官方推荐的新用法)。 - 如果你有特殊需求,需要旧版独立的
docker-compose
可执行文件,可以将其设置为true
。
- 此变量控制是否安装旧版独立的
-
日志与权限检查:
log_info
,log_warn
,log_error
函数用于输出带有颜色标记的信息、警告和错误,提高脚本的可读性。check_root
函数确保脚本以root
用户权限运行,这是安装系统级软件所必需的。
-
添加用户到 Docker 组 (
add_user_to_docker_group
):- 此函数将当前用户(或通过
sudo
运行时的原始用户)添加到docker
用户组。 - 重要提示: 将用户添加到
docker
组后,该用户无需sudo
即可运行 Docker 命令。为了使更改生效,你需要注销并重新登录,或者在当前会话中运行newgrp docker
命令(这可能会导致当前 shell 会话中断)。
- 此函数将当前用户(或通过
-
核心安装流程:
- 更新依赖: 更新
apt
软件包列表并安装ca-certificates
,curl
,gnupg
,lsb-release
等必要工具。 - 卸载旧版本: 尝试卸载系统中可能存在的旧版 Docker 相关软件包,避免冲突。
- 设置 Docker 官方 APT 仓库:
- 创建
/etc/apt/keyrings
目录。 - 下载并添加 Docker 官方的 GPG 密钥,用于验证软件包的真实性。
- 将 Docker 的 APT 仓库地址添加到
/etc/apt/sources.list.d/docker.list
文件中。
- 创建
- 安装 Docker Engine 和 Docker Compose 插件:
- 再次更新
apt
软件包索引,以包含新的 Docker 仓库。 - 安装
docker-ce
(Docker Engine 社区版),docker-ce-cli
(Docker 命令行客户端),containerd.io
(容器运行时),docker-buildx-plugin
(构建工具) 和docker-compose-plugin
(Docker Compose 插件)。
- 再次更新
- 更新依赖: 更新
-
Docker Compose 兼容性处理:
- 如果
INSTALL_OLD_DOCKER_COMPOSE_BINARY
为false
(默认),脚本会在/usr/local/bin/
目录下创建一个名为docker-compose
的符号链接,指向docker
可执行文件。 - 这意味着,即使你输入
docker-compose
命令,它实际上也会调用docker compose
命令,从而兼容旧的docker-compose
语法,同时使用新的插件功能。
- 如果
-
安装验证:
- 脚本会运行
docker run hello-world
来验证 Docker Engine 是否正确安装并运行。 - 接着,它会运行
docker compose version
来验证 Docker Compose 插件是否可用。 - 如果创建了
docker-compose
符号链接,还会额外验证docker-compose version
命令的兼容性。
- 脚本会运行
-
后续步骤:
- 脚本最后会提示用户,在尝试运行 Docker 命令之前,需要重新登录会话或运行
newgrp docker
,以确保用户组权限的完全生效
- 脚本最后会提示用户,在尝试运行 Docker 命令之前,需要重新登录会话或运行