Docker выполняет команду cp или mv в Dockerfile, но изменения не отображаются на изображении
Я довольно новичок в программировании и докере. Я столкнулся с такой проблемой, на которую я не смог найти ответ.
Я создал свой собственный образ докера без проблем, а затем я хотел использовать это изображение в качестве основы для дальнейших изменений. Поэтому я создал свой Dockerfile, который выглядит следующим образом (см. Ниже), и когда я использую sudo docker build -t my-name. он выполняется без проблем, однако когда я запускаю образ (sudo docker run -it my-name / bin / bash), я не вижу изменений в списке каталогов (каталог / root / new_files / не существует).
Кажется, я думаю, что это каким-то образом заполнило мою первую сборку, на которой основан мой этот образ, как я делал эти команды много раз раньше без проблем.
Любой совет, что могло послужить причиной запуска программы Docker, но изменений не видно на самом изображении.
Мой файл 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 не помогло. Ниже приведен базовый образ Docker file:
Базовый образ Docker file:
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 ответа
Непосредственной причиной ваших проблем является то, что, как только вы объявляете каталог VOLUME
в Dockerfile вы никогда больше не сможете вносить изменения в это дерево каталогов. В частности, поскольку ваш базовый образ Dockerfile заканчивается на
VOLUME /root
потом пару шагов спустя
FROM plu_build_1:latest # inherits that VOLUME
RUN cp -a /root/TEMPLATE/ /root/DEMO/
не работает, потому что ничего в /root
может быть когда-либо изменен когда-либо снова
Очень короткий ответ здесь никогда не ставить VOLUME
в Dockerfile вообще. Это может иметь смысл для таких вещей, как серверы баз данных, которые имеют единственное дерево каталогов, которое вы почти всегда хотите пережить одним контейнером, если можете, но это исключение, и у него есть некоторые запутанные побочные эффекты (как этот).
Если посмотреть на этот Dockerfile более широко, он выглядит как полноценная среда разработки, а не как автономное многократно используемое изображение. (Он содержит два сетевых сервера, два стека компиляторов и третью интерпретируемую языковую среду выполнения и интерактивную оболочку вне основного потока; он старается изо всех сил настраивать точечные файлы обеих оболочек, когда многие типичные пути Docker не запускают оболочек В общем, он содержит легко извлекаемый ключ ssh, который дает права доступа к чему-либо.) Вы можете подумать, лучше ли вам подходит стек, построенный на Vagrant, полноценной виртуальной машине и более модульной системе управления конфигурацией, такой как Ansible. Пытаюсь построить.
Это связано с командами кэширования контейнера при сборке. Когда файл dockerfile не изменился, он фактически не будет выполнять действия, так как предполагается, что каждая команда будет иметь тот же результат, что и предыдущий запуск (но он будет перезапускать любую строку, которая была изменена
Например, если cp -a $BASEDIR/TEMPLATE/ $BASEDIR/DEMO/
был изменен на cp -ar $BASEDIR/TEMPLATE/ $BASEDIR/DEMO/
например, он будет запускать эту команду и каждую строку после того, как кеш теперь недействителен.
Если вы хотите обновить образ докера с вашими последними изменениями, вам нужно будет выполнить сборку докера с опцией --no-cache, например, так.
docker build --no-cache my-name .