2015-12-29 68 views
4

我正在构建一个用C++编写的服务器,并且想用Docker与docker-compose一起部署它。做这件事的“正确方法”是什么?我应该从Dockerfile调用make还是手动构建,上传到某个服务器,然后从Dockerfile中上传COPY二进制文件?用Docker构建一个已编译的应用程序

+0

无论哪种方式都应该工作,我更喜欢你的第一个选项 – user2915097

+2

但是你会在生产机器上有开发文件(例如'-dev'包)。那是...呃...不是很好,呃? –

+0

不,您可以构建,然后清理并只保留容器中的可执行文件。 – user2915097

回答

6

我会这样做的方式是在你的容器外部运行你的构建,并只将构建的输出(你的二进制文件和任何必要的库)复制到你的容器中。然后,您可以将容器上传到容器注册表(例如,使用托管的容器或自己运行),然后从该注册表中将其拉到生产机器上。因此,流动看起来是这样的:

  1. 编译二进制
  2. 测试/理智,检查二进制本身
  3. 建集装箱二进制
  4. 测试/理智,检查容器图像图像与二进制
  5. 上传到容器注册表
  6. 部署到staging/test/qa,从注册表中取出
  7. 部署督促,从

因为它是重要的,你之前的生产部署测试,要测试的正是你会在生产中部署相同的事情注册表拉,所以你不想提取或者在构建之后以任何方式修改Docker镜像。

我不会跑构建你计划在督促部署容器,因为那么你的容器将有更多的文物各种(如临时生成输出,工具等),你不需要进行生产并且不必要地增加容器映像,而不使用部署的东西。

+6

该解决方案与Docker理念不完全一致。这可能导致相同的老问题“哦,但它在我的机器上工作”。除非C++应用程序很少或没有依赖关系,并且不依赖共享对象文件(.so文件),否则此解决方案将导致链接不正确版本的依赖关系 - blueskin 49分钟前 – blueskin

+1

@blueskin - 感谢您提供此信息。我也想过这个;我认为一种解决方案是使用两个容器:一个用于构建,一个卷映射到将输出导出到主机,第二个容器用于部署没有任何构建工件或临时文件,但只包含最终构建输出。思考? –

5

我的建议是完全开发,构建和测试容器本身。这确保了Docker的理念,即开发人员的环境与生产环境相同https://blog.newrelic.com/2016/06/20/docker-osx-mac/ 尤其是,在C++应用程序中,通常与共享库/对象文件存在依赖关系。

我不认为在Docker上有开发,测试和部署C++应用程序的标准化开发过程。 要回答你的问题,我们这样做是因为现在是这样,对待容器作为开发环境和执行一套做法对球队这样的:

  1. 我们的代码库(除了配置文件)总是生活共享卷(本地机器上)(版本上GIT)上
  2. 共享/依赖库和二进制文件等... 总是活容器
  3. 生成&测试上容器和提交所述图像清洁不希望的物体上之前文件,库等...并确保docker diff的变化如预期的那样
  4. 更改/更新环境(包括共享库),依赖性始终记录在案并与团队沟通。
6

我有困难docker-compose自动化我们的构建我结束了使用docker build的一切:

建设

运行

三层 - >开发 - >打造

然后我将构建输出复制到'部署'映像中

运行 - >部署

四层玩:

运行
  • 包含任何软件包需要为应用程序运行
    • 例如libsqlite3-0
发展
  • FROM <projname>:run
  • 包含了构建
    • 例如需要的软件包克++,cmake的,libsqlite3-dev的
  • Dockerfile执行任何外部构建
    • 例如步骤来建立升压python3(不包管理器回购的)
构建
  • FROM <projname>:develop
  • 包含源
  • Dockerfile执行内部版本(代码更改频繁)
  • 内置二进制文件被复制出该映像以供部署使用
部署构建
  • FROM <projname>:run
  • 输出复制到图像,并安装用于启动应用程序

文件夹结构

  • RUNENTRYPOINT看起来是这样的:

    . 
    ├── run 
    │   └── Dockerfile 
    ├── develop 
    │   └── Dockerfile 
    ├── build 
    │   ├── Dockerfile 
    │   └── removeOldImages.sh 
    └── deploy 
        ├── Dockerfile 
       └── pushImage.sh 
    

    设置构建服务器意味着执行:

    docker build -f run -t <projName>:run 
    docker build -f develop -t <projName>:develop 
    

    每次我们做一个构建,出现这种情况:

    # execute the build 
    docker build -f build -t <projName>:build 
    
    # install build outputs 
    docker build -f deploy -t <projName>:version 
    
    # if successful, push deploy image to dockerhub 
    docker tag <projName>:<version> <projName>:latest 
    docker push <projName>:<version> 
    docker push <projName>:latest 
    

    我是指人们对Dockerfiles为如何如果构建失败构建/运行/安装工程

    文档并且输出不足以进行调查,我可以在<projname>:build中运行/bin/bash并捅过来查看出了什么问题

  • +0

    看起来很酷。我很高兴看到你的Github回购以HelloWorld C++为例(所有4个docker文件和两个shell文件......)感谢分享。 – zipzit

    相关问题