twine upload报 401或pip install提示No matching distribution found——多半不是包坏了而是私服还没接对服务没起来、上传地址和安装索引搞混、username没写成__token__或 index-url 漏了/simple/。下面用 AngusRepo社区版私有化部署按操作顺序走完一遍安装 → 建仓与令牌 → .pypirc / pip.conf → 最小包上传与安装 → 验证。命令里的主机写成repo.example.com换成你的域名即可。1. 安装得到可打开的控制台前提Docker Engine Compose v2约 2 核 / 4 GB放行80gm.example.com与repo.example.com已解析到本机试用可写/etc/hosts。完整步骤见 第一次跑通。curl--fail--location--progress-bar-oAngusRepo-Community-1.0.0.zip\https://repo.anguskit.com/raw/raw-public/AngusKit/repo/AngusRepo-Community-1.0.0.zipunzipAngusRepo-Community-1.0.0.zipcdAngusRepo-1.0.0 ./install.sh向导与快速开始对齐ComposeAccess 选2捆绑反代TLS 选4HTTP:80Database 选 Compose 内 MySQLPublic DNS name 填后缀如example.com。出现Install finished.后./bin/angusctl.sh doctor# 看到 doctor: OK浏览器打开http://gm.example.com/登录再打开http://repo.example.com/。Windows 用curl.exe.\install.bat。需要 HTTPS 时见 安装与部署。下文默认HTTP 私有化。HTTP 下 pip 通常要加trusted-host上了可信证书后改成https://并可去掉该项。控制台能打开后先建仓库和令牌再改客户端配置。2. 建仓、令牌与拓扑twine upload只能进HOSTEDPROXY、GROUP 只读。在http://repo.example.com/创建仓库名示例类型干什么pypi-hostedHOSTEDtwine 上传目标建议禁止覆盖pypi-proxyPROXY代理 PyPI远程 URLhttps://pypi.orgpypi-allGROUPpip 统一安装入口成员顺序 hosted → proxy两套路径不要混上传/pypi/仓库名/HOSTED 根路径安装/pypi/仓库名/simple/必须带/simple/PEP 503同一控制台继续准备创建访问令牌只显示一次立刻保存CI 对pypi-hosted有 Write开发者对pypi-all有 ReadGROUP 成员顺序确认为 hosted → pypi-proxyexportREPO_TOKENyour_access_tokenexportREPO_HOSTrepo.example.com具体路径以控制台「接入配置」为准字段说明见 PyPI 格式。3. 安装pip.conf / index-url默认口径安装走 GROUPpypi-all/simple/上传走 HOSTED。# ~/.config/pip/pip.conf 或项目旁 pip.conf [global] index-url http://repo.example.com/pypi/pypi-all/simple/ trusted-host repo.example.com单次命令pipinstallsome-pkg\--index-urlhttp://$REPO_HOST/pypi/pypi-all/simple/\--trusted-host$REPO_HOST只想装内部包、公共包仍走官方源时pipinstallyour-package\--index-url https://pypi.org/simple\--extra-index-urlhttp://$REPO_HOST/pypi/pypi-hosted/simple/\--trusted-host$REPO_HOSTindex-url/extra-index-url必须以/simple/结尾。4. 发布.pypirc 与 twineusername固定写__token__不是登录名password才是访问令牌。# ~/.pypirc勿提交含真实令牌的文件 [distutils] index-servers angusrepo [angusrepo] repository http://repo.example.com/pypi/pypi-hosted/ username __token__ password your_access_tokenpython3-mpipinstallbuild twine python3-mbuild twine upload\--repository-urlhttp://$REPO_HOST/pypi/pypi-hosted/\--username__token__\--password$REPO_TOKEN\dist/*或twine upload -r angusrepo dist/*。同版本重复上传通常会失败——升版本不要覆盖。5. 验证闭环最小可上传包mkdir-p/tmp/angus-pypi-democd/tmp/angus-pypi-democatpyproject.tomlEOF [build-system] requires [setuptools61] build-backend setuptools.build_meta [project] name angus-demo-utils version 1.0.0 description AngusRepo PyPI smoke package requires-python 3.9 EOFmkdir-pangus_demo_utilsechoOK Trueangus_demo_utils/__init__.py python3-mpipinstall-qbuild twine python3-mbuild twine upload\--repository-urlhttp://$REPO_HOST/pypi/pypi-hosted/\--username__token__\--password$REPO_TOKEN\dist/*干净环境安装python3-mvenv /tmp/angus-pypi-venvsource/tmp/angus-pypi-venv/bin/activate pipinstallangus-demo-utils1.0.0\--index-urlhttp://$REPO_HOST/pypi/pypi-all/simple/\--trusted-host$REPO_HOSTpython-cimport angus_demo_utils; print(angus_demo_utils.OK)应打印True。控制台制品列表应能看到1.0.0。CI 最小片段-run:|python -m pip install build twine python -m build twine upload \ --repository-url http://$REPO_HOST/pypi/pypi-hosted/ \ --username __token__ \ --password $REPO_TOKEN \ dist/*Poetrypoetry source add指 GROUP 的/simple/认证用户名同样__token__。流水线编排另见 Jenkins 构建测试发布。6. 日常维护清理旧版本— HOSTED 保留最近 N 版先 Dry Run见 清理策略。PROXY 冷缓存— 首次拉公共包会慢可预热。入库检查— 轻量门禁在 Repo深度扫描另接见 入库门禁与 SBOM。报错速查症状常见原因怎么处理twine 401username 不是__token__或令牌错误改用户名与令牌查 HOSTED WriteNo matching distribution found安装 URL 缺/simple/或指错仓用…/pypi-all/simple/能上传不能安装装到了官方源没走含 HOSTED 的 GROUP改 index-urlSSL / 证书错误HTTP未设trusted-hostpip.conf 加上主机名409 / 文件已存在同版本重复上传升版本号FAQ能不能 twine 到 GROUP不能。上传只能 HOSTEDpip 安装用 GROUP 的/simple/。username 能写登录名吗按 PyPI token 约定应写__token__。写登录名在多数私服会直接 401。HTTP 环境必须配 trusted-host 吗是。无证书时 pip 默认校验 TLSHTTP 私服不配往往会握手失败。小结安装并打开控制台 → HOSTED PROXY GROUP → 发令牌。上传走 HOSTED 根路径安装走 GROUP/simple/。__token__ 令牌进密码位用最小包跑通 build → twine → pip。参考文章第一次跑通安装与部署PyPI 格式清理策略Jenkins 构建测试发布入库门禁与 SBOM