Docker выполняет команду cp или mv в Dockerfile, но изменения не отображаются на изображении - PullRequest
0 голосов
/ 09 января 2019

Я довольно новичок в программировании и докере. Я сталкивался с такой проблемой, на которую не мог найти ответ.

Я создал свой собственный образ докера без проблем, а затем я хотел использовать это изображение в качестве своей базы для дальнейших изменений. Поэтому я создал свой Dockerfile, который выглядит следующим образом (см. Ниже), и когда я использую sudo docker build -t my-name. он запускается без проблем, однако когда я запускаю образ (sudo docker run -it my-name / bin / bash), я не вижу изменений в списке каталогов (каталог / root / new_files / не существует).

Мне кажется, что это как-то связано с моей первой сборкой, на которой основан мой этот образ, как я делал эти команды много раз раньше без проблем.

Любой совет, что могло послужить причиной запуска программы Docker, но изменения не видны на самом изображении.

Файл My Docker:

FROM plu_build_1:latest

ENV BASEDIR=/root

WORKDIR /root

RUN cp -a $BASEDIR/TEMPLATE/ $BASEDIR/DEMO/

COPY DEMO/parameters.DEMO $BASEDIR/DEMO/

COPY DEMO/config.DEMO $BASEDIR/DEMO/

ENV PATH="${BASEDIR}/bin:${PATH}"

VOLUME ["/root/DEMO/LOG/"]
CMD ["bash"]

Хочу заметить, что вместо cp -a я попробовал команду 'mv' ... безуспешно также кажется, что создание ссылок с помощью 'ln' не работает.

Однако, если после сборки я ввожу образ и запускаю ту же команду внутри запущенного образа, он работает нормально, это означает, что я могу запустить 'cp -a $ BASEDIR / TEMPLATE / $ BASEDIR / DEMO /' и это работает.

Итак, --no-cache не помог. Ниже находится базовый образ Dockerfile:

базовый образ Dockerfile:

FROM fedora:25
RUN yum -y update \
  && yum -y install file gcc gcc-gfortran gcc-c++ glibc.i686 libgcc.i686 libpng-devel jasper jasper-devel hostname m4 make perl \ 
  tar tcsh time wget which zlib zlib-devel openssh-clients openssh-server net-tools \
  netcdf-fortran libpng15 iproute-tc tcp_wrappers-libs sendmail procmail psmisc procps-ng mailx  findutils ImageMagick \
  perl-CPAN ncl netcdf libpng libjpeg-turbo which patch vim less bzip2 \
  && yum clean all

RUN yum -y install netcdf-openmpi-devel.x86_64 netcdf-fortran-openmpi-devel.x86_64 netcdf-fortran-openmpi.x86_64 hdf5-openmpi.x86_64 openmpi.x86_64 openmpi-devel.x86_64 \
  && yum clean all

COPY files.tgz /root
COPY files-bin.tgz /root
COPY rings.tgz /root
# extract all and link all files

RUN tar -xvzf files.tgz \
&& tar -xvzf files-bin.tgz \
&& tar -xvzf rings.tgz \
&& rm files*.tgz \
&& rm rings.tgz 

WORKDIR /root/bin
COPY prog-cmake-linux.tar /root/bin
COPY files-cmake-linux.tar /root/bin
RUN tar xf prog-cmake-linux.tar \
 && tar xf files-cmake-linux.tar \
 && rm prog-cmake* \
 && rm files-cmake* \
 && rm -rdf /root/bin/test/ \
 && rm -rdf /root/bin/main/ \
 && rm -rdf /root/bin/*grid/ \
 && mkdir /wrf/netcdf_links \
 && ln -sf /usr/lib64/openmpi/lib /root/netcdf_links/lib \
 && ln -sf /usr/include/openmpi-x86_64 /root/netcdf_links/include 

RUN (echo y;echo o conf prerequisites_policy follow;echo o conf commit) | cpan   && cpan install Proc/Background.pm \
  && ln -s libnetcdff.so.6 /lib64/libnetcdff.so.5 \
  && ln -s libnetcdf.so.11 /lib64/libnetcdf.so.7

RUN echo export LDFLAGS="-lm" >> /etc/bashrc \
 && echo export NETCDF=/root/netcdf_links >> /etc/bashrc \
 && echo export JASPERINC=/usr/include/jasper/ >> /etc/bashrc \
 && echo export JASPERLIB=/usr/lib64/ >> /etc/bashrc \
 && echo export LD_LIBRARY_PATH="/usr/lib64/openmpi/lib" >> /etc/bashrc \
 && echo export PATH="/usr/lib64/openmpi/bin:$PATH" >> /etc/bashrc \
 && echo setenv LDFLAGS "-lm" >> /etc/csh.cshrc \
 && echo setenv NETCDF "/root/netcdf_links" >> /etc/csh.cshrc \
 && echo setenv JASPERINC "/usr/include/jasper/" >> /etc/csh.cshrc \
 && echo setenv JASPERLIB "/usr/lib64/" >> /etc/csh.cshrc \
 && echo setenv LD_LIBRARY_PATH "/usr/lib64/openmpi/lib" >> /etc/csh.cshrc \
 && echo setenv PATH "/usr/lib64/openmpi/bin:$PATH" >> /etc/csh.cshrc \
 && echo export BASEDIR=$BASEDIR >> /etc/bashrc \
 && echo export PATH+=:\$BASEDIR/bin >> /etc/bashrc

ENV LD_LIBRARY_PATH /usr/lib64/openmpi/lib
ENV PATH  /usr/lib64/openmpi/bin:$PATH

# set up ssh configuration
COPY ssh_config /root/.ssh/config
RUN mkdir -p /root/.openmpi
COPY default-mca-params.conf /root/.openmpi/mca-params.conf

RUN mkdir -p /var/run/sshd \
    && ssh-keygen -A \
    && sed -i 's/#PermitRootLogin yes/PermitRootLogin yes/g' /etc/ssh/sshd_config \
    && sed -i 's/#RSAAuthentication yes/RSAAuthentication yes/g' /etc/ssh/sshd_config \
    && sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/g' /etc/ssh/sshd_config \
    && ssh-keygen -f /root/.ssh/id_rsa -t rsa -N '' \
    && chmod 600 /root/.ssh/config \
    && chmod 700 /root/.ssh \
    && cp /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys
#
WORKDIR /root
VOLUME /root

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Непосредственной причиной ваших проблем является то, что, объявив каталог VOLUME в Dockerfile, вы больше никогда не сможете вносить изменения в это дерево каталогов. В частности, поскольку ваш базовый образ Dockerfile заканчивается на

VOLUME /root

затем пару шагов спустя

FROM plu_build_1:latest  # inherits that VOLUME
RUN cp -a /root/TEMPLATE/ /root/DEMO/

- запрет, потому что ничто в /root никогда не может быть изменено.

Очень короткий ответ здесь: никогда не помещать VOLUME в Dockerfile. Это может иметь смысл для таких вещей, как серверы баз данных, которые имеют единственное дерево каталогов, которое вы почти всегда хотите пережить одним контейнером, если можете, но это исключение, и у него есть некоторые запутанные побочные эффекты (как этот).

Если посмотреть на этот Dockerfile более широко, он выглядит как полноценная среда разработки, а не как автономное многократно используемое изображение. (Он содержит два сетевых сервера, два стека компиляторов и третью интерпретируемую языковую среду выполнения и интерактивную оболочку, не входящую в мейнстрим; он старается изо всех сил настроить оба shell-файла точек, когда многие типичные пути Docker вообще не содержат оболочек, он содержит легко извлекаемый ключ ssh, который дает права доступа к чему-либо root.) Вы можете подумать, является ли стек, построенный на Vagrant , полноценной виртуальной машиной и более модульной Система управления конфигурацией, такая как Ansible лучше подходит для того, что вы пытаетесь построить.

0 голосов
/ 09 января 2019

Это связано с командами кэширования контейнера при сборке. Когда файл dockerfile не изменился, он фактически не будет выполнять действия, так как предполагается, что каждая команда будет иметь тот же результат, что и предыдущий запуск (но он будет перезапускать любую строку, которая была изменена

Например, если cp -a $BASEDIR/TEMPLATE/ $BASEDIR/DEMO/ было изменено, например, на cp -ar $BASEDIR/TEMPLATE/ $BASEDIR/DEMO/, он будет запускать эту команду и каждую строку после того, как кеш теперь будет недействительным.

Если вы хотите обновить образ докера с вашими последними изменениями, вам нужно будет выполнить сборку докера с опцией --no-cache, например так.

 docker build --no-cache my-name .
...