我正在构建一个用C ++编写的服务器,并希望使用带有docker-compose的Docker来部署它。这样做的“正确方法”是什么?我应该从Dockerfile调用make
还是手动构建,从Dockerfile上传到某个服务器然后上传COPY
个二进制文件?
答案 0 :(得分:19)
我在使用docker-compose
自动构建时遇到了困难,最后我使用了docker build
来处理所有内容:
构建三层
运行→开发→构建
然后我将构建输出复制到' deploy'图像:
运行→部署
可以使用四层:
跑FROM <projname>:run
FROM <projname>:develop
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作为有关如何构建/运行/安装项目的文档。
如果构建失败并且输出不足以进行调查,我可以在/bin/bash
中运行<projname>:build
并查看错误。
我把这个想法放在一起a GitHub repository。它适用于C ++,但您可以将它用于任何事情。
答案 1 :(得分:6)
我的建议是完全开发,构建和测试容器本身。这确保了Docker的理念,即开发人员的环境与生产环境相同,请参阅 The Modern Developer Workstation on MacOS with Docker 。
特别是在C ++应用程序中,通常存在与共享库/目标文件的依赖关系。
我不认为在Docker上开发,测试和部署C ++应用程序存在标准化的开发过程。
要回答您的问题,我们现在的处理方式是将容器视为您的开发环境,并在团队中执行一系列实践,例如:
docker diff
更改符合预期。答案 2 :(得分:5)
我这样做的方法是在容器外部运行构建,只将构建的输出(二进制文件和任何必需的库)复制到容器中。然后,您可以将容器上载到容器注册表(例如,使用托管的容器或运行自己的容器),然后从该注册表中提取到生产计算机上。因此,流程可能如下所示:
由于您在生产部署之前进行测试非常重要,因此您希望测试与生产中部署完全相同的内容,因此您不希望以任何方式提取或修改Docker镜像建成之后。
我不会在您计划在prod中部署的容器中运行内部的,因为那时您的容器将具有各种其他工件(例如临时构建输出,工具等)您不需要在生产中使用您未能用于部署的内容来不必要地增加容器图像。
答案 3 :(得分:2)
虽然其他答案中提出的解决方案-特别是Misha Brukman在对this answer的评论中关于使用一个Dockerfile进行开发而将一个Dockerfile进行生产的建议-在当时被认为是惯用的写下问题后,应该注意的是,他们正在尝试解决的问题-尤其是清理构建环境以减小映像大小,同时仍然能够在开发和生产中使用相同的容器环境的问题-有效地被Docker 17.05中引入的 multi-stage builds 解决。
这里的想法是将Dockerfile分为两个部分,一个基于您最喜欢的开发环境,例如成熟的Debian基本映像,该映像与创建要在Windows上部署的二进制文件有关。结束时,另一个仅在最小的环境(例如Alpine)中运行构建的二进制文件。
通过这种方式,您可以避免开发环境和生产环境之间可能存在的差异,如蓝皮书在评论中提到的那样,同时仍确保您的生产映像不会被开发工具污染。
该文档提供了以下Go应用程序多阶段构建示例,您将随后将其应用于C ++开发环境(一个陷阱是Alpine使用musl,因此在使用时必须小心在您的开发环境中进行链接)。
FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]