如何在多阶段Docker构建中设置netCDF4包?

0 投票
1 回答
41 浏览
提问于 2025-04-14 18:36

我有一个现成的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

这里是图片描述

你能提供更多信息吗?这样我可以更好地复现这个问题。

撰写回答