链式自动构建在同一个Docker Hub存储库中

时间:2016-04-29 22:04:08

标签: heroku web-applications docker build-automation dockerhub

由于Docker Hub上的build time restrictions,我决定将耗时的自动构建的Dockerfile拆分为3个文件。 这些"子构建中的每一个"在Docker Hub的时间限制内完成。

我现在在同一个存储库中有以下设置:

| branch | dockerfile         | tag    |
| ------ | ------------------ | ------ |
| master | /step-1.Dockerfile | step-1 |
| master | /step-2.Dockerfile | step-2 |
| master | /step-3.Dockerfile | step-3 |

图像按以下顺序相互构建:

  • step-1.DockerfileFROM ubuntu
  • step-2.DockerfileFROM me/complex-image:step-1
  • step-3.DockerfileFROM me/complex-image:step-2

单独的网络应用使用"构建触发器"触发step-1的构建。 Docker Hub提供的URL。 (添加了{"docker_tag": "step-1"}'有效负载)但是,Docker Hub无法提供自动触发step-2然后step-3后缀的方法。

问:如何按照各自的顺序自动触发以下构建步骤?(即step-2完成后触发step-1。然后,触发step-3step-2完成后

注意:我不想为每个step-i设置单独的存储库,然后使用Docker Hub"存储库链接链接它们。" 我只是想在同一个回购中链接标签

注意:到目前为止,我的解决方案是将Docker Hub Webhook附加到我已经制作的网络应用程序中。当step-n完成后,(即使用包含标记名step-n的JSON调用我的网络应用的网址),网络应用会使用"构建触发器"触发step-n+1。它按预期工作,但是,我想知道是否有更好的"做事的方式。

编辑: As requested by Ken Cochrane以下是initial Dockerfile以及它使用的"build script"。我只是试图停靠Cling。 (一个C ++解释器)它需要编译llvm,clang和cling。正如您所料,根据机器的不同,它需要几个小时才能完成,而Docker Hub只允许使用#34;最多2小时构建:)" sub build"我后来添加的图像(仍然在develop分支中)构建了整个事物的一部分。我不确定这里还有进一步的优化。

另外,为了测试各种想法(并避免等待结果的h-hours),我设置了类似结构的another repo。 (唯一的区别是它的Dockerfile不做那么多工作)

Option 5上的

更新1::正如预期的那样,来自curl的{​​{1}}被忽略了:

step-1.Dockerfile

这种方法的另一个问题是它需要我将构建触发器(秘密)令牌放在Settings > Build Triggers > Last 10 Trigger Logs | Date/Time | IP Address | Status | Status Description | Request Body | Build Request | | ------------------------- | --------------- | ------- | ------------------------ | -------------------------- | ------------- | | April 30th, 2016, 1:18 am | <my.ip.v4.addr> | ignored | Ignored, build throttle. | {u'docker_tag': u'step-2'} | null | 中供所有人查看:)(希望Docker Hub可以选择使其无效并重新生成另一个)

更新2:以下是my current attempt: 它基本上是一个Heroku托管的应用,具有APScheduler周期性&#34;触发器&#34;这将启动初始构建步骤,以及一个Flask webhook处理程序,它将传播&#34;构建。 (即它具有有序的构建标记列表。每次webhook调用它时,它都会触发下一个构建步骤)我将在业余时间继续处理它。 (建议欢迎:))

4 个答案:

答案 0 :(得分:1)

构建需要多长时间?你可以发布你的Dockerfile吗?

选项1:了解自动构建需要花费多长时间,以了解为什么它没有及时完成。如果你在这里发布,我们可以看看你是否可以做任何优化。

选项2:您现在正在做什么,使用第三方应用程序按给定顺序触发构建。

选项3:我不确定这是否适合你,因为你使用相同的回购,但通常你会使用回购链接来获得这个功能,然后链接它们,当一个完成时,下一个一个触发第一个。但由于你有一个回购,它不会起作用。

选项4:将其分解为多个回购,然后您可以使用回购链接。

选项5:完全黑客,最后的手段(不确定它是否会起作用)。您可以在Dockerfile的最后一行添加CURL语句,以便在下一步中使用给定标记发布到repo的构建触发器链接。如果下一步需要一个标记,则可能需要在下一步中添加休眠以等待推送完成推送到集线器。

老实说,最好的选择1:你所做的事情应该能够在规定的时间内完成,你可能正在做一些我们可以优化的事情,以使整个事情变得更快。如果你在时间限制内进入,那么其他一切都是不需要的。

答案 1 :(得分:1)

最近对链依赖构建的要求相同,并且使用Docker Cloud自动构建以这种方式实现了它:

  • 为需要构建的每个Dockerfile创建一个包含构建规则的存储库。
  • 禁用相关存储库中所有构建规则的Autobuild选项。
  • 在包含hooks\post_push的每个目录中添加一个名为Dockerfile的shell脚本,该脚本具有依赖项,具有以下代码:

    for url in $(echo $BUILD_TRIGGERS | sed "s/,/ /g"); do
      curl -X POST -H "Content-Type: application/json" --data "{ \"build\": true, \"source_name\": \"$SOURCE_BRANCH\" }" $url
    done
    
  • 对于具有dependents的每个存储库,在自动构建中添加名为Build Environment Variable的{​​{1}},并将BUILD_TRIGGERS设置为每个依赖项的构建触发器URL的逗号分隔列表自动构建。

使用此设置,推送到 root 源存储库将触发 root 映像的构建,一旦完成并按下Value挂钩将被执行。在钩子中,对每个依赖的存储库构建触发器进行POST,其中包含在请求主体中构建的分支或标记的名称。这将导致依赖存储库的相应构建规则被触发。

答案 2 :(得分:0)

可以通过调整Docker Hub存储库中的Build Settings来实现此目的。

首先,为您的GitHub存储库/step-1.Dockerfile创建一个自动构建,标记为step-1。这个不需要任何特殊设置。

接下来,为您的GitHub存储库的/step-2.Dockerfile创建另一个自动构建,标记为step-2。在构建设置中,取消选中激活时,构建将在推送时自动发生。还要将存储库链接添加到me/step-1

step-3执行相同操作(将其链接到me/step-2)。

现在,当您推送到GitHub存储库时,它将触发第1步构建;当完成时,第2步将构建,之后,第3步将构建。

请注意,您需要等待上一个阶段成功构建一次,然后才能向其添加存储库链接。

答案 3 :(得分:0)

我只是尝试了另一个答案,但它们对我不起作用,所以我发明了另一种方法,通过为每个构建规则使用单独的分支来链接构建,例如:

master              # This is for docker image tagged base
docker-build-stage1 # tag stage1
docker-build-latest # tag latest
docker-build-dev    # tag dev

stage1依赖于base,latest依赖于stage1,dev依赖于最新。

在每个依赖项的post_push挂钩中,我使用自身的直接依赖项调用了以下脚本:

#!/bin/bash -x

git clone https://github.com/NobodyXu/llvm-toolchain.git
cd llvm-toolchain
git checkout ${1}
git merge --ff-only master

# Set up push.default for push
git config --local push.default simple

# Set up username and passwd
# About the credential, see my other answer:
#     https://stackoverflow.com/a/57532225/8375400
git config --local credential.helper store
echo "https://${GITHUB_ROBOT_USER}:${GITHUB_ROBOT_ACCESS_TOKEN}@github.com" > ~/.git-credentials

exec git push origin HEAD

变量GITHUB_ROBOT_USERGITHUB_ROBOT_ACCESS_TOKEN是在docker hub自动构建配置中设置的环境变量。

我个人更喜欢为此专门在github上注册一个启用2FA的新机器人帐户,邀请该机器人帐户成为协作者并使用访问令牌(而不是密码),因为比使用自己的帐户更安全可以访问远远超出需要的存储库,并且易于管理。

编辑:

您需要禁用存储库链接,否则Docker Hub中将出现很多意外的构建作业。

如果要查看此解决方案的演示,请选中NobodyXu/llvm-toolchain