Для создания Docker-контейнера с определенной версией компилятора необходимо добавить альтернативы обновления в последнюю строку Dockerfile

Я хотел бы создать докер-контейнер, который по умолчанию использует определенную версию компилятора:

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?

После того как вы создали приложение, нужны ли вам еще компиляторы? Можете ли вы RUN make install, а затем использовать многоэтапную сборку, чтобы COPY превратить встроенное приложение в окончательный образ без использования набора инструментов?

David Maze 30.04.2024 19:25
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
Как создать PHP Image с нуля
Как создать PHP Image с нуля
Сегодня мы создадим PHP Image from Scratch для того, чтобы легко развернуть базовые PHP-приложения. Пожалуйста, имейте в виду, что это разработка для...
0
1
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

🚨 О работе Dockerfile см. в конце ответа. Вот некоторые причины того, как я туда попал.

Я думаю, вы обнаружите, что на самом деле вы не используете GCC 10 для компиляции кода PETSc.

Попробуйте вставить RUN gcc --version непосредственно перед клонированием и сборкой репозитория PETSc. Я думаю, вы обнаружите, что видите что-то вроде этого:

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 отменяет изменения компилятора. Если вы измените порядок операций на этот, вы обнаружите, что GCC 10 действует, когда вы приступите к компиляции PETSc.

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

Другие вопросы по теме