C++ 应用程序应该在 GitLab CI Docker 工作流中的什么地方编译?
Where should c++ application be compiled in GitLab CI Docker workflow?
我想了解如何正确构建我的 .gitlab-ci.yml 和 Docker 文件,以便我可以将 C++ 应用程序构建到 Docker 容器中。
我正在纠结 C++ 应用程序的实际编译和 link 应该在 CI 工作流程中的什么地方进行。
我做了什么:
- 我目前的方法是在 Docker 中使用 Docker 和私有 gitlab 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 。
docker 文件然后复制在我的构建步骤中生成的最终二进制文件。
完成所有这些后,我觉得不太合适,我想知道我是否错过了意图。我试图在网上找到一个 C++ 示例作为示例,但没有成功。
我没有完全理解的是每个播放器在 docker-in-docker 设置中的作用:docker 图像,dind 图像,最后是容器 I正在生产……
我想知道的……
- 谁应该执行构建并包含构建环境,我的 .gitlab-ci.yml 或我的 Docker 文件中指定的基础映像?
- 如果我使用 docker 文件构建,如何将源代码的内容放入 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
这两种方法同样有效。如果您查看其他 SO 问题,您可能会注意到的一件事是 Java/Docker 图像几乎普遍在其主机上构建一个 jar 文件,然后 COPY
将其放入图像中,但是 Go/Docker图像倾向于使用来自来源的多阶段Docker文件tar。
如果您已经拥有相当成熟的构建系统并且您的开发人员已经拥有非常一致的设置,那么在 CI 环境中(在您的 .gitlab.yml
文件中)做更多的工作是有意义的。以您已经采用的相同方式构建您的应用程序,然后 COPY
将它变成一个最小的 Docker 图像。如果您需要运送 Docker 和非 Docker 工件,此方法也很有用。如果你有一个 make dist
风格的 tar 文件并想从中得到一个 Docker 图像,你可以使用一个非常简单的 Docker 文件,比如
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 图像,那么集中大部分内容可能是有意义的Docker 文件中的内容。这样做的好处是每个开发人员都可以在本地 运行 自己的确切构建顺序,而不是依赖 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"]
如果您在 Docker 文件中进行主要构建,则需要 COPY
源代码。在序列的这一点上,卷安装不起作用。 CI 系统在任何情况下都应避免将源代码绑定安装到容器中:您希望 运行 针对您构建的实际工件进行测试,而不是构建的混合体 Docker图像,但替换了所有源代码。
我想了解如何正确构建我的 .gitlab-ci.yml 和 Docker 文件,以便我可以将 C++ 应用程序构建到 Docker 容器中。
我正在纠结 C++ 应用程序的实际编译和 link 应该在 CI 工作流程中的什么地方进行。
我做了什么:
- 我目前的方法是在 Docker 中使用 Docker 和私有 gitlab 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 。 docker 文件然后复制在我的构建步骤中生成的最终二进制文件。
完成所有这些后,我觉得不太合适,我想知道我是否错过了意图。我试图在网上找到一个 C++ 示例作为示例,但没有成功。
我没有完全理解的是每个播放器在 docker-in-docker 设置中的作用:docker 图像,dind 图像,最后是容器 I正在生产……
我想知道的……
- 谁应该执行构建并包含构建环境,我的 .gitlab-ci.yml 或我的 Docker 文件中指定的基础映像?
- 如果我使用 docker 文件构建,如何将源代码的内容放入 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
这两种方法同样有效。如果您查看其他 SO 问题,您可能会注意到的一件事是 Java/Docker 图像几乎普遍在其主机上构建一个 jar 文件,然后 COPY
将其放入图像中,但是 Go/Docker图像倾向于使用来自来源的多阶段Docker文件tar。
如果您已经拥有相当成熟的构建系统并且您的开发人员已经拥有非常一致的设置,那么在 CI 环境中(在您的 .gitlab.yml
文件中)做更多的工作是有意义的。以您已经采用的相同方式构建您的应用程序,然后 COPY
将它变成一个最小的 Docker 图像。如果您需要运送 Docker 和非 Docker 工件,此方法也很有用。如果你有一个 make dist
风格的 tar 文件并想从中得到一个 Docker 图像,你可以使用一个非常简单的 Docker 文件,比如
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 图像,那么集中大部分内容可能是有意义的Docker 文件中的内容。这样做的好处是每个开发人员都可以在本地 运行 自己的确切构建顺序,而不是依赖 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"]
如果您在 Docker 文件中进行主要构建,则需要 COPY
源代码。在序列的这一点上,卷安装不起作用。 CI 系统在任何情况下都应避免将源代码绑定安装到容器中:您希望 运行 针对您构建的实际工件进行测试,而不是构建的混合体 Docker图像,但替换了所有源代码。