Я хотел бы создать докер-контейнер, который по умолчанию использует определенную версию компилятора:
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?
🚨 О работе 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
После того как вы создали приложение, нужны ли вам еще компиляторы? Можете ли вы
RUN make install
, а затем использовать многоэтапную сборку, чтобыCOPY
превратить встроенное приложение в окончательный образ без использования набора инструментов?