如何将代码从 Git 更新到 Docker 容器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27529191/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 10:37:52  来源:igfitidea点击:

How to update code from Git to a Docker container

pythongitdeploymentcontinuous-integrationdocker

提问by Cheruiyot Felix

I have a Docker file trying to deploy Django code to a container

我有一个 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 [email protected]/{user}/{repo}

RUN pip install -r website/requirements.txt

#EXPOSE = ["8000"]
CMD python website/manage.py runserver 0.0.0.0:8000

And then I build my code as docker build -t dockerhubaccount/demo:v1 ., and this pulls my code from Bitbucket to the container. I run it as docker run -p 8000:8080 -td felixcheruiyot/demo:v1and things appear to work fine.

然后我将我的代码构建为docker build -t dockerhubaccount/demo:v1 .,这会将我的代码从 Bitbucket 拉到容器中。我运行它docker run -p 8000:8080 -td felixcheruiyot/demo:v1,事情似乎工作正常。

Now I want to update the code i.e since I used git clone ..., I have this confusion:

现在我想更新代码,即自从我使用以来git clone ...,我有这个困惑:

  • How can I update my code when I have new commits and upon Docker containers build it ships with the new code (note: when I run build it does not fetch it because of cache).
  • What is the best workflow for this kind of approach?
  • 当我有新的提交并且在 Docker 容器构建时我如何更新我的代码,它会随新代码一起提供(注意:当我运行构建时,它不会因为缓存而获取它)。
  • 这种方法的最佳工作流程是什么?

采纳答案by seanmcl

There are a couple of approaches you can use.

您可以使用几种方法。

  1. You can use docker build --no-cacheto avoid using the cache of the Git clone.
  2. The startup command calls git pull. So instead of running python manage.py, you'd have something like CMD cd /repo && git pull && python manage.pyor use a start script if things are more complex.
  1. 您可以使用docker build --no-cache避免使用 Git 克隆的缓存。
  2. 启动命令调用git pull. 因此python manage.pyCMD cd /repo && git pull && python manage.py如果事情更复杂,您将拥有类似或使用启动脚本的内容,而不是运行。

I tend to prefer 2. You can also run a cron job to update the code in your container, but that's a little more work and goes somewhat against the Docker philosophy.

我倾向于使用 2。您也可以运行 cron 作业来更新容器中的代码,但这需要做更多的工作,并且在某种程度上违背了 Docker 理念。

回答by Adrian Mouat

I would recommend you checkout out the code on your host and COPYit into the image. That way it will be updated whenever you make a change. Also, during development you can bind mount the source directory over the code directory in the container, meaning any changes are reflected immediately in the container.

我建议您签出主机上的代码并将COPY其放入图像中。这样,无论何时进行更改,它都会更新。此外,在开发过程中,您可以在容器中的代码目录上绑定挂载源目录,这意味着任何更改都会立即反映在容器中。

A docker command for git repositories that checks for the last update would be very useful though!

但是,用于检查上次更新的 git 存储库的 docker 命令将非常有用!

回答by takaomag

Another solution.

另一种解决方案。

Docker build command uses cache as long as a instruction string is exactly same as the one of cached image. So, if you write

只要指令字符串与缓存图像的指令字符串完全相同,Docker 构建命令就会使用缓存。所以,如果你写

RUN echo '2014122400' >/dev/null && git pull ...

On next update, you change as follows.

在下次更新时,您将更改如下。

RUN echo '2014122501' >/dev/null && git pull ...

This can prevents docker from using cache.

这可以防止 docker 使用缓存。

回答by geoand

I would like to offer another possible solution. I need to warn however that it's definitely not the "docker way" of doing things and relies on the existence of volumes (which could be a potential blocker in tools like Docker Swarm and Kubernetes)

我想提供另一种可能的解决方案。然而,我需要警告说,这绝对不是做事的“docker 方式”,而是依赖于卷的存在(这可能是 Docker Swarm 和 Kubernetes 等工具中的潜在障碍)

The basic principle that we will be taking advantage of is the fact that the contents of container directories that are used as Docker Volumes, are actually stored in the file system of the host. Check out thispart of the documentation.

我们将利用的基本原则是,用作 Docker Volumes 的容器目录的内容实际上存储在主机的文件系统中。查看文档的这一部分。

In your case you would make /opt/appa Docker Volume. You don't need to map the Volume explicitly to a location on the host's file-system since as a I will describe below, the mapping can be obtained dynamically.

在您的情况下,您将制作/opt/app一个 Docker 卷。您不需要将卷显式映射到主机文件系统上的某个位置,因为正如我将在下面描述的那样,可以动态获取映射。

So for starters leave your Dockerfile exactly as it is and switch your container creation command to something like:

所以对于初学者来说,让你的 Dockerfile 保持原样,并将你的容器创建命令切换为类似的内容:

docker run -p 8000:8080 -v /opt/app --name some-name -td felixcheruiyot/demo:v1

The command docker inspect -f {{index .Volumes "/opt/webapp"}} some-namewill print the full file system path on the host where your code is stored (thisis where I picked up the inspect trick).

该命令docker inspect -f {{index .Volumes "/opt/webapp"}} some-name将在存储代码的主机上打印完整的文件系统路径(是我使用检查技巧的地方)。

Armed with that knowledge all you have to do is replace that code and your all set. So a very simple deploy script would be something like:

有了这些知识,您所要做的就是替换该代码和所有设置。所以一个非常简单的部署脚本应该是这样的:

code_path=$(docker inspect -f {{index .Volumes "/opt/webapp"}} some-name)
rm -rfv $code_path/*
cd $code_path
git clone [email protected]/{user}/{repo}

The benefits you get with an approach like this are:

使用这样的方法可以获得的好处是:

  • There are no potentially costly cacheless image rebuilds
  • There is no need to move application specific running information into the run command. The Dockerfile is the only source of needed for instrumenting the application
  • 没有潜在的昂贵的无缓存图像重建
  • 无需将特定于应用程序的运行信息移动到运行命令中。Dockerfile 是检测应用程序所需的唯一来源

UPDATE

更新

You can achieve the same results I have mentioned above using docker cp(starting Docker 1.8). This way the container need not have volumes, and you can replace code in the container as you would on the host file-system.

您可以使用docker cp(从 Docker 1.8 开始)获得我上面提到的相同结果。这样容器就不需要有卷,您可以像在主机文件系统上一样替换容器中的代码。

Of course as I mentioned in the beginning of the answer, this is not the "docker way" of doing things, which advocates containers being immutable and reproducible.

当然,正如我在答案开头提到的,这不是“docker方式”的做事方式,它提倡容器是不可变的和可复制的。

回答by Michal Z m u d a

If you use GitHub you can use the GitHub API to not cache specific RUN commands.

如果您使用 GitHub,您可以使用 GitHub API 来不缓存特定的 RUN 命令。

You need to have jq installed to parse JSON: apt-get install -y jq

你需要安装 jq 来解析 JSON: apt-get install -y jq

Example:

例子:

docker build --build-arg SHA=$(curl -s 'https://api.github.com/repos/Tencent/mars/commits' | jq -r '.[0].sha') -t imageName .

In Dockerfile (ARG command should be right before RUN):

在 Dockerfile 中(ARG 命令应该在 RUN 之前):

ARG SHA=LATEST
RUN SHA=${SHA} \
    git clone https://github.com/Tencent/mars.git

Or if you don't want to install jq:

或者,如果您不想安装 jq:

SHA=$(curl -s 'https://api.github.com/repos/Tencent/mars/commits' | grep sha | head -1)

If a repository has new commits, git clonewill be executed.

如果存储库有新的提交,git clone将被执行。