如何将代码从Git更新到Docker容器
我有一个Docker文件试图将Django代码部署到一个容器
FROM ubuntu:latest MAINTAINER { myname } #RUN echo "deb http://archive.ubuntu.com/ubuntu/ $(lsb_release -sc) main universe" >> /etc/apt/sou$ RUN apt-get update RUN DEBIAN_FRONTEND=noninteractive apt-get install -y tar git curl dialog wget net-tools nano buil$ RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python python-dev python-distribute python-p$ RUN mkdir /opt/app WORKDIR /opt/app #Pull Code RUN git clone git@bitbucket.org/{user}/{repo} RUN pip install -r website/requirements.txt #EXPOSE = ["8000"] CMD python website/manage.py runserver 0.0.0.0:8000
然后我构build我的代码作为docker build -t dockerhubaccount/demo:v1 .
,这将我的代码从Bitbucket拉到容器。 我运行它作为docker run -p 8000:8080 -td felixcheruiyot/demo:v1
和东西似乎工作正常。
现在我想更新代码,即因为我使用git clone ...
,我有这个困惑:
- 当我有新的提交时,并且在Docker容器使用新的代码构build它时,我怎样才能更新我的代码(注意:当我运行构build时,它不会因为caching而获取它)。
- 什么是这种方法的最佳工作stream程?
有几种方法可以使用。
- 您可以使用
docker build --no-cache
来避免使用Git克隆的caching。 - 启动命令调用
git pull
。 所以不是运行python manage.py
,而是使用CMD cd /repo && git pull && python manage.py
或者在事情更复杂的情况下使用启动脚本。
我倾向于更喜欢2.你也可以运行一个cron工作来更新你的容器中的代码,但是这是一个更多的工作,有点违背了Docker的理念。
我build议你在主机上签出代码并COPY
到图像中。 这样,每当你做出改变,它都会被更新。 而且,在开发过程中,您可以将源目录绑定到容器中的代码目录上,这意味着任何更改都会立即反映在容器中。
虽然git仓库的docker命令检查最后一次更新将是非常有用的!
解决scheme
只要指令string与caching图像完全相同,Docker构build命令就会使用caching。 所以,如果你写
RUN echo '2014122400' >/dev/null && git pull ...
在下次更新时,您更改如下。
RUN echo '2014122501' >/dev/null && git pull ...
这可以防止docker使用caching。
我想提供另一个可能的解决scheme。 然而,我需要警告的是,这绝对不是做事的“docker方式”,而是依赖于卷的存在(这可能是像Docker Swarm和Kubernetes这样的工具的潜在阻碍者)
我们将要利用的基本原则是用作Docker卷的容器目录的内容实际上存储在主机的文件系统中。 看看这部分的文档。
在你的情况下,你会/opt/app
Docker卷。 您不需要将卷明确映射到主机文件系统上的某个位置,因为如下所述,可以dynamic获取映射。
因此,对于初学者,将Dockerfile完全保持原样,并将您的容器创build命令切换为如下所示:
docker run -p 8000:8080 -v /opt/app --name some-name -td felixcheruiyot/demo:v1
命令docker inspect -f {{index .Volumes "/opt/webapp"}} some-name
将会在代码存储的主机上打印完整的文件系统path( 这是我拿起检查技巧的地方)。
有了这些知识,你所要做的就是replace那些代码和你所有的东西。 所以一个非常简单的部署脚本就像这样:
code_path=$(docker inspect -f {{index .Volumes "/opt/webapp"}} some-name) rm -rfv $code_path/* cd $code_path git clone git@bitbucket.org/{user}/{repo}
你用这种方法得到的好处是:
- 没有潜在的昂贵的无caching图像重build
- 不需要将应用程序特定的运行信息移动到运行命令中。 Dockerfile是检测应用程序所需的唯一来源
UPDATE
您可以使用docker cp (启动Docker 1.8)来达到上述相同的结果。 通过这种方式,容器不需要卷,并且可以像在主机文件系统上那样replace容器中的代码。
当然,正如我在回答开头所提到的,这不是“做事的泊坞子”,它主张容器是不变的,可重复的。
如果使用GitHub,则可以使用GitHub API不caching特定的RUN命令。
你需要安装jq来parsingJSON: apt-get install -y jq
例:
docker build --build-arg SHA=$(curl -s 'https://api.github.com/repos/Tencent/mars/commits' | jq -r '.[0].sha') -t imageName .
在Dockerfile中(ARG命令应该在RUN之前):
ARG SHA=LATEST RUN SHA=${SHA} \ git clone https://github.com/Tencent/mars.git
或者如果你不想安装jq:
SHA=$(curl -s 'https://api.github.com/repos/Tencent/mars/commits' | grep sha | head -1)
如果一个仓库有新的提交, git clone
将被执行。