如何在多阶段Docker构建中设置netCDF4包?
我有一个现成的dockerfile,它运行一个涉及netCDF4的python程序。下面是一个简化版:
ARG BASE_IMG=python:3.11-slim
ARG VENV="/opt/venv"
# ------------------------------ #
FROM $BASE_IMG
ARG VENV
RUN apt-get update && \
apt-get upgrade && \
apt-get install -y python3-dev libhdf5-dev libnetcdf-dev
RUN python -m venv $VENV
ENV PATH="$VENV/bin:$PATH"
RUN pip install numpy~=1.23.5 netcdf4~=1.6.4 h5py~=3.9.0
COPY test.py test.py
ENTRYPOINT ["python", "-m", "test"]
我的完整dockerfile还涉及一些c++的编译,我想把它改成多阶段构建,这样编译工具就不会出现在我的最终镜像里。在这个过程中,我还想在编译阶段使用pip install
安装我的python包,然后把整个虚拟环境转移到最终阶段,像这样:
ARG BASE_IMG=python:3.11-slim
ARG VENV="/opt/venv"
FROM $BASE_IMG as compile-image
ARG VENV
RUN apt-get update && \
apt-get upgrade && \
apt-get install -y python3-dev libhdf5-dev libnetcdf-dev
RUN python -m venv $VENV
ENV PATH="$VENV/bin:$PATH"
RUN pip install numpy~=1.23.5 netcdf4~=1.6.4 h5py~=3.9.0
# ------------------------------ #
FROM $BASE_IMG
ARG VENV
RUN apt-get update && \
apt-get upgrade && \
apt-get install -y libhdf5-dev libnetcdf-dev
COPY --from=compile-image $VENV $VENV
ENV PATH="$VENV/bin:$PATH"
COPY test.py test.py
ENTRYPOINT ["python", "-m", "test"]
这样做效果很好,但是通过这种方式复制netCDF4包似乎导致netcdf的读写操作变得很慢。我可以做一个和上面完全一样的Dockerfile,只是在最终阶段直接安装netCDF4,这样就不会出现这种慢的问题。所以我在想,netCDF4包可能使用了某种外部的c库,我也需要把它复制过去。有没有人知道怎么判断netCDF4是否正确链接了它的所有库,或者我具体需要复制哪些东西才能让它正常工作?
1 个回答
1
这里使用了一个测试文件 test_echam_spectral-deflated.nc。我不太清楚你是怎么处理这些数据的,但我的测试脚本会从这个 .nc
文件中加载所有变量:
test.py
import time
import numpy as np
from netCDF4 import Dataset
netcdf_file_path = '/data/test_echam_spectral-deflated.nc'
start_time = time.time()
dataset = Dataset(netcdf_file_path, mode='r')
for var in dataset.variables:
np.array(dataset.variables[var][:])
end_time = time.time()
elapsed_time = end_time - start_time
print(f"Time taken to load the NetCDF file: {elapsed_time} seconds")
dataset.close()
这些数据是通过一个卷挂载的方式与一个容器共享的。
我没有发现加载时间有明显的差别。下面是你的第一个 Dockerfile
:
这是第二个多阶段的 Dockerfile
。
你能提供更多信息吗?这样我可以更好地复现这个问题。