docker debian

构建Debian软件包并不总是很有趣。 如果您曾经尝试将某些软件转换为.deb软件包,则可能是由于大量可用的构建工具和文件格式而感到不知所措,或者是为了满足软件包的所有依赖关系而弄乱了系统。 有很多事情可以而且最初会出错。

幸运的是,自动化和虚拟化的正确组合可以带来很大的不同。 在本文中,我将告诉您我在Jimdo开发的Debian软件包构建系统背后的故事,该系统解决了我们多年来面临的许多难题 。

包装制造的黑暗时代

当我2013年开始在Jimdo工作时,我们在构建Debian软件包时遇到了自己的问题。 从第一天开始,我们就依靠Debian操作系统为服务器供电。 Debian本身已经带有成千上万的可安装软件包。 但是,如果捆绑的软件已过时,我们仍然需要自己重新编译较新的版本。 此外,我们也希望将自己的工具作为.deb文件分发。 因此,能够构建和维护Debian软件包对我们一直很重要。

为了那时可以创建软件包,工程师必须登录一个专用的构建服务器,恰当地命名为buildhost02,然后以特殊的“ buildmaster”用户身份运行几个Shell命令。 这个过程有几个缺点:通常很难弄清楚是构建了特定的软件包,或者为什么要首先构建它。 最糟糕的是,有时我们不知道如何创建软件包。 除了松散的shell脚本集合外,没有统一的方法来创建软件包,更不用说它们来源的默认位置了。

问题列表清楚地表明,此构建系统不会永远持续下去。 我们的构建服务器buildhost02很难理解和修改,并且设置具有相同功能的另一台服务器非常麻烦(尽管其名称以“ 02”结尾,如果出现问题,则没有其他服务器)。 此外,由于构建通常涉及安装多个依赖项,因此随着时间的流逝,主机越来越受到污染。 综上所述,buildhost02是所谓的独特雪花 。

包装2.0

2014年5月,我有机会开始致力于我们所谓的“包装2.0”里程碑。 里程碑的目标是根据我们过去的经验开发一个新的更好的构建系统。 后来,该项目被称为buildbox

使用buildbox时,软件包构建应该是:

  • 自动化的。 工程师应该能够通过在本地计算机上运行单个命令来构建用于分发Y的软件包X。
  • 记录下来。 很明显,如何以及为什么要构建软件包以及由谁来维护它。
  • 可重复的。 应该有可能复制软件包的每个内部版本。
  • 简单。 工程师,或者实际上任何人,都应该能够建造这座建筑。

为了完成里程碑,我们同意,我不仅必须使用buildbox重建所有100多个自定义Debian软件包(此过程需要大量的逆向工程),而且我还必须重新部署每个软件包以确保所有内容仍然如预期般运作。

输入buildtasks gem

在打包软件方面,没有一种千篇一律的工具可以支持每种编程语言。

在Jimdo,我们使用多种语言,最主要的是PHP,Python,Ruby和Go。 每种语言都有自己的包装标准和工具(这很可悲)。 结果,在很多地方都可以找到构建说明,例如Makefile, debian/rules文件,shell脚本等,它们通常取决于事先安装的其他软件。

这种多样性代表了我必须尽早解决的挑战。 我知道必须支持不同的构建机制将需要某种形式的抽象。

这就是buildtasks库的形式。 Buildtasks是一个Rubygem,它允许您通过一组Rake任务来构建Debian软件包。 目前,它支持两种构建方式:

  • git-buildpackage
  • fpm-cookery

前者是构建已经带有debian/目录的软件包的理想选择(就像所有Debian上游软件包一样)。 后者对于从各种尚未“去Debian化”的代码轻松创建包很有用。 在Jimdo,我们大量使用这两种方法。

buildtasks gem提供了一个方便的Ruby DSL,以抽象出包构建中涉及的实际步骤。 这是一个示例Rakefile利用了gem对git-buildpackage的支持:

# Rakefile
require "buildtasks"BuildTasks::GitBuildpackage.define do name "periodicnoise" version "debian/1.1" source "https://github.com/Jimdo/periodicnoise"
end

该Ruby代码将自动生成一些Rake任务,以为给定项目periodicnoise创建一个Debian软件包。 您可以通过以下方式列出任务:

$ rake -T
rake build    # Build packages
rake clean    # Remove any temporary products
rake clobber  # Remove any generated file
rake clone    # Clone Git repository and checkout version
rake deps     # Install build dependencies
rake patch    # Apply any patches
rake publish  # Publish built packages

完成这些任务后,下面是触发程序包构建的方法:

$ rake build publish PUBLISH_DIR=/some/path

在后台,buildtasks库将从GitHub克隆定义的Git存储库,签出指定的版本(debian / 1.1),安装debian/control列出的所有构建依赖项,最后调用git-buildpackage来构建软件包。 然后,将包复制到PUBLISH_DIR环境变量指定的目录中。 所有这些复杂性对用户都是隐藏的,用户的工作是为Rakefile提供适当的属性。

但是buildtasks不仅抽象出了构建步骤,而且还提供了一个通用接口。 不管您选择哪种构建机制(git-buildpackage或fpm-cookery或将来添加的其他工具),生成的Rake任务将始终包括两个易于理解且对人和机器自动化的操作: buildpublish 。 实际上,您不一定需要构建任务来满足此接口。 您也可以提供自己的具有相同名称的Rake任务。

Buildtasks是开源的。 您可以通过gem install buildtasks安装它,并阅读GitHub上的完整文档。

Docker的隔离构建

尽管buildtasks提供了创建Debian软件包的逻辑,但它只是buildbox的一个组成部分,尽管很重要。 另一个至关重要的部分是用于建筑的环境。 最重要的是,需要隔离此环境-最少安装目标OS,并尽可能减少预装的软件包。 (特定于程序包的构建依赖项应在实际构建过程中安装,而不是在此之前安装。只有这样,您才会发现损坏或丢失的依赖项。)

由于这些原因,将构建任务与某种形式的服务器虚拟化配对是一个好主意。 虚拟机是一次性的,通常可以在数分钟内完成配置。 更重要的是,它们提供了一个干净的隔离环境,非常适合构建包装。

当我实现buildbox的第一个版本时,我决定将Vagrant与VirtualBox一起使用。 随着时间的流逝,很明显,VM并不是最适合我们的需求。

当我最终决定尝试Docker时,我意识到了这一点。 无需等待几分钟就可以使新的VM投入使用(我们使用Puppet来配置基本的VirtualBox VM),可以立即通知Docker容器。 甚至更好:对于每个构建,都保证环境是原始的。 我们不再需要采用丑陋的解决方法,例如重用现有的VM并在内部版本之间共享依赖关系,以加快整个过程。 Docker是缺少的一环,它使我们能够以可预测和可复制的方式快速构建软件包。

演示:使用Docker Compose

我们配备了buildtasks gem,并且我们知道Docker是适合当前任务的正确技术。 现在,我们要做的就是将两者结合起来。 接下来的演示向您展示了如何使用Docker Compose实现这一目标。 Compose是用于描述,构建和运行Docker应用程序的有用工具。 它专为管理多容器应用程序而设计,但是与单个容器(如我们将在演示中使用的容器)一样,可以很好地工作。

首先,我们需要编写一个Dockerfile定义用于包构建的环境。 请记住,我们努力将预装软件减少到最少。 因此,我们将仅将buildtasks gem与git-buildpackage和fpm-cookery以及其他一些必需的依赖项一起安装。 为了这个演示的目的,我们的Docker映像将基于Docker Hub上官方“ debian”存储库中的debian:jessie映像。 通常,您应该使用要为其构建软件包的操作系统的映像。

这是最终的Dockerfile

# Dockerfile
FROM debian:jessieENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && apt-get install -y \ build-essential \ curl \ devscripts \ equivs \ git-buildpackage \ git \ lsb-release \ make \ openssh-client \ pristine-tar \ rake \ rsync \ ruby \ ruby-dev \ rubygems \ wgetRUN echo "gem: --no-ri --no-rdoc" >/etc/gemrc
RUN gem install fpm -v 1.4.0
RUN gem install fpm-cookery -v 0.29.0
RUN gem install buildtasks -v 0.0.1
RUN gem install bundler -v 1.10.0

下一步,我们创建一个名为docker-compose.yml的文件,该文件告诉Compose该做什么。 该文件如下所示:

# docker-compose.yml
demo: build: . command: rake build publish PUBLISH_DIR=/pkg volumes: - .:/data - pkg:/pkg working_dir: /data

最后但并非最不重要的一点是,我们需要一个带有构建指令的Rakefile 。 为了简单起见,我们将使用我之前向您展示的一种用于周期噪声的方法:

# Rakefile
require "buildtasks"BuildTasks::GitBuildpackage.define do name "periodicnoise" version "debian/1.1" source "https://github.com/Jimdo/periodicnoise"
end

有了这三个文件,我们最终可以指示Compose构建并运行我们的演示容器应用程序。 这个过程实质上可以归结为创建Docker映像,然后根据该映像在容器内执行rake build publish 。 通过使用两个数据量,我们确保当前Rakefile在容器内(位于/data/Rakefile/data/Rakefile ,并且所有构建的软件包最终位于主机系统上的pkg/

这是Compose的输出:

$ docker-compose build
Building demo...
...
Successfully built a5d21c6f8085$ docker-compose run demo
git clone https://github.com/Jimdo/periodicnoise git-debian-1.1
...
cd git-debian-1.1
git checkout -qf debian/1.1
...
DEBIAN_FRONTEND=noninteractive mk-build-deps -i -r -t 'apt-get -y' debian/control
...
git-buildpackage --git-ignore-branch --git-ignore-new --git-builder=debuild -i.git -I.git -uc -us -b
...
dpkg-deb: building package `periodicnoise' in`../periodicnoise_1.1_amd64.deb'.
...
mkdir -p /pkg
cp periodicnoise_1.1_amd64.deb /pkg

之后,我们可以验证该软件包是否已成功构建并保存到我们的本地pkg/文件夹中:

$ ls -1 pkg/
periodicnoise_1.1_amd64.deb

如果您想自己尝试,可以在此处找到该演示的源代码。

结论

在本文中,我向您展示了buildbox的两个主要组成部分-Jimdo的Debian软件包构建系统-以及如何将它们一起使用:有一个buildtasks gem,它可以自动化并抽象化构建步骤,还有Docker ,它提供了一个隔离的环境立即可用于构建。

Buildbox本身还不是开源的,但实际上它是一个Git存储库,其中包含Dockerfile,Rakefile和Makefile的集合,以及将所有内容粘合在一起的shell脚本。 使用buildbox时,工程师只需一个命令即可为Debian发行版Y生成项目X的软件包,而仅需一条命令即可将结果推送到我们的内部Debian软件包存储库。

我希望阅读完本文后,您也能够开发出使打包构建更有趣的东西。 该技术已经存在-准备好好使用。

翻译自: https://www.javacodegeeks.com/2015/08/using-docker-to-build-debian-packages.html

docker debian

docker debian_使用Docker构建Debian软件包相关推荐

  1. 使用Docker构建Debian软件包

    构建Debian软件包并不总是很有趣. 如果您曾经尝试将某些软件转换为.deb软件包,那么您可能会因大量可用的构建工具和文件格式不知所措,或者是为了满足软件包的所有依赖性而弄乱了系统. 有很多事情可能 ...

  2. iso镜像添加软件包_超薄Docker容器-减少Docker镜像大小的指南

    Photo by William Warby on Unsplash 您是否曾经想过为什么您的单应用程序Docker容器会增长到400 MB? 或者,也许为什么一个只有几十MB的应用程序二进制文件会生 ...

  3. Docker最全总结,DockerFile,Docker编排容器,Docker镜像,Docker-compose构建

    文章目录 Docker 简介 为什么使用docker: Docker引擎: Docker系统镜像: Docker容器: Docker仓库: ubuntu安装docker: ubuntu脚本自动安装: ...

  4. Docker构建YApi镜像, Docker安装YApi, Docker部署YApi

    目录 概述 基本环境 docker网络 安装MongoDb 构建YAPI镜像 运行YAPI Nginx反向代理 挂域名 概述 YApi 是高效.易用.功能强大的 api 管理平台,旨在为开发.产品.测 ...

  5. x86 下制作 ARM Docker 镜像,Docker Hub、Travis 自动构建 qemu-user-static

    一般情况下,Docker 的镜像都是在一个已有的镜像内,一步步运行给定的命令,从而生成一个新的镜像.这样的步骤在大多数人使用的 x86 架构计算机上都不是问题,由于架构互相兼容,一台计算机上生成的镜像 ...

  6. 【实战演练】两种方法让 Docker 帮您快速构建应用程序

    写在前面 在这篇文章中,Deni Bertovic将向我们展示如何使用Docker来快速构建Haskell应用程序并生成Docker镜像. 备注: Haskell 是一种标准化的,通用的纯函数编程语言 ...

  7. Jenkins+docker+maven+git自动化构建与部署

    2019独角兽企业重金招聘Python工程师标准>>> 公司项目需要,本地提供代码管理+git+jenkins+maven环境,通过SSH发布到docker服务器进行部署 持续集成的 ...

  8. jenkins pipeline api获取stage的详细信息_Jenkins + Docker 助力 Serverless 应用构建与部署...

    本文来源: ServerlessLife 公众号 近日,使用 Serverless 开发了一个应用.其中 CI/CD,是需要考虑的一个问题.这里用到了 Jenkins 和 Docker.并且 Jenk ...

  9. Docker教程(四) Docker镜像构建

    Docker教程(四) Docker镜像构建 本文链接:https://blog.csdn.net/yuan_xw/article/details/77744272 Docker教程(四) Docke ...

最新文章

  1. linux(centos) 常用命令
  2. 将DLINK无线AP加入到公司网络
  3. 《VMware Virtual SAN权威指南》一3.10.3 缓存设备与容量设备的比率
  4. 实训项目1-熟练使用VMware安装Windows server 2012
  5. 利用python爬取_在知乎上利用Python爬取了三百万数据!服务器崩了!企业级大项目...
  6. 小程序设计避免犯什么错_新设计师犯下的5种印刷错误以及如何避免
  7. Minimum spanning tree HDU - 6954
  8. MySQL锁系列3 MDL锁
  9. Convirt 2.0 更新到 2.1版本
  10. 任务一:实现图形计算功能 1 关键算法(30 分)输入一个正方体的边长(a)计算正方体的体积。要求:结果保留两位小数,使用带参数的方法实现
  11. Linux7 下Hadoop集群用户管理方案之五 安装Hadoop集群遇到的坑
  12. 【上海房价预测】代码实现——利用BP神经网络进行上海二手房价预测
  13. Python数据分析之Matplotlib-I
  14. elang 字符处理
  15. mv150us无线网卡驱动linux,水星mw150us无线网卡驱动官方下载-v90最新版
  16. 知识普及:HTML 5到底是个什么东西
  17. 100个python算法超详细讲解:存钱
  18. win10下安装cuda和cudnn
  19. 2023年中高级前端养成指南-需要关注和学习的13大类80余个前端技术栈与前端趋势-看这篇就够了系列
  20. puking java_GitHub - pukingli/mpsdk4j: JAVA微信公平台开发SDK,没有复杂的功能,一切源于微信API,愿你会喜欢使用。...

热门文章

  1. python每条语句以什么结尾_Python程序设计中一行可以写____条语句,每条语句以____结束。...
  2. Cannot read properties of undefined (reading ‘parentNode‘)
  3. 在keil工程中删除编译文件的方法
  4. 高并发大流量情况下带来的海量数据分库分表的正确姿势
  5. 【CicadaPlayer】ScaleMode
  6. 三种函数指针的表达以及函数指针概念讲解
  7. ACdream 1210 Chinese Girls' Amusement
  8. Windows通过使用命令行(CACLS)修改文件权限
  9. Mysql错误1452 - Cannot add or update a child row: a foreign key constraint fails 原因及解决方法
  10. 性能测试,压力测试,负载测试的区别与联系