Update dock安装cf
This commit is contained in:
253
dock安装cf
253
dock安装cf
@@ -1,220 +1,145 @@
|
|||||||
mkdir -p /data
|
|
||||||
|
|
||||||
cat > /data/install_docker_offline.sh << 'EOF'
|
|
||||||
cat > /data/install_docker_offline.sh << 'EOF'
|
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# 仅使用你提供的离线包(Docker 本体来源固定为 ZIP)
|
# ===============================
|
||||||
|
# 仅使用你指定的 Docker 离线包
|
||||||
|
# ===============================
|
||||||
URL_PRIMARY="https://pub-b69a7194f4ea42fba6aa990c49bded91.r2.dev/xui/dockde12.zip"
|
URL_PRIMARY="https://pub-b69a7194f4ea42fba6aa990c49bded91.r2.dev/xui/dockde12.zip"
|
||||||
URL_BACKUP="https://freeyx.vps3344.dpdns.org/xui/dockde12.zip"
|
URL_BACKUP="https://freeyx.vps3344.dpdns.org/xui/dockde12.zip"
|
||||||
|
|
||||||
WORKDIR="/tmp/docker_offline_install"
|
WORKDIR="/root/docker_offline_install"
|
||||||
ZIP_FILE="$WORKDIR/dockde12.zip"
|
ZIP_FILE="$WORKDIR/dockde12.zip"
|
||||||
|
|
||||||
log(){ echo "[*] $*"; }
|
log(){ echo -e "\033[32m[✔]\033[0m $*"; }
|
||||||
warn(){ echo "[!] $*"; }
|
warn(){ echo -e "\033[33m[!]\033[0m $*"; }
|
||||||
die(){ echo "[X] $*"; exit 1; }
|
err(){ echo -e "\033[31m[✘]\033[0m $*"; }
|
||||||
|
|
||||||
need_root() {
|
# ===============================
|
||||||
[ "$(id -u)" -eq 0 ] || die "请使用 root 运行(sudo -i 后再执行)"
|
# 基础检查
|
||||||
}
|
# ===============================
|
||||||
|
[ "$(id -u)" -eq 0 ] || { err "请使用 root 运行"; exit 1; }
|
||||||
|
[ "$(uname -m)" = "x86_64" ] || { err "仅支持 x86_64 架构"; exit 1; }
|
||||||
|
|
||||||
arch_check() {
|
# ===============================
|
||||||
[ "$(uname -m)" = "x86_64" ] || die "仅支持 x86_64(AMD64)架构"
|
# dpkg / apt 锁等待
|
||||||
}
|
# ===============================
|
||||||
|
wait_lock() {
|
||||||
wait_dpkg_locks() {
|
for i in {1..60}; do
|
||||||
log "检查 dpkg/apt 锁..."
|
|
||||||
local i
|
|
||||||
for i in $(seq 1 60); do
|
|
||||||
if fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1 || \
|
if fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1 || \
|
||||||
fuser /var/lib/dpkg/lock >/dev/null 2>&1 || \
|
fuser /var/lib/dpkg/lock >/dev/null 2>&1 || \
|
||||||
fuser /var/cache/apt/archives/lock >/dev/null 2>&1; then
|
fuser /var/cache/apt/archives/lock >/dev/null 2>&1; then
|
||||||
sleep 2
|
sleep 2
|
||||||
continue
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
done
|
|
||||||
die "dpkg/apt 锁持续占用(可能正在自动更新)。请稍后再运行。"
|
|
||||||
}
|
|
||||||
|
|
||||||
env_sanity_check() {
|
|
||||||
# systemd 检查:没有 systemd 的环境,docker.service 无法按常规启动
|
|
||||||
if ! command -v systemctl >/dev/null 2>&1; then
|
|
||||||
warn "检测不到 systemctl(可能不是标准 Debian 主机环境)。安装可能完成,但无法以 systemd 方式启动。"
|
|
||||||
else
|
else
|
||||||
if ! systemctl is-system-running >/dev/null 2>&1; then
|
return
|
||||||
warn "systemd 可能未正常运行(容器/精简环境常见)。即使安装成功,docker 服务也可能无法启动。"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
done
|
||||||
|
err "dpkg/apt 锁长期占用,请稍后再试"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
# 容器环境提示(不强制退出,但给出风险提示)
|
# ===============================
|
||||||
|
# 环境提示(不强退)
|
||||||
|
# ===============================
|
||||||
if command -v systemd-detect-virt >/dev/null 2>&1; then
|
if command -v systemd-detect-virt >/dev/null 2>&1; then
|
||||||
local virt
|
virt=$(systemd-detect-virt || true)
|
||||||
virt="$(systemd-detect-virt || true)"
|
|
||||||
if [ "$virt" != "none" ] && [ -n "$virt" ]; then
|
if [ "$virt" != "none" ] && [ -n "$virt" ]; then
|
||||||
warn "检测到虚拟化/容器环境:$virt。若是非特权 LXC/OpenVZ,Docker 可能无法运行(需要特权/开启 nesting)。"
|
warn "检测到虚拟化/容器环境:$virt(非特权容器可能无法运行 Docker)"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
|
||||||
|
|
||||||
install_tools_if_missing() {
|
# ===============================
|
||||||
# 仅安装“解压/下载必要工具”,不涉及 Docker 包来源
|
# 准备工具(不涉及 Docker 来源)
|
||||||
wait_dpkg_locks
|
# ===============================
|
||||||
|
wait_lock
|
||||||
if ! command -v curl >/dev/null 2>&1 && ! command -v wget >/dev/null 2>&1; then
|
|
||||||
log "安装下载工具 curl..."
|
|
||||||
apt-get update -y >/dev/null 2>&1 || true
|
apt-get update -y >/dev/null 2>&1 || true
|
||||||
apt-get install -y curl >/dev/null 2>&1 || die "无法安装 curl(网络或源不可用)"
|
apt-get install -y curl wget unzip python3 >/dev/null 2>&1 || true
|
||||||
fi
|
|
||||||
|
|
||||||
if ! command -v unzip >/dev/null 2>&1 && ! command -v python3 >/dev/null 2>&1; then
|
# ===============================
|
||||||
log "安装解压工具 unzip(或 python3)..."
|
# 停服务 + 清理冲突
|
||||||
apt-get update -y >/dev/null 2>&1 || true
|
# ===============================
|
||||||
apt-get install -y unzip >/dev/null 2>&1 || true
|
log "停止旧 Docker / containerd"
|
||||||
if ! command -v unzip >/dev/null 2>&1; then
|
|
||||||
apt-get install -y python3 >/dev/null 2>&1 || die "缺少 unzip/python3 且无法安装(网络或源不可用)"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
stop_old_services() {
|
|
||||||
log "停止可能存在的旧服务..."
|
|
||||||
systemctl stop docker >/dev/null 2>&1 || true
|
systemctl stop docker >/dev/null 2>&1 || true
|
||||||
systemctl stop containerd >/dev/null 2>&1 || true
|
systemctl stop containerd >/dev/null 2>&1 || true
|
||||||
}
|
|
||||||
|
|
||||||
purge_conflicts() {
|
log "清理可能冲突的旧包"
|
||||||
log "清理可能冲突的旧包(尽量保证可重复安装)..."
|
wait_lock
|
||||||
# 这些包会与离线 docker-ce / containerd.io / runc 冲突
|
apt-get remove -y docker.io docker-doc docker-compose podman-docker \
|
||||||
local PKGS="docker.io docker-doc docker-compose podman-docker containerd runc docker-ce docker-ce-cli containerd.io"
|
docker-ce docker-ce-cli containerd containerd.io runc >/dev/null 2>&1 || true
|
||||||
wait_dpkg_locks
|
apt-get purge -y docker.io docker-doc docker-compose podman-docker \
|
||||||
apt-get remove -y $PKGS >/dev/null 2>&1 || true
|
docker-ce docker-ce-cli containerd containerd.io runc >/dev/null 2>&1 || true
|
||||||
apt-get purge -y $PKGS >/dev/null 2>&1 || true
|
|
||||||
apt-get autoremove -y >/dev/null 2>&1 || true
|
apt-get autoremove -y >/dev/null 2>&1 || true
|
||||||
|
|
||||||
# 关键:旧 containerd 配置经常导致新版本 containerd 启动失败
|
# containerd 老配置是最大坑,直接备份移走
|
||||||
if [ -f /etc/containerd/config.toml ]; then
|
if [ -f /etc/containerd/config.toml ]; then
|
||||||
log "备份并移除旧 /etc/containerd/config.toml(避免 containerd 启动冲突)"
|
warn "发现旧 containerd 配置,已备份并移除"
|
||||||
mv /etc/containerd/config.toml "/etc/containerd/config.toml.bak.$(date +%s)" || true
|
mv /etc/containerd/config.toml /etc/containerd/config.toml.bak.$(date +%s)
|
||||||
fi
|
fi
|
||||||
}
|
|
||||||
|
|
||||||
download_zip() {
|
# ===============================
|
||||||
log "准备下载离线包(双线路)..."
|
# 下载离线包(双线路)
|
||||||
|
# ===============================
|
||||||
rm -rf "$WORKDIR"
|
rm -rf "$WORKDIR"
|
||||||
mkdir -p "$WORKDIR"
|
mkdir -p "$WORKDIR"
|
||||||
|
|
||||||
local ok=0
|
log "下载 Docker 离线包(主线路)"
|
||||||
if command -v curl >/dev/null 2>&1; then
|
if ! curl -L -k --retry 3 --connect-timeout 10 -o "$ZIP_FILE" "$URL_PRIMARY"; then
|
||||||
curl -L -k --retry 3 --connect-timeout 10 -o "$ZIP_FILE" "$URL_PRIMARY" && ok=1 || true
|
warn "主线路失败,切换备用线路"
|
||||||
if [ "$ok" -ne 1 ]; then
|
curl -L -k --retry 3 --connect-timeout 10 -o "$ZIP_FILE" "$URL_BACKUP" \
|
||||||
curl -L -k --retry 3 --connect-timeout 10 -o "$ZIP_FILE" "$URL_BACKUP" && ok=1 || true
|
|| { err "离线包下载失败"; exit 1; }
|
||||||
fi
|
|
||||||
else
|
|
||||||
wget --no-check-certificate -t 3 -T 10 -O "$ZIP_FILE" "$URL_PRIMARY" && ok=1 || true
|
|
||||||
if [ "$ok" -ne 1 ]; then
|
|
||||||
wget --no-check-certificate -t 3 -T 10 -O "$ZIP_FILE" "$URL_BACKUP" && ok=1 || true
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[ "$ok" -eq 1 ] || die "离线包下载失败(两条线路都失败)"
|
[ -s "$ZIP_FILE" ] || { err "下载的 ZIP 文件为空"; exit 1; }
|
||||||
[ -s "$ZIP_FILE" ] || die "离线包下载为空文件"
|
|
||||||
}
|
|
||||||
|
|
||||||
extract_debs() {
|
# ===============================
|
||||||
log "解压离线包..."
|
# 解压并整理 deb
|
||||||
|
# ===============================
|
||||||
|
log "解压离线包"
|
||||||
cd "$WORKDIR"
|
cd "$WORKDIR"
|
||||||
|
unzip -oq "$ZIP_FILE" || python3 - <<PY
|
||||||
if command -v unzip >/dev/null 2>&1; then
|
import zipfile
|
||||||
unzip -oq "$ZIP_FILE" || die "unzip 解压失败"
|
|
||||||
else
|
|
||||||
python3 - <<PY
|
|
||||||
import zipfile, sys
|
|
||||||
try:
|
|
||||||
zipfile.ZipFile("$ZIP_FILE").extractall("$WORKDIR")
|
zipfile.ZipFile("$ZIP_FILE").extractall("$WORKDIR")
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
sys.exit(1)
|
|
||||||
PY
|
PY
|
||||||
fi
|
|
||||||
|
|
||||||
# 防止套娃目录:把所有 deb 收拢到 WORKDIR 根目录
|
find "$WORKDIR" -name "*.deb" -exec mv -f {} "$WORKDIR" \; 2>/dev/null
|
||||||
find "$WORKDIR" -name "*.deb" -exec mv -f {} "$WORKDIR" \; 2>/dev/null || true
|
ls *.deb >/dev/null 2>&1 || { err "未找到 deb 文件"; exit 1; }
|
||||||
|
|
||||||
ls "$WORKDIR"/*.deb >/dev/null 2>&1 || die "解压后未找到 .deb 文件(可能压缩包结构变化或损坏)"
|
# ===============================
|
||||||
}
|
# 安装(两段式,保证成功率)
|
||||||
|
# ===============================
|
||||||
install_debs_with_fix() {
|
log "安装 Docker(第一次 dpkg)"
|
||||||
log "安装离线 deb 包..."
|
|
||||||
cd "$WORKDIR"
|
|
||||||
|
|
||||||
# 第一次安装可能会失败(依赖缺失),不直接退出
|
|
||||||
set +e
|
set +e
|
||||||
dpkg -i --force-overwrite ./*.deb >/dev/null 2>&1
|
dpkg -i --force-overwrite *.deb >/dev/null 2>&1
|
||||||
local rc=$?
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [ "$rc" -ne 0 ]; then
|
log "修复依赖"
|
||||||
warn "dpkg 首次安装遇到依赖/冲突,尝试 apt 自动修复依赖..."
|
wait_lock
|
||||||
wait_dpkg_locks
|
apt-get -f install -y || { err "依赖修复失败"; exit 1; }
|
||||||
apt-get update -y >/dev/null 2>&1 || true
|
|
||||||
apt-get -f install -y || die "依赖自动修复失败(可能网络/源不可用或系统依赖严重缺失)"
|
|
||||||
|
|
||||||
log "依赖修复完成,重试安装 deb..."
|
log "重新安装 Docker(第二次 dpkg)"
|
||||||
dpkg -i --force-overwrite ./*.deb >/dev/null 2>&1 || die "重试 dpkg 安装仍失败"
|
dpkg -i --force-overwrite *.deb >/dev/null 2>&1 || { err "dpkg 安装失败"; exit 1; }
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
start_and_verify() {
|
# ===============================
|
||||||
log "启动 Docker..."
|
# 启动并验证
|
||||||
if command -v systemctl >/dev/null 2>&1; then
|
# ===============================
|
||||||
|
log "启动 Docker"
|
||||||
systemctl daemon-reload >/dev/null 2>&1 || true
|
systemctl daemon-reload >/dev/null 2>&1 || true
|
||||||
systemctl unmask docker >/dev/null 2>&1 || true
|
systemctl unmask docker >/dev/null 2>&1 || true
|
||||||
systemctl enable docker >/dev/null 2>&1 || true
|
systemctl enable docker >/dev/null 2>&1 || true
|
||||||
systemctl restart docker >/dev/null 2>&1 || true
|
systemctl restart docker >/dev/null 2>&1 || true
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
||||||
|
if docker info >/dev/null 2>&1; then
|
||||||
|
log "Docker 安装成功"
|
||||||
|
docker --version
|
||||||
|
docker compose version >/dev/null 2>&1 && docker compose version
|
||||||
else
|
else
|
||||||
warn "没有 systemctl,跳过 docker.service 启动(需要你自行以非 systemd 方式启动)"
|
err "Docker 启动失败"
|
||||||
fi
|
journalctl -xeu docker.service | tail -n 30
|
||||||
|
|
||||||
if command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
|
|
||||||
log "Docker 安装并运行成功:$(docker --version 2>/dev/null || true)"
|
|
||||||
if docker compose version >/dev/null 2>&1; then
|
|
||||||
log "Compose 可用:$(docker compose version 2>/dev/null || true)"
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
warn "Docker 未能正常运行。常见原因:容器环境/内核特性缺失/systemd 不可用。"
|
|
||||||
if command -v systemctl >/dev/null 2>&1; then
|
|
||||||
warn "可用命令:journalctl -xeu docker.service"
|
|
||||||
systemctl status docker --no-pager >/dev/null 2>&1 || true
|
|
||||||
fi
|
|
||||||
exit 1
|
exit 1
|
||||||
}
|
fi
|
||||||
|
|
||||||
cleanup() {
|
# ===============================
|
||||||
rm -rf "$WORKDIR" >/dev/null 2>&1 || true
|
# 清理
|
||||||
}
|
# ===============================
|
||||||
|
rm -rf "$WORKDIR"
|
||||||
main() {
|
log "完成"
|
||||||
need_root
|
|
||||||
arch_check
|
|
||||||
env_sanity_check
|
|
||||||
install_tools_if_missing
|
|
||||||
stop_old_services
|
|
||||||
purge_conflicts
|
|
||||||
download_zip
|
|
||||||
extract_debs
|
|
||||||
install_debs_with_fix
|
|
||||||
start_and_verify
|
|
||||||
cleanup
|
|
||||||
}
|
|
||||||
|
|
||||||
main
|
|
||||||
EOF
|
|
||||||
|
|
||||||
chmod +x /data/install_docker_offline.sh
|
|
||||||
bash /data/install_docker_offline.sh
|
|
||||||
|
|||||||
Reference in New Issue
Block a user