Docker RUN不保存文件 [英] Docker RUN does NOT persist files

查看:476
本文介绍了Docker RUN不保存文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我的Docker文件是这样的:

  FROM jenkins:latest 

RUN echofoo> / var / jenkins_home / toto; ls -alh / var / jenkins_home
RUN ls -alh / var / jenkins_home

RUN rm /var/jenkins_home/.bash_logout; ls -alh / var / jenkins_home
RUN ls -alh / var / jenkins_home

RUN echobar>> /var/jenkins_home/.profile; cat /var/jenkins_home/.profile
RUN cat /var/jenkins_home/.profile

这里是输出:

 将构建上下文发送到Docker守护程序373.8 kB步骤1:FROM jenkins:latest ---> fc39417bd5fb步骤2:RUN echofoo> / var / jenkins_home / toto; ls -alh / var / jenkins_home --->使用缓存
---> c614b13d9d83步骤3:运行ls -alh / var / jenkins_home --->使用缓存---> 8a16a0c92f67步骤4:运行rm /var/jenkins_home/.bash_logout; ls -alh / var / jenkins_home --->使用缓存---> f6ca5d5bdc64步骤5:运行ls -alh / var / jenkins_home
--->使用缓存---> 3372c3275b1b步骤6:RUN echobar>> /var/jenkins_home/.profile; cat /var/jenkins_home/.profile --->运行在79842be2c6e3
#〜/ .profile:由命令解释器执行登录shell。
#如果〜/ .bash_profile或〜/ .bash_login
#存在,则此文件不会被bash(1)读取。
#看到/ usr / share / doc / bash / examples / startup-files的例子。
#文件位于bash-doc包中。

#默认的umask设置在/ etc / profile中;要为ssh登录设置umask
#,请安装和配置libpam-umask包。
#umask 022

#如果运行bash,如果[-n$ BASH_VERSION];那么
#include .bashrc如果它存在
如果[-f$ HOME / .bashrc];然后 。 $ HOME / .bashrc
fi fi

#设置PATH,所以如果[-d$ HOME / bin];如果存在,它包含用户的私有bin;然后
PATH =$ HOME / bin:$ PATHfi bar ---> 28559b8fe041删除中间容器79842be2c6e3步骤7:运行cat /var/jenkins_home/.profile --->运行在c694e0cb5866
#〜/ .profile:由命令解释程序执行登录shell。
#如果〜/ .bash_profile或〜/ .bash_login
#存在,则此文件不会被bash(1)读取。
#看到/ usr / share / doc / bash / examples / startup-files的例子。
#文件位于bash-doc包中。

#默认的umask设置在/ etc / profile中;要为ssh登录设置umask
#,请安装和配置libpam-umask包。
#umask 022

#如果运行bash,如果[-n$ BASH_VERSION];那么
#include .bashrc如果它存在
如果[-f$ HOME / .bashrc];然后 。 $ HOME / .bashrc
fi fi

#设置PATH,所以如果[-d$ HOME / bin];如果存在,它包含用户的私有bin;然后
PATH =$ HOME / bin:$ PATHfi ---> b7e47d65d65e删除中间容器c694e0cb5866成功构建b7e47d65d65e

你们知道为什么foo文件不会持久存在步骤3?为什么在第5步上重新创建.bash_logout文件?为什么bar不在第7步中的.profile文件中?



当然,如果我根据这个图像启动一个容器,我的修改是持久的...所以我的Dockerfile是无用的。任何线索?

解决方案

这些更改不会持续存在的原因是,它们位于 Jenkins Docker文件标记 / var / jenkins_home / 作为 VOLUME



卷内的信息在 docker build ,或更精确地;每个构建步骤基于图像的内容创建一个新的卷,丢弃在上一个构建步骤中使用的卷。



如何解决这个问题?



我认为解决这个问题的最好办法就是:




  • 在图像内的其他位置添加要修改的文件,例如: jenkins_home / var / jenkins_home_overrides /

  • 根据或wrap创建一个自定义入口点,默认的entrypoint脚本复制您的 jenkins_home_overrides的内容 jenkins_home 首次启动集装箱。



其实...



只要我写了这个;看起来像官方的詹金斯图像已经支持这个开箱即用;
https://github.com/jenkinsci/docker /blob/683b0d6ed17016ee3211f247304ef2f265102c2b/jenkins.sh#L5-L23



根据文档,您需要将文件添加到 / usr / share / jenkins / ref / 目录,那些将在启动时被复制到 / var / jenkins / home



另见 https://issues.jenkins-ci.org/browse/JENKINS-24986


I have a problem with Docker which does not persist commands launch via "RUN".

Here is my Dockerfile :

FROM jenkins:latest

RUN echo "foo" > /var/jenkins_home/toto ; ls -alh  /var/jenkins_home
RUN ls -alh  /var/jenkins_home

RUN rm /var/jenkins_home/.bash_logout  ; ls -alh  /var/jenkins_home
RUN ls -alh  /var/jenkins_home

RUN echo "bar" >> /var/jenkins_home/.profile ; cat /var/jenkins_home/.profile
RUN  cat /var/jenkins_home/.profile

And here is the output :

Sending build context to Docker daemon 373.8 kB Step 1 : FROM jenkins:latest  ---> fc39417bd5fb Step 2 : RUN echo "foo" > /var/jenkins_home/toto ; ls -alh  /var/jenkins_home  ---> Using cache 
---> c614b13d9d83 Step 3 : RUN ls -alh  /var/jenkins_home  ---> Using cache  ---> 8a16a0c92f67 Step 4 : RUN rm /var/jenkins_home/.bash_logout  ; ls -alh  /var/jenkins_home  ---> Using cache  ---> f6ca5d5bdc64 Step 5 : RUN ls -alh  /var/jenkins_home
---> Using cache  ---> 3372c3275b1b Step 6 : RUN echo "bar" >> /var/jenkins_home/.profile ; cat /var/jenkins_home/.profile  ---> Running in 79842be2c6e3
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.

# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022

# if running bash if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then     . "$HOME/.bashrc"
    fi fi

# set PATH so it includes user's private bin if it exists if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH" fi bar  ---> 28559b8fe041 Removing intermediate container 79842be2c6e3 Step 7 : RUN cat /var/jenkins_home/.profile  ---> Running in c694e0cb5866
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.

# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022

# if running bash if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then     . "$HOME/.bashrc"
    fi fi

# set PATH so it includes user's private bin if it exists if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH" fi  ---> b7e47d65d65e Removing intermediate container c694e0cb5866 Successfully built b7e47d65d65e

Do you guys know why "foo" file is not persisted on step 3? Why ".bash_logout" file is recreated on step 5? Why "bar" is not in my ".profile" file anymore on step 7?

And of course, if I start a container based on this image, none of my modifications are persisted... so my Dockerfile is... useless. Any clue?

解决方案

The reason those changes are not persisted, is that they are inside a volume the Jenkins Dockerfile marks /var/jenkins_home/ as a VOLUME.

Information inside volumes is not persisted during docker build, or more precisely; each build-step creates a new volume based on the image's content, discarding the volume that was used in the previous build step.

How to resolve this?

I think the best way to resolve this, is to;

  • Add the files you want to modify inside jenkins_home in a different location inside the image, e.g. /var/jenkins_home_overrides/
  • Create a custom entrypoint based on, or "wrapping", the default entrypoint script that copies the content of your jenkins_home_overrides to jenkins_home the first time the container is started.

Actually...

And just when I wrote that up; It looks like the official Jenkins image already support this out of the box; https://github.com/jenkinsci/docker/blob/683b0d6ed17016ee3211f247304ef2f265102c2b/jenkins.sh#L5-L23

According to the documentation, you need to add your files to the /usr/share/jenkins/ref/ directory, and those will be copied to /var/jenkins/home upon start.

Also see https://issues.jenkins-ci.org/browse/JENKINS-24986

这篇关于Docker RUN不保存文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆