创建具有特定编译器版本的 docker 容器需要将 update-alternatives 添加为 Dockerfile 的最后一行

问题描述 投票:0回答:1

我想创建一个默认使用特定编译器版本的 docker 容器:

ARG UBUNTU_VERSION=20.04
FROM ubuntu:${UBUNTU_VERSION}

ARG COMPILER_VERSION=10
ARG PETSC_VERSION=v3.18.6

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y software-properties-common
RUN add-apt-repository ppa:ubuntu-toolchain-r/test
RUN apt-get update
RUN apt-get install -y gcc-${COMPILER_VERSION} g++-${COMPILER_VERSION} gfortran-${COMPILER_VERSION}

RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${COMPILER_VERSION} 60 && \
    update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${COMPILER_VERSION} 60 && \
    update-alternatives --install /usr/bin/gfortran gfortran /usr/bin/gfortran-${COMPILER_VERSION} 60

RUN apt-get install -y build-essential git python3 openssh-server openssh-client python3-pip ffmpeg libsm6 libxext6 cmake pkg-config \
                       openmpi-bin libopenmpi-dev

RUN python3 -m pip install pytest numpy h5py pathlib requests pandas matplotlib plotly scikit-learn PyYAML Pillow vtk types-PyYAML pytest-cov

RUN echo "Using PETSC_VERSION: ${PETSC_VERSION}"
RUN git clone -b ${PETSC_VERSION} https://gitlab.com/petsc/petsc.git /petsc && \
    cd /petsc && \
    ./configure \
        PETSC_ARCH=linux-gnu \
        --with-fc=gfortran --with-cc=gcc --with-cxx=g++ \
        --with-fortran-bindings \
        --download-openmpi \
        --with-mpi-f90module-visibility=1 \
        --download-fftw \
        --download-hdf5 \
        --download-hdf5-fortran-bindings \
        --download-fblaslapack \
        --download-scalapack \
        --download-ml \
        --download-zlib && \
    make all

ENV PETSC_DIR /petsc
ENV PETSC_ARCH linux-gnu

ENV OMPI_ALLOW_RUN_AS_ROOT 1
ENV OMPI_ALLOW_RUN_AS_ROOT_CONFIRM 1

RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${COMPILER_VERSION} 60 && \
    update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${COMPILER_VERSION} 60 && \
    update-alternatives --install /usr/bin/gfortran gfortran /usr/bin/gfortran-${COMPILER_VERSION} 60

这工作得很好,当我们以交互方式运行容器时,它会默认选择正确的编译器版本。但是,我们必须为此目的使用相同的

update-alternatives
,一次确保我们的其他包使用正确的编译器安装,最后再次确保容器中执行的任何内容都使用指定的版本出色地。如果我们省略最后一部分,则将使用原来存在的编译器。为什么会发生这种情况?我们是否有更有效的方法来设计 Dockerfile?

docker dockerfile
1个回答
0
投票

🚨工作

Dockerfile
请参阅答案末尾。以下是我到达那里的一些原因。

我想你会发现你实际上并没有使用 GCC 10 来编译 PETSc 代码。

尝试在克隆和构建 PETSc 存储库之前立即插入

RUN gcc --version
。我想你会发现你看到这样的东西:

Step 13/13 : RUN gcc --version
 ---> Running in dc6e2b3c0095
gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

这意味着,尽管您之前设置了编译器的替代版本,但它仍然会恢复为默认编译器。为什么?

其原因是后续

apt-get install
中的某些内容正在恢复编译器更改。如果你将操作顺序更改为这个,那么当你编译 PETSc 时,你会发现 GCC 10 已经生效了。

RUN apt-get install -y build-essential git python3 openssh-server openssh-client python3-pip ffmpeg libsm6 libxext6 cmake pkg-config \
                       openmpi-bin libopenmpi-dev

RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${COMPILER_VERSION} 60 && \
    update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${COMPILER_VERSION} 60 && \
    update-alternatives --install /usr/bin/gfortran gfortran /usr/bin/gfortran-${COMPILER_VERSION} 60

现在您应该在克隆/编译步骤之前看到这一点:

Step 13/13 : RUN gcc --version
 ---> Running in 77abf17d52bc
gcc (Ubuntu 10.5.0-1ubuntu1~20.04) 10.5.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

但现在遇到了一个障碍:PETSc 构建中存在错误。它更喜欢默认编译器版本!

我的建议是简单地删除第一组

update-alternatives
命令,因为它们对后续构建没有任何影响。

无论如何,这是一个完整的

Dockerfile
,它应该可以做你想做的事情而不会重复。我必须安装更新的
CMake

ARG UBUNTU_VERSION=20.04
FROM ubuntu:${UBUNTU_VERSION}

ARG COMPILER_VERSION=10
ARG PETSC_VERSION=v3.18.6

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && \
    apt-get install -y \
        software-properties-common \
        gnupg \
        wget \
        lsb-release
RUN add-apt-repository ppa:ubuntu-toolchain-r/test

# For recent CMake version.
#
RUN wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc | gpg --dearmor - | tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null
RUN echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/kitware.list

RUN apt-get update
RUN apt-get install -y \
        gcc-${COMPILER_VERSION} \
        g++-${COMPILER_VERSION} \
        gfortran-${COMPILER_VERSION} \
        build-essential \
        git \
        python3 \
        openssh-server \
        openssh-client \
        python3-pip \
        ffmpeg \
        libsm6 \
        libxext6 \
        cmake \
        pkg-config \
        openmpi-bin \
        libopenmpi-dev

RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${COMPILER_VERSION} 60 && \
    update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${COMPILER_VERSION} 60 && \
    update-alternatives --install /usr/bin/gfortran gfortran /usr/bin/gfortran-${COMPILER_VERSION} 60

RUN python3 -m pip install pytest numpy h5py pathlib requests pandas matplotlib plotly scikit-learn PyYAML Pillow vtk types-PyYAML pytest-cov

RUN echo "Using PETSC_VERSION: ${PETSC_VERSION}"
RUN git clone -b ${PETSC_VERSION} https://gitlab.com/petsc/petsc.git /petsc && \
    cd /petsc && \
    ./configure \
        PETSC_ARCH=linux-gnu \
        --with-fc=gfortran --with-cc=gcc --with-cxx=g++ \
        --with-fortran-bindings \
        --download-openmpi \
        --with-mpi-f90module-visibility=1 \
        --download-fftw \
        --download-hdf5 \
        --download-hdf5-fortran-bindings \
        --download-fblaslapack \
        --download-scalapack \
        --download-ml \
        --download-zlib && \
    make all

ENV PETSC_DIR /petsc
ENV PETSC_ARCH linux-gnu

ENV OMPI_ALLOW_RUN_AS_ROOT 1
ENV OMPI_ALLOW_RUN_AS_ROOT_CONFIRM 1
© www.soinside.com 2019 - 2024. All rights reserved.