内网环境 Docker 如何pip install package
在内网环境用 Docker 基础镜像构建新镜像时,安装包通常有几种处理方式,核心思路是:不要在构建时访问公网,把依赖提前准备好或放到内网源里。
方案一:把安装包放进构建目录,用 COPY 拷进镜像
适合安装少量 .deb、.rpm、.tar.gz、.whl 等离线包。
例如目录结构:
my-image/
├── Dockerfile
└── packages/
├── nginx_1.24.0.deb
├── libxxx.deb
└── app.tar.gz
Dockerfile 示例:
FROM ubuntu:22.04
COPY packages/ /tmp/packages/
RUN dpkg -i /tmp/packages/*.deb || apt-get install -f -y \
&& rm -rf /tmp/packages/*
如果是 CentOS / Rocky / RHEL:
FROM rocky:9
COPY packages/ /tmp/packages/
RUN dnf install -y /tmp/packages/*.rpm \
&& rm -rf /tmp/packages/*
Python 离线 wheel 包示例:
FROM python:3.11
COPY wheels/ /tmp/wheels/
COPY requirements.txt /tmp/
RUN pip install --no-index --find-links=/tmp/wheels -r /tmp/requirements.txt \
&& rm -rf /tmp/wheels
方案二:搭建内网软件源,构建时从内网源安装
适合依赖较多、需要长期维护的环境。比如搭建:
内网 apt 源
内网 yum/dnf 源
内网 pip 源
内网 npm 源
内网 Maven 仓库
内网 Docker Registry
Ubuntu/Debian 示例:
FROM ubuntu:22.04
RUN sed -i 's|http://archive.ubuntu.com/ubuntu|http://内网apt源/ubuntu|g' /etc/apt/sources.list \
&& apt-get update \
&& apt-get install -y curl vim nginx \
&& rm -rf /var/lib/apt/lists/*
CentOS/Rocky 示例:
FROM rocky:9
COPY internal.repo /etc/yum.repos.d/internal.repo
RUN dnf install -y nginx curl vim \
&& dnf clean all
Python pip 内网源示例:
FROM python:3.11
COPY requirements.txt /app/
RUN pip install -i http://内网pip源/simple --trusted-host 内网pip源 \
-r /app/requirements.txt
方案三:提前在外网机器下载依赖,再带入内网
外网机器下载:
apt-get download curl vim nginx
或者下载 Python wheel:
pip download -r requirements.txt -d wheels/
然后把这些文件拷贝到内网,再在 Dockerfile 里:
COPY wheels/ /tmp/wheels/
RUN pip install --no-index --find-links=/tmp/wheels -r requirements.txt
方案四:直接在外网构建好镜像,再导入内网
外网构建:
docker build -t myapp:1.0 .
docker save myapp:1.0 -o myapp_1.0.tar
拷贝到内网后加载:
docker load -i myapp_1.0.tar
这种方式适合内网机器完全不能访问任何源,只负责运行镜像。
推荐做法
如果只是少量包:
把安装包放到构建目录,然后 COPY 进去安装。
如果是公司长期使用:
搭建内网 apt/yum/pip/npm/Maven 源 + 内网 Docker Registry。
如果内网完全隔离:
外网构建好镜像,docker save 导出,内网 docker load 导入。
一个常见的离线 Dockerfile 模板是:
FROM ubuntu:22.04
COPY packages/ /tmp/packages/
RUN dpkg -i /tmp/packages/*.deb || true \
&& apt-get install -f -y \
&& rm -rf /tmp/packages/*
不过要注意:apt-get install -f 仍然可能需要访问软件源。如果完全离线,必须把所有依赖包也一起准备好。
可以用 pip download 的这些参数指定目标 Python 版本 / 系统平台 / ABI,而不是按当前机器的 Python 环境下载。
1. 下载目标 Python 3.10 的包,走公司内网源
假设你的目标容器是:
Python 3.10
Linux x86_64
CPython
命令可以这样写:
python -m pip download \
-r requirements.txt \
-d wheels/ \
-i http://pypi.company.com/simple \
--trusted-host pypi.company.com \
--only-binary=:all: \
--python-version 310 \
--implementation cp \
--abi cp310 \
--platform manylinux2014_x86_64
其中:
-d wheels/ 下载到 wheels 目录
-i 指定公司内网 PyPI 镜像源
--python-version 310 目标 Python 版本是 3.10
--implementation cp CPython
--abi cp310 Python 3.10 的 CPython ABI
--platform manylinux2014_x86_64 目标 Linux x86_64 平台
--only-binary=:all: 只下载 wheel,不下载源码包
pip 官方文档说明,pip download 可以通过 --platform、--python-version、--implementation、--abi 为“非当前运行环境”的解释器和系统下载依赖;使用这些选项时需要配合 --only-binary=:all: 或 --no-deps。(Pip)
2. Python 版本对应关系
常见写法:
Python 3.8 -> --python-version 38 --abi cp38
Python 3.9 -> --python-version 39 --abi cp39
Python 3.10 -> --python-version 310 --abi cp310
Python 3.11 -> --python-version 311 --abi cp311
Python 3.12 -> --python-version 312 --abi cp312
例如下载 Python 3.11 兼容包:
python -m pip download \
-r requirements.txt \
-d wheels/ \
-i http://pypi.company.com/simple \
--trusted-host pypi.company.com \
--only-binary=:all: \
--python-version 311 \
--implementation cp \
--abi cp311 \
--platform manylinux2014_x86_64
pip 的 --python-version 会参与 wheel 和 Requires-Python 兼容性判断;官方也建议如果指定其中一个目标环境参数,最好同时指定 platform、Python version、implementation、ABI,避免误下载当前机器兼容但目标环境不兼容的包。(Pip)
3. 如果下载机器和目标容器 Python 版本一致
这是最简单、最稳的方式。比如你下载机器本身就是 Python 3.10,目标 Docker 镜像也是 Python 3.10:
python3.10 -m pip download \
-r requirements.txt \
-d wheels/ \
-i http://pypi.company.com/simple \
--trusted-host pypi.company.com
这种方式通常不需要手动写 --python-version、--abi、--platform,因为 pip 默认按当前解释器和系统选择包。pip 文档说明这些选项默认会使用当前系统/解释器的值。(Pip)
4. 下载后在 Dockerfile 里离线安装
目录结构:
project/
├── Dockerfile
├── requirements.txt
└── wheels/
├── xxx.whl
├── yyy.whl
└── ...
Dockerfile:
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
COPY wheels/ /wheels/
RUN pip install --no-index --find-links=/wheels -r requirements.txt
--no-index 表示不访问 PyPI 或镜像源,只从本地 --find-links=/wheels 目录找包;pip 文档也说明 pip download 下载出的目录可以后续通过 pip install --find-links 用于离线或受限环境安装。(Pip)
5. 如果报 “No matching distribution found”
常见原因有三个:
第一,内网源里没有对应版本的 wheel 包。比如目标是 Python 3.10,但内网源只有 cp39 的包。
第二,平台写错了。比如目标镜像是 Alpine Linux,通常不是 manylinux2014_x86_64,而可能需要 musllinux_1_2_x86_64。如果是 ARM 服务器,需要类似:
--platform manylinux2014_aarch64
第三,某些包没有 wheel,只有源码包。你用了:
--only-binary=:all:
这种情况下 pip 会直接失败。解决方式是先在和目标镜像一致的环境里构建 wheel:
python -m pip wheel \
-r requirements.txt \
-w wheels/ \
-i http://pypi.company.com/simple \
--trusted-host pypi.company.com
然后 Docker 构建时再离线安装。
6. 推荐流程
公司内网环境建议这样做:
# 1. 明确目标镜像 Python 版本
docker run --rm python:3.10-slim python -V
# 2. 下载 Python 3.10 Linux x86_64 兼容 wheel
python -m pip download \
-r requirements.txt \
-d wheels/ \
-i http://pypi.company.com/simple \
--trusted-host pypi.company.com \
--only-binary=:all: \
--python-version 310 \
--implementation cp \
--abi cp310 \
--platform manylinux2014_x86_64
# 3. Dockerfile 里离线安装
如果你们基础镜像固定,比如 python:3.10-slim,最稳的是用同版本基础镜像起一个临时容器,在里面执行 pip download 或 pip wheel,这样下载出来的包和最终运行环境最一致。

浙公网安备 33010602011771号