我的docker随笔30:C++程序的自动化构建
Posted 李迟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我的docker随笔30:C++程序的自动化构建相关的知识,希望对你有一定的参考价值。
本文描述一个 C++ 程序的自动化构建过程,涉及:
1、制作适用于 c++ 简单程序的基础镜像。
2、使用 CICD 进行编译和构建,并发布。在此过程,涉及到邮件通知。
本文示例在简单应用场合中有实践意义,即不使用如 jenkins 这样重型工具,如果信任现成免费的私有的服务,可将自动化工作迁移到公网,否则内建局域网服务或使用公有云搭建。
技术总结
- 下载原始镜像
- 在原始镜像的容器中,添加必要的文件,一般有链接器、动态库
- 重新制作镜像,提交远程仓库。
- 不同编译器,其依赖动态库,链接器不同,建议镜像的库,与宿主机一致。
- 注意:不同程序依赖的动态库不同,在宿主机上用
ldd
命令可查看详情。
制作镜像
下载原始镜像
注:源码为 C++,使用 C++11 特性,选 alpine,其 C 库不是 glibc。选 busybox 64版本。在 64 位系统直接执行:
docker pull busybox
即可得到 64 位的版本。
运行 busybox:
docker run --name -it bar busybox sh
拷贝文件
基于 ubuntu 1604 64bit制作。标的程序为:
ldd test
linux-vdso.so.1 => (0x00007ffe173f3000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f506d62a000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f506d2a8000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f506cf9e000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f506cd88000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f506c9be000)
/lib64/ld-linux-x86-64.so.2 (0x0000558004458000)
容器执行:
mkdir -p /lib64 /lib/x86_64-linux-gnu/ /usr/lib/gcc/x86_64-linux-gnu/5
date > /etc/version
宿主机执行:
docker cp /lib64/ld-linux-x86-64.so.2 bar:/lib64
docker cp /lib/x86_64-linux-gnu/ld-2.23.so bar:/lib/x86_64-linux-gnu/
docker cp /lib/x86_64-linux-gnu/libpthread.so.0 bar:/lib/x86_64-linux-gnu/
docker cp /lib/x86_64-linux-gnu/libpthread-2.23.so bar:/lib/x86_64-linux-gnu/
docker cp -a /usr/lib/x86_64-linux-gnu/libstdc++.so.6 bar:/lib/x86_64-linux-gnu/
docker cp -a /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21 bar:/lib/x86_64-linux-gnu/
docker cp -a /lib/x86_64-linux-gnu/libm.so.6 bar:/lib/x86_64-linux-gnu/
docker cp -a /lib/x86_64-linux-gnu/libm-2.23.so bar:/lib/x86_64-linux-gnu/
docker cp -a /lib/x86_64-linux-gnu/libc.so.6 bar:/lib/x86_64-linux-gnu/
docker cp -a /lib/x86_64-linux-gnu/libc-2.23.so bar:/lib/x86_64-linux-gnu/
docker cp -a /lib/x86_64-linux-gnu/libgcc_s.so.1 bar:/lib/x86_64-linux-gnu/
docker cp -a /usr/lib/gcc/x86_64-linux-gnu/5/libgcc_s.so bar:/usr/lib/gcc/x86_64-linux-gnu/5/
在宿主机重新制作基础镜像:
docker commit bar registry.cn-hangzhou.aliyuncs.com/latelee/busybox:rt64
验证:
# 一窗口:
docker run -it --rm --name footest registry.cn-hangzhou.aliyuncs.com/latelee/busybox:rt64 sh
# 二窗口:
docker cp test footest:/
# 一窗口 即容器执行:
/test
验证正确后,上传:
docker push registry.cn-hangzhou.aliyuncs.com/latelee/busybox:rt64
使用
前面制作的镜像是基于ubuntu 16.04 64bit的运行时库,GCC版本为5.4,如此制作,是因为 busybox并没有带必备的动态库和链接器。在编译C++程序时,最好使用相同版本的编译器,如果使用不同版本的库,则还需要额外再制作。当然,如果嫌麻烦,可直接使用ubuntu的镜像,但体积较大,可权衡取舍。
编译后,假定得到test程序,将其拷贝到镜像中即可,Dockerfile可参考如下内容:
From registry.cn-hangzhou.aliyuncs.com/latelee/busybox:rt64
LABEL maintainer="Late Lee"
COPY test /
COPY config.yaml /
CMD ["/test"]
再制作镜像,上传到仓库,完成。
CICD 配置
上述步骤可自动化完成。将C++代码托管在 github 上,再利用 github 自带的 Actions 执行 CI 脚本,在该脚本中完成需要的操作。完整脚本如下:
name: C/C++ CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-16.04
steps:
- uses: actions/checkout@v2
- name: make
run: |
make -C test/ -f Makefile_bin -j
cp test/a.out test
- name: ls
run: ls * -lh
- name: Publish to ali Registry
uses: elgohr/Publish-Docker-Github-Action@master
with:
name: registry.cn-hangzhou.aliyuncs.com/latelee/ci_test:latest
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
registry: registry.cn-hangzhou.aliyuncs.com
dockerfile: Dockerfile
释义:使用 ubuntu-16.04系统,先用官方的actions/checkout
下载代码,再编译,再利用现成的推送方案elgohr/Publish-Docker-Github-Action
,并指定仓库名称、地址、账号密码,等等。当提交代码到仓库时,会自动编译、构建并上传到阿里云仓库。注意,为安全起见,账号和密码使用 secrets,需要在仓库中额外设置。
工程仓库
后续整理提供。
以上是关于我的docker随笔30:C++程序的自动化构建的主要内容,如果未能解决你的问题,请参考以下文章