我正在构建一个用C++编写的服务器,并且想用Docker与docker-compose一起部署它。做这件事的“正确方法”是什么?我应该从Dockerfile调用make
还是手动构建,上传到某个服务器,然后从Dockerfile中上传COPY
二进制文件?用Docker构建一个已编译的应用程序
回答
我会这样做的方式是在你的容器外部运行你的构建,并只将构建的输出(你的二进制文件和任何必要的库)复制到你的容器中。然后,您可以将容器上传到容器注册表(例如,使用托管的容器或自己运行),然后从该注册表中将其拉到生产机器上。因此,流动看起来是这样的:
- 编译二进制
- 测试/理智,检查二进制本身
- 建集装箱二进制
- 测试/理智,检查容器图像图像与二进制
- 上传到容器注册表
- 部署到staging/test/qa,从注册表中取出
- 部署督促,从
因为它是重要的,你之前的生产部署测试,要测试的正是你会在生产中部署相同的事情注册表拉,所以你不想提取或者在构建之后以任何方式修改Docker镜像。
我不会跑构建内你计划在督促部署容器,因为那么你的容器将有更多的文物各种(如临时生成输出,工具等),你不需要进行生产并且不必要地增加容器映像,而不使用部署的东西。
该解决方案与Docker理念不完全一致。这可能导致相同的老问题“哦,但它在我的机器上工作”。除非C++应用程序很少或没有依赖关系,并且不依赖共享对象文件(.so文件),否则此解决方案将导致链接不正确版本的依赖关系 - blueskin 49分钟前 – blueskin
@blueskin - 感谢您提供此信息。我也想过这个;我认为一种解决方案是使用两个容器:一个用于构建,一个卷映射到将输出导出到主机,第二个容器用于部署没有任何构建工件或临时文件,但只包含最终构建输出。思考? –
我的建议是完全开发,构建和测试容器本身。这确保了Docker的理念,即开发人员的环境与生产环境相同https://blog.newrelic.com/2016/06/20/docker-osx-mac/ 尤其是,在C++应用程序中,通常与共享库/对象文件存在依赖关系。
我不认为在Docker上有开发,测试和部署C++应用程序的标准化开发过程。 要回答你的问题,我们这样做是因为现在是这样,对待容器作为开发环境和执行一套做法对球队这样的:
- 我们的代码库(除了配置文件)总是生活共享卷(本地机器上)(版本上GIT)上
- 共享/依赖库和二进制文件等... 总是活容器
- 生成&测试上容器和提交所述图像清洁不希望的物体上之前文件,库等...并确保
docker diff
的变化如预期的那样 - 更改/更新环境(包括共享库),依赖性始终记录在案并与团队沟通。
我有困难docker-compose
自动化我们的构建我结束了使用docker build
的一切:
运行
三层 - >开发 - >打造
然后我将构建输出复制到'部署'映像中
运行 - >部署
四层玩:
运行- 包含任何软件包需要为应用程序运行
- 例如libsqlite3-0
FROM <projname>:run
- 包含了构建
- 例如需要的软件包克++,cmake的,libsqlite3-dev的
- Dockerfile执行任何外部构建
- 例如步骤来建立升压python3(不包管理器回购的)
FROM <projname>:develop
- 包含源
- Dockerfile执行内部版本(代码更改频繁)
- 内置二进制文件被复制出该映像以供部署使用
FROM <projname>:run
- 输出复制到图像,并安装用于启动应用程序
文件夹结构
RUN
或ENTRYPOINT
看起来是这样的: .
├── 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
并捅过来查看出了什么问题
看起来很酷。我很高兴看到你的Github回购以HelloWorld C++为例(所有4个docker文件和两个shell文件......)感谢分享。 – zipzit
- 1. 使用已编译的类文件创建一个新的Java应用程序
- 2. gitlab.com CI-在docker中使用docker构建NodeJS应用程序
- 3. 运行已编译的iPhone模拟器应用程序构建? (.app)没有Xcode?
- 4. 应用程序可以编译并创建另一个应用程序吗?
- 5. Docker构建的多个应用程序和插件?
- 6. 什么是iOS应用程序的编译/构建文件?
- 7. 构建Web应用程序编程
- 8. 构建一个picketlink应用程序
- 9. 构建一个playframework应用程序
- 10. 构建一个iPhone应用程序与
- 11. 将已编译的应用程序迁移到基于Web的应用程序
- 12. 构建Java编译/执行Web应用程序
- 13. 编译器/链接器错误,同时构建应用程序
- 14. 从工作导轨应用程序在线编译/构建ruby
- 15. LLVM编译器试图构建应用程序
- 16. 在C++应用程序中构建/编译libcurl问题
- 17. 如何构建/编译ndk应用程序?
- 18. 为iOS 4.2到iOS 6构建/编译应用程序?
- 19. 如何从APK编辑已编译的Android应用程序类
- 20. “使用Docker创建React应用程序”
- 21. 如何创建一个AngularJS应用程序的Docker容器?
- 22. 使用Docker构建应用程序堆栈
- 23. 如何使用docker构建多租户应用程序
- 24. 如何使用docker构建J2EE应用程序
- 25. 使用gradle构建docker play应用程序
- 26. 错误与编译Hello World程序Android应用程序的构建路径
- 27. 使用SBT本地打包程序构建的调试Docker应用程序
- 28. 构建应用程序时由Xcode编译的未使用的类是什么?
- 29. 在MATLAB中查找已编译的应用程序的路径
- 30. 已编译的应用程序中的Matlab网络浏览器
无论哪种方式都应该工作,我更喜欢你的第一个选项 – user2915097
但是你会在生产机器上有开发文件(例如'-dev'包)。那是...呃...不是很好,呃? –
不,您可以构建,然后清理并只保留容器中的可执行文件。 – user2915097