fix: pip 镜像失败时自动回退并提示代理
EOF Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+2
-2
@@ -201,8 +201,8 @@ setup_backend() {
|
|||||||
fi
|
fi
|
||||||
# shellcheck disable=SC1091
|
# shellcheck disable=SC1091
|
||||||
source venv/bin/activate
|
source venv/bin/activate
|
||||||
pip install --upgrade pip --progress-bar on -i "${PIP_MIRROR}"
|
pip_install_with_fallback --upgrade pip
|
||||||
pip install -r requirements.txt --progress-bar on -i "${PIP_MIRROR}"
|
pip_install_with_fallback -r requirements.txt
|
||||||
deactivate
|
deactivate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+80
-1
@@ -5,6 +5,17 @@
|
|||||||
# export https_proxy=http://192.168.8.246:10810
|
# export https_proxy=http://192.168.8.246:10810
|
||||||
# export HTTP_PROXY="$http_proxy"
|
# export HTTP_PROXY="$http_proxy"
|
||||||
# export HTTPS_PROXY="$https_proxy"
|
# export HTTPS_PROXY="$https_proxy"
|
||||||
|
#
|
||||||
|
# pip 镜像(可覆盖):
|
||||||
|
# export PIP_MIRROR=https://mirrors.aliyun.com/pypi/simple
|
||||||
|
|
||||||
|
# 国内镜像优先;代理不可用时仍可走直连镜像。官方源放最后。
|
||||||
|
PIP_MIRROR_FALLBACKS=(
|
||||||
|
"https://pypi.tuna.tsinghua.edu.cn/simple"
|
||||||
|
"https://mirrors.aliyun.com/pypi/simple"
|
||||||
|
"https://mirrors.cloud.tencent.com/pypi/simple"
|
||||||
|
"https://pypi.org/simple"
|
||||||
|
)
|
||||||
|
|
||||||
setup_deploy_proxy() {
|
setup_deploy_proxy() {
|
||||||
local proxy="${HTTP_PROXY:-${http_proxy:-}}"
|
local proxy="${HTTP_PROXY:-${http_proxy:-}}"
|
||||||
@@ -22,7 +33,17 @@ setup_deploy_proxy() {
|
|||||||
export HTTPS_PROXY="$https_proxy"
|
export HTTPS_PROXY="$https_proxy"
|
||||||
export ALL_PROXY="${ALL_PROXY:-$http_proxy}"
|
export ALL_PROXY="${ALL_PROXY:-$http_proxy}"
|
||||||
|
|
||||||
if [[ -n "${log_info:-}" ]]; then
|
# 国内 PyPI 镜像走直连,避免坏代理导致 "from versions: none"
|
||||||
|
local no_proxy_extra="pypi.tuna.tsinghua.edu.cn,mirrors.aliyun.com,mirrors.cloud.tencent.com,files.pythonhosted.org"
|
||||||
|
if [[ -z "${NO_PROXY:-${no_proxy:-}}" ]]; then
|
||||||
|
export NO_PROXY="127.0.0.1,localhost,${no_proxy_extra}"
|
||||||
|
export no_proxy="${NO_PROXY}"
|
||||||
|
else
|
||||||
|
export NO_PROXY="${NO_PROXY:-${no_proxy}},${no_proxy_extra}"
|
||||||
|
export no_proxy="${NO_PROXY}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if declare -F log_info >/dev/null 2>&1; then
|
||||||
log_info "使用网络代理: ${http_proxy}"
|
log_info "使用网络代理: ${http_proxy}"
|
||||||
else
|
else
|
||||||
echo "[INFO] 使用网络代理: ${http_proxy}"
|
echo "[INFO] 使用网络代理: ${http_proxy}"
|
||||||
@@ -34,3 +55,61 @@ Acquire::http::Proxy "${http_proxy}";
|
|||||||
Acquire::https::Proxy "${https_proxy}";
|
Acquire::https::Proxy "${https_proxy}";
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pip_host_from_url() {
|
||||||
|
# https://host/path -> host
|
||||||
|
local url="$1"
|
||||||
|
url="${url#https://}"
|
||||||
|
url="${url#http://}"
|
||||||
|
echo "${url%%/*}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 用法: pip_install_with_fallback --upgrade pip
|
||||||
|
# pip_install_with_fallback -r requirements.txt
|
||||||
|
# 依次尝试 PIP_MIRROR 与备用镜像;失败时给出代理提示。
|
||||||
|
pip_install_with_fallback() {
|
||||||
|
local mirrors=()
|
||||||
|
local m seen=""
|
||||||
|
if [[ -n "${PIP_MIRROR:-}" ]]; then
|
||||||
|
mirrors+=("${PIP_MIRROR}")
|
||||||
|
fi
|
||||||
|
for m in "${PIP_MIRROR_FALLBACKS[@]}"; do
|
||||||
|
mirrors+=("$m")
|
||||||
|
done
|
||||||
|
|
||||||
|
local mirror host
|
||||||
|
for mirror in "${mirrors[@]}"; do
|
||||||
|
case " ${seen} " in
|
||||||
|
*" ${mirror} "*) continue ;;
|
||||||
|
esac
|
||||||
|
seen="${seen} ${mirror}"
|
||||||
|
|
||||||
|
host="$(pip_host_from_url "${mirror}")"
|
||||||
|
if declare -F log_info >/dev/null 2>&1; then
|
||||||
|
log_info "pip 安装(镜像: ${mirror})…"
|
||||||
|
else
|
||||||
|
echo "[INFO] pip 安装(镜像: ${mirror})…"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if pip install "$@" --progress-bar on -i "${mirror}" --trusted-host "${host}"; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if declare -F log_warn >/dev/null 2>&1; then
|
||||||
|
log_warn "镜像不可用: ${mirror},尝试下一个…"
|
||||||
|
else
|
||||||
|
echo "[WARN] 镜像不可用: ${mirror},尝试下一个…"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if declare -F log_error >/dev/null 2>&1; then
|
||||||
|
log_error "所有 pip 镜像均失败(常见原因:服务器无法访问外网 / 代理未设置 / 代理拦截 HTTPS)。"
|
||||||
|
log_error "请先检测网络,再重试安装:"
|
||||||
|
log_error " curl -I https://pypi.tuna.tsinghua.edu.cn/simple/fastapi/"
|
||||||
|
log_error " export http_proxy=http://192.168.8.246:10810"
|
||||||
|
log_error " export https_proxy=\$http_proxy HTTP_PROXY=\$http_proxy HTTPS_PROXY=\$http_proxy"
|
||||||
|
log_error " # 或换镜像: export PIP_MIRROR=https://mirrors.aliyun.com/pypi/simple"
|
||||||
|
else
|
||||||
|
echo "[ERROR] 所有 pip 镜像均失败。请设置代理或更换 PIP_MIRROR 后重试。" >&2
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|||||||
+2
-1
@@ -33,8 +33,9 @@ fi
|
|||||||
|
|
||||||
log_info "更新主程序依赖…"
|
log_info "更新主程序依赖…"
|
||||||
cd backend
|
cd backend
|
||||||
|
# shellcheck source=/dev/null
|
||||||
source venv/bin/activate
|
source venv/bin/activate
|
||||||
pip install -r requirements.txt --progress-bar on -i "${PIP_MIRROR}"
|
pip_install_with_fallback -r requirements.txt
|
||||||
deactivate
|
deactivate
|
||||||
cd "${INSTALL_DIR}"
|
cd "${INSTALL_DIR}"
|
||||||
|
|
||||||
|
|||||||
+45
-2
@@ -295,7 +295,50 @@ sudo bash deploy/update.sh
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 10. 更新后无法访问(连接被拒绝)
|
## 10. pip 安装失败(No matching distribution / from versions: none)
|
||||||
|
|
||||||
|
若 `install.sh` / `update.sh` 在安装 Python 依赖时报:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ERROR: Could not find a version that satisfies the requirement fastapi==0.115.6 (from versions: none)
|
||||||
|
ERROR: No matching distribution found for fastapi==0.115.6
|
||||||
|
```
|
||||||
|
|
||||||
|
说明 **pip 根本拉不到 PyPI 索引**(网络/代理问题),不是版本号写错。
|
||||||
|
|
||||||
|
在服务器上排查:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -I https://pypi.tuna.tsinghua.edu.cn/simple/fastapi/
|
||||||
|
curl -I https://mirrors.aliyun.com/pypi/simple/fastapi/
|
||||||
|
```
|
||||||
|
|
||||||
|
处理方式(任选其一后重新安装):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 方式 A:走代理后再装(代理地址按实际修改)
|
||||||
|
export http_proxy=http://192.168.8.246:10810
|
||||||
|
export https_proxy=http://192.168.8.246:10810
|
||||||
|
export HTTP_PROXY="$http_proxy"
|
||||||
|
export HTTPS_PROXY="$https_proxy"
|
||||||
|
cd /opt/secondary-school-grade-archive
|
||||||
|
sudo -E bash deploy/install.sh
|
||||||
|
|
||||||
|
# 方式 B:换国内镜像
|
||||||
|
export PIP_MIRROR=https://mirrors.aliyun.com/pypi/simple
|
||||||
|
cd /opt/secondary-school-grade-archive/backend
|
||||||
|
source venv/bin/activate
|
||||||
|
pip install -r requirements.txt -i "$PIP_MIRROR" --trusted-host mirrors.aliyun.com
|
||||||
|
deactivate
|
||||||
|
# 依赖装好后继续跑完安装(或再执行 install.sh)
|
||||||
|
sudo -E bash /opt/secondary-school-grade-archive/deploy/install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
当前脚本会自动尝试多个镜像;仍失败时请先保证服务器能访问上述 URL。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. 更新后无法访问(连接被拒绝)
|
||||||
|
|
||||||
若浏览器提示 **ERR_CONNECTION_REFUSED**,通常是 `update.sh` 停止了旧 PM2,但 **systemd 服务未成功启动**。
|
若浏览器提示 **ERR_CONNECTION_REFUSED**,通常是 `update.sh` 停止了旧 PM2,但 **systemd 服务未成功启动**。
|
||||||
|
|
||||||
@@ -319,6 +362,6 @@ ss -tlnp | grep 23566
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 11. 技术支持
|
## 12. 技术支持
|
||||||
|
|
||||||
微信 **dekun03** · 手机 **18364911125**
|
微信 **dekun03** · 手机 **18364911125**
|
||||||
|
|||||||
Reference in New Issue
Block a user