在GitLab CI Docker工作流程中应在哪里编译c ++应用程序?

时间:2019-12-29 23:25:51

标签: c++ docker gitlab gitlab-ci-runner dind

我想了解如何正确构造.gitlab-ci.yml和Dockerfile,以便可以将C ++应用程序构建到Docker容器中。

我正在为应该在CI工作流程中进行C ++应用程序的实际编译和链接而苦恼。

我所做的事情:

  • 我目前的做法是在带有私有gitlab docker注册表的Docker中使用Docker。
  • 我的gitlab-ci.yml使用我基于docker:19.03.1-dind映像创建的Dind docker映像服务,但包含用于安全地与我的私人gitlab docker注册表进行通信的证书。
  • 我也有一个我的gitlab-ci.yml基于docker:19.03.1引用的自定义基础映像,其中包括构建所需的内容,例如cmake,build-base mariadb-dev等。
  • 已将我的构建脚本添加到gitlab-ci.yml中,以构建应用程序cmake…&& cmake --build。 然后,dockerfile复制在我的构建步骤中生成的最终二进制文件。

完成所有这些操作后,我感觉不对劲,我想知道我是否错过了这个意图。我试图在网上找到一个C ++示例作为示例,但没有成功。

我不完全了解的是docker-in-docker设置中每个玩家的角色:docker镜像,dind镜像,最后是我正在生产的容器…

我想知道的...

  • 谁应该执行构建并包含构建环境,.gitlab-ci.yml或Dockerfile中指定的基本映像?
  • 如果我使用dockerfile进行构建,如何将源内容放入docker容器?我是否复制/ builds目录?我应该挂载吗?
  • 在哪里划分谁执行工作,gitlab-ci.yml或Docker文件?
  • 参考使用Docker-in-Docker Gitlab CI构建的C ++ docker应用程序的工作示例。

.gitlab-ci.yml

image: $CI_REGISTRY/building-blocks/dev-mysql-cpp:latest
#image: docker:19.03.1

services:
  - name: $CI_REGISTRY/building-blocks/my-dind:latest
    alias: docker

stages:
  - build
  - release

variables:
  # Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
  DOCKER_TLS_CERTDIR: "/certs"
  CONTAINER_TEST_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
  CONTAINER_RELEASE_IMAGE: $CI_REGISTRY_IMAGE:latest

before_script:
        - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY

build:
  stage: build
  script:
    - mkdir build

1 个答案:

答案 0 :(得分:0)

两种方法都同样有效。如果您查看其他SO问题,您可能会注意到一件事,即Java / Docker映像几乎普遍在其主机上构建jar文件,然后COPY将其转换为映像,但是Go / Docker映像倾向于使用一个从源头开始的多阶段Dockerfile。

如果您已经具有相当成熟的构建系统,并且开发人员已经具有非常一致的设置,则有必要在CI环境(在您的.gitlab.yml文件中)中进行更多工作。以与您以前相同的方式构建应用程序,然后COPY使其成为最小的Docker映像。如果您需要同时运送Docker和非Docker工件,则此方法也很有用。如果您有一个make dist样式的tar文件,并且想从中获取Docker映像,则可以使用一个非常简单的Dockerfile,例如

FROM ubuntu
RUN apt-get update && apt-get install ...
ADD dist/myapp.tar.gz /usr/local  # unpacking it
EXPOSE 12345
CMD ["myapp"]                     # /usr/local/bin/myapp

另一方面,如果您的开发人员具有各种桌面环境,并且您实际上是在尝试标准化东西,而您只需要交付Docker映像,则可以将大部分内容集中在Dockerfile中。这样做的好处是,每个开发人员都可以自己在本地运行确切的构建顺序,而不必依靠CI系统来尝试简单的更改。围绕GNU Autoconf构建的东西可能看起来更像

FROM ubuntu AS build
RUN apt-get update \
 && apt-get install --no-install-recommends --assume-yes \
      build-essential \
      lib...-dev
WORKDIR /app
COPY . .
RUN ./configure --prefix=/usr/local \
 && make \
 && make install

FROM ubuntu
RUN apt-get update \
 && apt-get install --no-install-recommends --assume-yes \
      lib...
COPY --from=build /usr/local /usr/local
CMD ["myapp"]

如果您在Dockerfile中进行主要构建,则需要在其中COPY插入源代码。在此刻,卷装载在此时不起作用。 CI系统在任何情况下都应避免将源代码绑定安装到容器中:您要针对已构建的实际工件运行测试,而不是构建的Docker映像的混合体,而是替换了其所有源代码。